├── .gitattributes
├── .github
├── pull_request_template.md
└── issue_template.md
├── .eslintignore
├── app
├── tray_icon.ico
├── tray_icon.png
├── tray_iconTemplate@2x.png
├── main
│ ├── plugins
│ │ ├── core
│ │ │ ├── icon.png
│ │ │ ├── index.js
│ │ │ ├── plugins
│ │ │ │ ├── getReadme.js
│ │ │ │ ├── Preview
│ │ │ │ │ ├── FormItem.js
│ │ │ │ │ ├── ActionButton.js
│ │ │ │ │ ├── Settings.js
│ │ │ │ │ ├── styles.css
│ │ │ │ │ └── index.js
│ │ │ │ ├── getInstalledPlugins.js
│ │ │ │ ├── format.js
│ │ │ │ ├── loadPlugins.js
│ │ │ │ ├── getAvailablePlugins.js
│ │ │ │ ├── initializeAsync.js
│ │ │ │ └── index.js
│ │ │ ├── quit
│ │ │ │ └── index.js
│ │ │ ├── reload
│ │ │ │ └── index.js
│ │ │ ├── settings
│ │ │ │ ├── Settings
│ │ │ │ │ ├── styles.css
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── Hotkey.js
│ │ │ │ │ └── countries.js
│ │ │ │ └── index.js
│ │ │ ├── autocomplete
│ │ │ │ └── index.js
│ │ │ └── version
│ │ │ │ └── index.js
│ │ ├── index.js
│ │ └── externalPlugins.js
│ ├── store
│ │ ├── index.js
│ │ ├── configureStore.js
│ │ ├── configureStore.production.js
│ │ └── configureStore.development.js
│ ├── reducers
│ │ ├── index.js
│ │ └── search.js
│ ├── createWindow
│ │ ├── toggleWindow.js
│ │ ├── showWindowWithTerm.js
│ │ ├── handleUrl.js
│ │ ├── checkForUpdates.js
│ │ ├── donateDialog.js
│ │ ├── AppTray.js
│ │ └── buildMenu.js
│ ├── containers
│ │ ├── DevTools.js
│ │ └── Search
│ │ │ ├── styles.css
│ │ │ └── index.js
│ ├── constants
│ │ ├── ui.js
│ │ └── actionTypes.js
│ ├── components
│ │ ├── MainInput
│ │ │ ├── styles.css
│ │ │ └── index.js
│ │ └── ResultsList
│ │ │ ├── Row
│ │ │ ├── index.js
│ │ │ └── styles.css
│ │ │ ├── styles.css
│ │ │ └── index.js
│ ├── css
│ │ ├── global.css
│ │ ├── themes
│ │ │ ├── light.css
│ │ │ └── dark.css
│ │ └── system-font.css
│ ├── index.html
│ ├── main.js
│ ├── actions
│ │ └── search.js
│ └── createWindow.js
├── lib
│ ├── plugins
│ │ ├── settings
│ │ │ ├── get.js
│ │ │ ├── index.js
│ │ │ └── validate.js
│ │ ├── index.js
│ │ └── npm.js
│ ├── rpc
│ │ ├── functions
│ │ │ ├── index.js
│ │ │ └── initializePlugins.js
│ │ ├── register.js
│ │ ├── wrap.js
│ │ └── events.js
│ ├── loadThemes.js
│ ├── initializePlugins.js
│ ├── trackEvent.js
│ ├── getWindowPosition.js
│ └── config.js
├── background
│ ├── createWindow.js
│ ├── rpc
│ │ └── initialize.js
│ ├── background.js
│ └── index.html
├── AppUpdater.js
├── package.json
└── main.development.js
├── mocha-webpack.opts
├── postcss.config.js
├── test
├── .eslintrc
└── actions
│ └── search.spec.js
├── .vscode
└── settings.json
├── .editorconfig
├── .babelrc
├── webpack.config.test.js
├── docs
├── plugins
│ ├── styles.md
│ ├── from-scratch.md
│ ├── share.md
│ ├── boilerplate.md
│ ├── cerebro-tools.md
│ ├── examples.md
│ └── plugin-structure.md
└── plugins.md
├── appveyor.yml
├── server.js
├── .gitignore
├── .travis.yml
├── LICENSE
├── webpack.config.electron.js
├── .eslintrc
├── webpack.config.base.js
├── webpack.config.development.js
├── webpack.config.production.js
├── package.json
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | ./main.js
2 | webpack.config.*.js
3 |
--------------------------------------------------------------------------------
/app/tray_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fede1024/cerebro/master/app/tray_icon.ico
--------------------------------------------------------------------------------
/app/tray_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fede1024/cerebro/master/app/tray_icon.png
--------------------------------------------------------------------------------
/app/tray_iconTemplate@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fede1024/cerebro/master/app/tray_iconTemplate@2x.png
--------------------------------------------------------------------------------
/app/main/plugins/core/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fede1024/cerebro/master/app/main/plugins/core/icon.png
--------------------------------------------------------------------------------
/app/main/store/index.js:
--------------------------------------------------------------------------------
1 | import configureStore from './configureStore'
2 |
3 | export default configureStore()
4 |
--------------------------------------------------------------------------------
/mocha-webpack.opts:
--------------------------------------------------------------------------------
1 | --colors
2 | --reporter spec
3 | --webpack-config webpack.config.test.js
4 | --exit
5 | test/**/*.spec.js
6 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | 'postcss-nested': {},
4 | autoprefixer: {}
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/app/lib/plugins/settings/get.js:
--------------------------------------------------------------------------------
1 | import config from 'lib/config'
2 |
3 | export default (pluginName) => config.get('plugins')[pluginName]
4 |
--------------------------------------------------------------------------------
/app/lib/plugins/settings/index.js:
--------------------------------------------------------------------------------
1 | import get from './get'
2 | import validate from './validate'
3 |
4 | export default { get, validate }
5 |
--------------------------------------------------------------------------------
/app/lib/rpc/functions/index.js:
--------------------------------------------------------------------------------
1 | // Export RPC-versions of lib functions
2 | export { default as initializePlugins } from './initializePlugins'
3 |
--------------------------------------------------------------------------------
/app/main/plugins/index.js:
--------------------------------------------------------------------------------
1 | import core from './core'
2 | import externalPlugins from './externalPlugins'
3 |
4 | export default Object.assign(externalPlugins, core)
5 |
--------------------------------------------------------------------------------
/app/main/reducers/index.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux'
2 | import search from './search'
3 |
4 | const rootReducer = combineReducers({
5 | search
6 | })
7 |
8 | export default rootReducer
9 |
--------------------------------------------------------------------------------
/app/background/createWindow.js:
--------------------------------------------------------------------------------
1 | import { BrowserWindow } from 'electron'
2 |
3 | export default ({ src }) => {
4 | const backgroundWindow = new BrowserWindow({
5 | show: false,
6 | })
7 | backgroundWindow.loadURL(src)
8 | return backgroundWindow
9 | }
10 |
--------------------------------------------------------------------------------
/test/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "mocha": true
4 | },
5 | "settings": {
6 | "import/core-modules": "electron",
7 | "import/resolver": {
8 | "webpack": {
9 | "config": "webpack.config.base.js"
10 | }
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/main/store/configureStore.js:
--------------------------------------------------------------------------------
1 | if (process.env.NODE_ENV !== 'development') {
2 | module.exports = require('./configureStore.production') // eslint-disable-line global-require
3 | } else {
4 | module.exports = require('./configureStore.development') // eslint-disable-line global-require
5 | }
6 |
--------------------------------------------------------------------------------
/app/main/createWindow/toggleWindow.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Show or hide main window
3 | * @return {BrowserWindow} appWindow
4 | */
5 | export default (appWindow) => {
6 | if (appWindow.isVisible()) {
7 | appWindow.hide()
8 | } else {
9 | appWindow.show()
10 | appWindow.focus()
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/main/plugins/core/index.js:
--------------------------------------------------------------------------------
1 | import autocomplete from './autocomplete'
2 | import quit from './quit'
3 | import plugins from './plugins'
4 | import settings from './settings'
5 | import version from './version'
6 | import reload from './reload'
7 |
8 | export default {
9 | autocomplete, quit, plugins, settings, version, reload
10 | }
11 |
--------------------------------------------------------------------------------
/app/background/rpc/initialize.js:
--------------------------------------------------------------------------------
1 | import register from 'lib/rpc/register'
2 |
3 | import initializePlugins from 'lib/initializePlugins'
4 |
5 | /**
6 | * Register some functions.
7 | * After `register` function can be called using rpc from main window
8 | */
9 | export default () => {
10 | register('initializePlugins', initializePlugins)
11 | }
12 |
--------------------------------------------------------------------------------
/app/main/createWindow/showWindowWithTerm.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Show main window with updated search term
3 | *
4 | * @return {BrowserWindow} appWindow
5 | */
6 | export default (appWindow, term) => {
7 | appWindow.show()
8 | appWindow.focus()
9 | appWindow.webContents.send('message', {
10 | message: 'showTerm',
11 | payload: term
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/app/main/store/configureStore.production.js:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware } from 'redux'
2 | import thunk from 'redux-thunk'
3 | import rootReducer from '../reducers'
4 |
5 | const enhancer = applyMiddleware(thunk)
6 |
7 | export default function configureStore(initialState) {
8 | return createStore(rootReducer, initialState, enhancer)
9 | }
10 |
--------------------------------------------------------------------------------
/app/background/background.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom'
3 | import initializeRpc from './rpc/initialize'
4 | import { on } from 'lib/rpc/events'
5 |
6 | require('fix-path')()
7 |
8 | initializeRpc()
9 |
10 | // Handle `reload` rpc event and reload window
11 | on('reload', () => location.reload())
12 |
13 | global.React = React
14 | global.ReactDOM = ReactDOM
15 |
--------------------------------------------------------------------------------
/app/main/plugins/core/plugins/getReadme.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Get plugin Readme.md content
3 | *
4 | * @param {String} repository Repository field from npm package
5 | * @return {Promise}
6 | */
7 | export default (repo) => (
8 | fetch(`https://api.github.com/repos/${repo}/readme`)
9 | .then(response => response.json())
10 | .then(json => Buffer.from(json.content, 'base64').toString())
11 | )
12 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "search.exclude": {
3 | ".git": true,
4 | ".eslintcache": true,
5 | "app/dist": true,
6 | "app/main.prod.js": true,
7 | "app/main.prod.js.map": true,
8 | "dll": true,
9 | "release": true,
10 | "node_modules": true,
11 | "npm-debug.log.*": true,
12 | "test/**/__snapshots__": true,
13 | "yarn.lock": true,
14 | ".tmp": true
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/main/containers/DevTools.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { createDevTools } from 'redux-devtools'
3 | import LogMonitor from 'redux-devtools-log-monitor'
4 | import DockMonitor from 'redux-devtools-dock-monitor'
5 |
6 | export default createDevTools(
7 |
11 |
12 |
13 | )
14 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = tab
5 | end_of_line = lf
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 |
10 | [*.{json,js,jsx,html,css}]
11 | indent_style = space
12 | indent_size = 2
13 |
14 | [.eslintrc]
15 | indent_style = space
16 | indent_size = 2
17 |
18 | [.travis.yml]
19 | indent_style = space
20 |
21 | [*.md]
22 | trim_trailing_whitespace = false
23 |
--------------------------------------------------------------------------------
/app/main/constants/ui.js:
--------------------------------------------------------------------------------
1 | // Height of main input
2 | export const INPUT_HEIGHT = 45
3 |
4 | // Heigth of default result line
5 | export const RESULT_HEIGHT = 45
6 |
7 | // Width of main window
8 | export const WINDOW_WIDTH = 650
9 |
10 | // Maximum results that would be rendered
11 | export const MAX_RESULTS = 25
12 |
13 | // Results view shows this count of resutls without scrollbar
14 | export const MIN_VISIBLE_RESULTS = 10
15 |
--------------------------------------------------------------------------------
/app/lib/rpc/register.js:
--------------------------------------------------------------------------------
1 | import { on, send } from './events'
2 |
3 | /**
4 | * Register listener for rpc-calls.
5 | * @param {String} name Name of a function that is sent throuth messaging system
6 | * @param {Function} fn Function registered for this name
7 | */
8 | export default (name, fn) => {
9 | on(`rpc.fn.${name}`, ({ args, callId }) => {
10 | fn.apply(null, args).then(result => send(callId, result))
11 | })
12 | }
13 |
--------------------------------------------------------------------------------
/app/main/components/MainInput/styles.css:
--------------------------------------------------------------------------------
1 | .input {
2 | width: 100%;
3 | height: 45px;
4 | background-color: var(--main-background-color);
5 | color: var(--main-font-color);
6 | font-size: 1.5em;
7 | border: 0;
8 | outline: none;
9 | padding: 0 10px;
10 | line-height: 60px;
11 | box-sizing: border-box;
12 | background: transparent;
13 | white-space: nowrap;
14 | -webkit-app-region: drag;
15 | -webkit-user-select: none;
16 | }
17 |
--------------------------------------------------------------------------------
/app/background/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/main/constants/actionTypes.js:
--------------------------------------------------------------------------------
1 | export const UPDATE_TERM = 'UPDATE_TERM'
2 | export const MOVE_CURSOR = 'MOVE_CURSOR'
3 | export const SELECT_ELEMENT = 'SELECT_ELEMENT'
4 | export const SHOW_RESULT = 'SHOW_RESULT'
5 | export const HIDE_RESULT = 'HIDE_RESULT'
6 | export const UPDATE_RESULT = 'UPDATE_RESULT'
7 |
8 | export const RESET = 'RESET'
9 | export const CHANGE_VISIBLE_RESULTS = 'CHANGE_VISIBLE_RESULTS'
10 |
11 | export const ICON_LOADED = 'ICON_LOADED'
12 |
--------------------------------------------------------------------------------
/app/main/containers/Search/styles.css:
--------------------------------------------------------------------------------
1 | .search {
2 | position: relative;
3 | display: flex;
4 | flex-direction: column;
5 | height: 100%;
6 | }
7 |
8 | .inputWrapper {
9 | position: relative;
10 | z-index: 2;
11 | width: 100%;
12 | height: 45px;
13 | }
14 |
15 | .autocomplete {
16 | position: absolute;
17 | z-index: 1;
18 | width: 100%;
19 | height: 45px;
20 | font-size: 1.5em;
21 | padding: 0 10px;
22 | line-height: 46px;
23 | box-sizing: border-box;
24 | color: var(--secondary-font-color);
25 | white-space: pre;
26 | }
27 |
--------------------------------------------------------------------------------
/app/main/plugins/core/plugins/Preview/FormItem.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 | import { Select, Text, Checkbox } from 'cerebro-ui/Form'
3 |
4 | const components = {
5 | bool: Checkbox,
6 | option: Select,
7 | }
8 |
9 | const FormItem = ({ type, ...props }) => {
10 | const Component = components[type] || Text
11 |
12 | return (
13 |
14 | )
15 | }
16 |
17 | FormItem.propTypes = {
18 | value: PropTypes.any,
19 | type: PropTypes.string.isRequired,
20 | }
21 |
22 | export default FormItem
23 |
--------------------------------------------------------------------------------
/app/main/plugins/core/plugins/getInstalledPlugins.js:
--------------------------------------------------------------------------------
1 | import { packageJsonPath } from 'lib/plugins'
2 | import { readFile } from 'fs'
3 |
4 | const readPackageJson = () => new Promise((resolve, reject) => {
5 | readFile(packageJsonPath, (err, source) => (
6 | err ? reject(err) : resolve(source)
7 | ))
8 | })
9 |
10 | /**
11 | * Get list of all installed plugins with versions
12 | *
13 | * @return {Promise