Skip to content

Commit

Permalink
Changes in plugin settings (#1)
Browse files Browse the repository at this point in the history
Do not store settings structure in config, always get it from plugin object
  • Loading branch information
KELiON authored and BrainMaestro committed Mar 21, 2017
1 parent 3711ea8 commit 6762c00
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 118 deletions.
2 changes: 1 addition & 1 deletion app/lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const defaultSettings = memoize(() => {
cleanOnHide: true,
skipDonateDialog: false,
lastShownDonateDialog: null,
external: {},
plugins: {},
}
})

Expand Down
2 changes: 1 addition & 1 deletion app/lib/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ export const ensureFiles = () => {
}

export const client = npm(pluginsPath)
export { default as addSettings } from './settings'
export { default as settings } from './settings'
49 changes: 0 additions & 49 deletions app/lib/plugins/settings.js

This file was deleted.

3 changes: 3 additions & 0 deletions app/lib/plugins/settings/get.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import config from 'lib/config'

export default (pluginName) => config.get('plugins')[pluginName]
4 changes: 4 additions & 0 deletions app/lib/plugins/settings/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import get from './get'
import validate from './validate'

export default { get, validate }
24 changes: 24 additions & 0 deletions app/lib/plugins/settings/validate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { every } from 'lodash/fp'

const VALID_TYPES = new Set([
'array',
'string',
'number',
'bool',
'option',
])

const validSetting = ({ type, options }) => {
// General validation of settings
if (!type || !VALID_TYPES.has(type)) return false

// Type-specific validations
if (type === 'option') return Array.isArray(options) && options.length

return true
}

export default ({ settings }) => {
if (!settings) return true
return every(validSetting)(settings)
}
11 changes: 2 additions & 9 deletions app/main/actions/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import plugins from '../plugins/'
import config from 'lib/config'
import { shell, clipboard, remote } from 'electron'
import store from '../store'
import { settings as pluginSettings } from 'lib/plugins'

import {
UPDATE_TERM,
Expand Down Expand Up @@ -36,24 +37,16 @@ const DEFAULT_SCOPE = {
* @param {Function} callback Callback function that receives used search term and found results
*/
const eachPlugin = (term, display) => {
const externalSettings = config.get('external') || {}
// TODO: order results by frequency?
Object.keys(plugins).forEach(name => {
const settings = externalSettings[name]
if (settings) {
Object.keys(settings).forEach(key => {
settings[key] = settings[key].value
})
}

try {
plugins[name].fn({
...DEFAULT_SCOPE,
term,
hide: (id) => store.dispatch(hideElement(`${name}-${id}`)),
update: (id, result) => store.dispatch(updateElement(`${name}-${id}`, result)),
display: (payload) => display(name, payload),
settings,
settings: pluginSettings.get(name),
})
} catch (error) {
// Do not fail on plugin errors, just log them to console
Expand Down
60 changes: 60 additions & 0 deletions app/main/plugins/core/cerebro/settings/Settings/PluginSettings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { PropTypes, Component } from 'react'
import config from 'lib/config'
import styles from './styles.css'
import SettingsComponent from './components'

export default class PluginSettings extends Component {
constructor(props) {
super(props)
this.state = {
values: config.get('plugins')[props.name],
}
this.renderSetting = this.renderSetting.bind(this)
this.changeSetting = this.changeSetting.bind(this)
}

changeSetting(plugin, label, value) {
const values = {
...this.state.values,
[label]: value,
}

this.setState({ values })
config.set('plugins', {
...config.get('plugins'),
[this.props.name]: values,
})
}

renderSetting(key) {
const setting = this.props.settings[key]
const { defaultValue, label, ...restProps } = setting
const value = key in this.state.values ? this.state.values[key] : defaultValue

return (
<SettingsComponent
key={key}
label={label || key}
value={value}
onChange={newValue => this.changeSetting(this.props.name, key, newValue)}
{...restProps}
/>
)
}

render() {
return (
<div className={styles.settingItem}>
<label className={styles.header}>Settings</label>
{Object
.keys(this.props.settings)
.map(this.renderSetting)}
</div>
)
}
}

PluginSettings.propTypes = {
name: PropTypes.string.isRequired,
settings: PropTypes.object.isRequired,
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const SettingsComponent = ({ type, ...props }) => {
}

SettingsComponent.propTypes = {
value: PropTypes.any.isRequired,
value: PropTypes.any,
type: PropTypes.string.isRequired,
}

Expand Down

This file was deleted.

41 changes: 34 additions & 7 deletions app/main/plugins/core/cerebro/settings/Settings/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import CountrySelect from './CountrySelect'
import Select from 'react-select'
import loadThemes from 'lib/loadThemes'
import styles from './styles.css'
import ExternalSettings from './external-settings'
import PluginSettings from './PluginSettings'
import plugins from 'main/plugins'

import { pickBy } from 'lodash'

class Settings extends Component {
constructor(props) {
Expand All @@ -17,20 +20,47 @@ class Settings extends Component {
theme: get('theme'),
developerMode: get('developerMode'),
cleanOnHide: get('cleanOnHide'),
external: get('external'),
pluginsSettings: get('plugins'),
}
this.changeConfig = this.changeConfig.bind(this)
}
pluginChangeSettings(name) {
return updateSettings => {
const { pluginsSettings } = this.state
const newPluginsSettings = {
...pluginsSettings,
[name]: updateSettings
}
this.setState({ pluginsSettings: newPluginsSettings })
this.changeConfig('plugins', newPluginsSettings)
}
}
changeConfig(key, value) {
this.props.set(key, value)
this.setState({
[key]: value
})
}
renderPluginsSettings() {
const { pluginsSettings } = this.state
const pluginsWithSettings = pickBy(plugins, p => p.settings)
return Object.keys(pluginsWithSettings).map(name => {
const { settings } = pluginsWithSettings[name]
return (
<PluginSettings
values={pluginsSettings[name] || {}}
settings={settings}
onChange={this.pluginChangeSettings(name)}
/>
)
})
}
render() {
const {
hotkey, showInTray, country, theme, developerMode, cleanOnHide, external
hotkey, showInTray, country, theme, developerMode, cleanOnHide
} = this.state


return (
<div className={styles.settings}>
<div className={styles.item}>
Expand Down Expand Up @@ -113,10 +143,7 @@ class Settings extends Component {
</div>
</div>

<ExternalSettings
settings={external}
onChange={settings => this.changeConfig('external', settings)}
/>
{this.renderPluginsSettings()}
</div>
)
}
Expand Down
9 changes: 7 additions & 2 deletions app/main/plugins/externalPlugins.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import debounce from 'lodash/debounce'
import chokidar from 'chokidar'
import path from 'path'
import { modulesDirectory, ensureFiles, addSettings } from 'lib/plugins'
import { modulesDirectory, ensureFiles, settings } from 'lib/plugins'

const requirePlugin = (pluginPath) => {
try {
Expand Down Expand Up @@ -55,7 +55,12 @@ pluginsWatcher.on('addDir', (pluginPath) => {
console.groupEnd()
return
}
addSettings(plugin, base)
if (!settings.validate(plugin)) {
console.log('Invalid plugins settings')
console.groupEnd()
return
}

console.log('Loaded.')
const requirePath = window.require.resolve(pluginPath)
const watcher = chokidar.watch(requirePath, { depth: 0 })
Expand Down

0 comments on commit 6762c00

Please sign in to comment.