Simplify prefs window

This commit is contained in:
DC
2016-05-24 01:43:59 -07:00
parent 12f9709601
commit a59faacbd7
2 changed files with 57 additions and 104 deletions

View File

@@ -542,6 +542,9 @@ function resumeTorrents () {
.forEach((x) => startTorrentingSummary(x))
}
// Updates a single property in the UNSAVED prefs
// For example: updatePreferences("foo.bar", "baz")
// Call savePreferences to save to config.json
function updatePreferences (property, value) {
var path = property.split('.')
var key = state.unsaved.prefs
@@ -554,6 +557,7 @@ function updatePreferences (property, value) {
key[path[i]] = value
}
// All unsaved prefs take effect atomically, and are saved to config.json
function savePreferences () {
state.saved.prefs = Object.assign(state.saved.prefs || {}, state.unsaved.prefs)
saveState()

View File

@@ -1,6 +1,5 @@
module.exports = Preferences
var fs = require('fs-extra')
var h = require('virtual-dom/h')
var hyperx = require('hyperx')
var hx = hyperx(h)
@@ -9,46 +8,70 @@ var {dispatch} = require('../lib/dispatcher')
var remote = require('electron').remote
var dialog = remote.dialog
var prefState
function Preferences (state) {
prefState = state.unsaved.prefs
var definitions = getPreferenceDefinitions()
var sections = []
definitions.forEach(function (sectionDefinition) {
sections.push(renderSection(sectionDefinition))
})
return hx`
<div class='preferences'>
${sections}
${renderGeneralSection(state)}
</div>
`
}
function renderSection (definition) {
var controls = []
function renderGeneralSection (state) {
return renderSection({
title: 'General',
description: '',
icon: 'settings'
}, [
renderDownloadDirSelector(state)
])
}
definition.controls.forEach(function (controlDefinition) {
controls.push(controlDefinition.renderer(controlDefinition))
function renderDownloadDirSelector (state) {
return renderFileSelector({
label: 'Download Path',
description: 'Data from torrents will be saved here',
property: 'downloadPath',
options: {
title: 'Select download directory',
properties: [ 'openDirectory' ]
}
},
state.unsaved.prefs.downloadPath,
function (filePath) {
setStateValue('downloadPath', filePath)
})
}
// Renders a prefs section.
// - definition should be {icon, title, description}
// - controls should be an array of vdom elements
function renderSection (definition, controls) {
var helpElem = !definition.description ? null : hx`
<div class='help text'>
<i.icon>help_outline</i>${definition.description}
</div>
`
return hx`
<section class='section preferences-panel'>
<div class='section-container'>
<div class='section-heading'><i.icon>${definition.icon}</i>${definition.title}</div>
<div class='help text'><i.icon>help_outline</i>${definition.description}</div>
<div class='section-body'>
<div class='section-heading'>
<i.icon>${definition.icon}</i>${definition.title}
</div>
${helpElem}
<div class='section-body'>
${controls}
</div>
</div>
</div>
</section>
`
}
function renderFileSelector (definition) {
var value = getStateValue(definition.property)
// Creates a file chooser
// - defition should be {label, description, options}
// options are passed to dialog.showOpenDialog
// - value should be the current pref, a file or folder path
// - callback takes a new file or folder path
function renderFileSelector (definition, value, callback) {
return hx`
<div class='control-group'>
<div class='controls'>
@@ -58,98 +81,24 @@ function renderFileSelector (definition) {
</label>
<div class='controls'>
<input type='text' class='file-picker-text'
id=${definition.property} placeholder=${definition.placeholder}
readonly='readonly'
value=${value}/>
<button class='btn' onclick=${filePickerHandler}><i.icon>folder_open</i></button>
id=${definition.property}
disabled='disabled'
value=${value} />
<button class='btn' onclick=${handleClick}>
<i.icon>folder_open</i>
</button>
</div>
</div>
</div>
`
function filePickerHandler () {
function handleClick () {
dialog.showOpenDialog(remote.getCurrentWindow(), definition.options, function (filenames) {
if (!Array.isArray(filenames)) return
if (!definition.validator || definition.validator(filenames[0])) {
setStateValue(definition.property, filenames[0])
}
callback(filenames[0])
})
}
}
/*
function renderCheckbox (definition) {
var checked = getStateValue(definition.property)
var checkbox = checked ? 'check_box' : 'check_box_outline_blank'
return hx`
<div class='control-group'>
<div class='controls'>
<div class='checkbox'>
<label class='control-label'>
<i.icon onclick=${checkboxHandler}>${checkbox}</i>
<div class='preference-title' onclick=${checkboxHandler}>${definition.label}</div>
</label>
<div class='preference-description'>${definition.description}</div>
</div>
</div>
</div>
`
function checkboxHandler (e) {
setStateValue(definition.property, !getStateValue(definition.property))
}
}
*/
function getPreferenceDefinitions () {
return [
{
title: 'General',
description: 'These are WebTorrent Desktop main preferences. Will put a very long text to check if it overflows correctly.',
icon: 'settings',
controls: [
{
label: 'Download Path',
description: 'Directory where the files will be stored. Please, check if it has enough space!',
property: 'downloadPath',
renderer: renderFileSelector,
placeholder: 'Your downloads directory ie: $HOME/Downloads',
options: {
title: 'Select download directory.',
properties: [ 'openDirectory' ]
},
validator: function (value) {
return fs.existsSync(value)
}
}
]
}/*,
{
title: 'Interface',
description: 'Here you can change the way the application looks and beahaves.',
icon: 'view_compact',
controls: [
{
label: 'Disable Tray',
description: 'This option gives you the chance to quit immediately and don\'t send the application to background when you close it.',
property: 'interface.disableTray',
renderer: renderCheckbox
}
]
}*/
]
}
function getStateValue (property) {
var path = property.split('.')
var key = prefState
for (var i = 0; i < path.length - 1; i++) {
if (typeof key[path[i]] === 'undefined') {
return ''
}
key = key[path[i]]
}
return key[path[i]]
}
function setStateValue (property, value) {
dispatch('updatePreferences', property, value)
}