Chargement/Sauvegarde profil via l'UI

This commit is contained in:
wpetit 2015-09-18 12:13:24 +02:00
parent 383f70f7f3
commit 6c8d26139e
9 changed files with 140 additions and 13 deletions

View File

@ -4,7 +4,7 @@ var path = require('path');
module.exports = function(grunt) { module.exports = function(grunt) {
var NW_VERSION = '0.12.2'; var NW_VERSION = '0.12.3';
var BUILD_DIR = 'build'; var BUILD_DIR = 'build';
var BUILD_TARGETS = { var BUILD_TARGETS = {
linux_ia32: true, linux_ia32: true,

View File

@ -77,7 +77,8 @@ html, body {
transition: 150ms linear; transition: 150ms linear;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
min-width: 150px; width: 125px;
height: 125px;
} }
.launcher li.app-item::after { .launcher li.app-item::after {
@ -105,6 +106,11 @@ html, body {
display: block; display: block;
text-align: center; text-align: center;
color: white; color: white;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 90%;
overflow: hidden;
margin: auto;
} }
/* Edit View */ /* Edit View */
@ -116,6 +122,14 @@ html, body {
flex-direction: column; flex-direction: column;
} }
.edit .menu-bar {
padding: 5px 10px;
}
.edit .menu-bar button {
margin-right: 3px;
}
.edit .workspace { .edit .workspace {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -136,6 +150,10 @@ html, body {
flex: 2; flex: 2;
} }
.edit .item-form > form {
width: 100%;
}
.edit .apps-list .icon-theme-selector > select { .edit .apps-list .icon-theme-selector > select {
width: 100%; width: 100%;
} }

View File

@ -4,6 +4,7 @@ var ProfileTree = require('./profile-tree.jsx');
var DesktopAppList = require('./desktop-app-list.jsx'); var DesktopAppList = require('./desktop-app-list.jsx');
var ItemForm = require('./item-form.jsx'); var ItemForm = require('./item-form.jsx');
var IconThemeSelector = require('./icon-theme-selector.jsx'); var IconThemeSelector = require('./icon-theme-selector.jsx');
var ProfileMenu = require('./profile-menu.jsx');
var tree = require('../../util/tree'); var tree = require('../../util/tree');
var actions = require('../../store/actions'); var actions = require('../../store/actions');
@ -21,7 +22,7 @@ var EditView = React.createClass({
return ( return (
<div className="edit"> <div className="edit">
<div className="menu-bar"> <div className="menu-bar">
<ProfileMenu />
</div> </div>
<div className="workspace"> <div className="workspace">
<div className="left-menu"> <div className="left-menu">

View File

@ -0,0 +1,79 @@
var React = require('react');
var connect = require('react-redux').connect;
var actions = require('../../store/actions');
var ProfileMenu = React.createClass({
render: function() {
return (
<div className="profile-menu">
<input ref="fileInput" style={{display: 'none'}} filter=".json" type="file" />
<button className="btn btn-default" onClick={this.handleOpenClick}>Ouvrir</button>
<button className="btn btn-primary" onClick={this.handleSaveClick}>Enregistrer</button>
</div>
);
},
handleOpenClick: function() {
var dispatch = this.props.dispatch;
this.showFileDialog()
.then(function(profilePath) {
dispatch(actions.common.loadProfile(profilePath));
})
;
},
handleSaveClick: function() {
var dispatch = this.props.dispatch;
var profile = this.props.profile;
var profilePath = this.props.profilePath;
var promise = profilePath ? Promise.resolve(profilePath) : this.showFileDialog(true);
promise.then(function(profilePath) {
dispatch(actions.edit.saveProfile(profilePath, profile));
});
},
showFileDialog: function(saveAs) {
var fileInput = this.refs.fileInput.getDOMNode();
// Toggle 'save as' feature
if(saveAs) {
fileInput.nwsaveas = true;
} else {
fileInput.removeAttribute('nwsaveas');
}
return new Promise(function(resolve, reject) {
fileInput.addEventListener('change', handleChange, false);
fileInput.click();
function handleChange(evt) {
fileInput.removeEventListener('change', handleChange);
var value = this.value;
this.value = null;
resolve(value);
}
});
}
});
function select(state) {
return {
profile: state.profile,
profilePath: state.profilePath
};
}
module.exports = connect(select)(ProfileMenu);

View File

@ -50,10 +50,6 @@ var TreeNode = React.createClass({
var ProfileTree = React.createClass({ var ProfileTree = React.createClass({
componentDidMount: function() {
this.props.dispatch(actions.common.loadProfile('./default-profile.json'));
},
render: function() { render: function() {
return ( return (

View File

@ -10,7 +10,7 @@ exports.loadProfile = function(profilePath) {
dispatch({ type: LOAD_PROFILE, profilePath: profilePath }); dispatch({ type: LOAD_PROFILE, profilePath: profilePath });
return Util.System.loadJSONFile(profilePath) return Util.System.loadJSON(profilePath)
.then(function(profile) { .then(function(profile) {
dispatch({ type: LOAD_PROFILE_SUCCESS, profile: profile }); dispatch({ type: LOAD_PROFILE_SUCCESS, profile: profile });
return profile; return profile;

View File

@ -39,10 +39,19 @@ exports.loadDesktopApps = function() {
}; };
}; };
exports.saveProfile = function(profile) { exports.saveProfile = function(destPath, profile) {
return function(dispatch, getState) { return function(dispatch, getState) {
dispatch({ type: SAVE_PROFILE, profile: profile, path: destPath });
return Util.System.saveJSON(destPath, profile)
.then(function() {
dispatch({ type: SAVE_PROFILE_SUCCESS, profile: profile, path: destPath });
})
.catch(function(err) {
dispatch({ type: SAVE_PROFILE_FAILED, error: err });
})
;
}; };
}; };

View File

@ -10,7 +10,7 @@ exports.runApp = function(execPath) {
dispatch({ type: RUN_APP, execPath: execPath }); dispatch({ type: RUN_APP, execPath: execPath });
return Util.System.runApp(execPath) return Util.System.runApp(execPath, { clearFreeDesktopFlags: true })
.then(function() { .then(function() {
dispatch({ type: RUN_APP_SUCCESS, execPath: execPath }); dispatch({ type: RUN_APP_SUCCESS, execPath: execPath });
return execPath; return execPath;

View File

@ -10,7 +10,7 @@ var Cache = require('./cache');
* @param filePath The path of the json file * @param filePath The path of the json file
* @return Promise * @return Promise
*/ */
exports.loadJSONFile = function(filePath) { exports.loadJSON = function(filePath) {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
fs.readFile(filePath, 'utf8', function(err, fileContent) { fs.readFile(filePath, 'utf8', function(err, fileContent) {
if(err) return reject(err); if(err) return reject(err);
@ -24,6 +24,19 @@ exports.loadJSONFile = function(filePath) {
}); });
}; };
exports.saveJSON = function(filePath, obj) {
var jsonStr = JSON.stringify(obj, null, 2);
return new Promise(function(resolve, reject) {
fs.writeFile(filePath, jsonStr, function(err) {
if(err) return reject(err);
return resolve();
});
});
};
/** /**
* Load a INI file * Load a INI file
* *
@ -44,7 +57,18 @@ exports.loadINIFile = function(filePath) {
}); });
}; };
exports.runApp = function(execPath) { exports.clearFreeDesktopFlags = function(exec) {
return exec.replace(/%[uUdDfFnNickvm]/g, '');
};
exports.runApp = function(execPath, opts) {
opts = opts || {};
if(opts.clearFreeDesktopFlags) {
execPath = exports.clearFreeDesktopFlags(execPath);
}
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
cp.exec(execPath, function(err) { cp.exec(execPath, function(err) {
if(err) return reject(err); if(err) return reject(err);