Sélecteur pour le thème d'icone

This commit is contained in:
wpetit 2015-08-31 23:08:56 +02:00
parent 5cd3fafb5e
commit 1c0a4e9f13
8 changed files with 97 additions and 34 deletions

View File

@ -2,20 +2,37 @@ var React = require('react');
var Util = require('../util');
var LazyLoad = require('./mixins/lazy-load');
var LOADING_ICON = 'img/hourglass.svg';
module.exports = React.createClass({
mixins: [LazyLoad],
getInitialState: function() {
return { icon: 'img/hourglass.svg', loading: false };
return { icon: LOADING_ICON, currentTheme: undefined };
},
onInViewport: function() {
if(!this.state.loading) {
this.setState({ loading: true });
var desktopEntry = this.props.desktopEntry;
this._findIcon(desktopEntry.Icon);
}
this.updateIconIfInViewport();
},
updateIconIfInViewport: function() {
var currentTheme = this.state.currentTheme;
var newTheme = this.props.theme;
if( !this.isInViewport() || newTheme === currentTheme ) return;
this.setState({ icon: LOADING_ICON, currentTheme: newTheme });
var desktopEntry = this.props.desktopEntry;
this._findIcon(desktopEntry.Icon, newTheme);
},
componentDidUpdate: function() {
this.updateIconIfInViewport();
},
render: function() {
@ -33,11 +50,12 @@ module.exports = React.createClass({
},
_findIcon: function(iconPath) {
_findIcon: function(iconPath, theme) {
var self = this;
var DEFAULT_ICON = 'application-default-icon';
var theme = null;
console.log('Search icon %s:%s', iconPath, theme);
Util.DesktopApps.findIcon(iconPath || DEFAULT_ICON, theme)
.then(function(iconPath) {
@ -47,7 +65,9 @@ module.exports = React.createClass({
return iconPath;
})
.then(function(iconPath) {
self.setState({ icon: iconPath });
global.window.requestAnimationFrame(function() {
self.setState({ icon: iconPath });
});
})
;

View File

@ -1,17 +1,21 @@
var React = require('react');
var Util = require('../util');
var DesktopAppItem = require('./desktop-app-item.jsx');
var IconThemeSelector = require('./icon-theme-selector.jsx');
var path = require('path');
var debug = require('debug')('pitaya:desktop-app-list');
module.exports = React.createClass({
getInitialState: function() {
return {
desktopFiles: []
desktopFiles: [],
selectedTheme: null
};
},
componentDidMount: function() {
// Load system desktop apps
var baseDirs = global.process.env.XDG_DATA_DIRS.split(':').map(function(baseDir){
return path.join(baseDir, 'applications');
@ -28,15 +32,23 @@ module.exports = React.createClass({
var items = this.state.desktopFiles.map(function(desktopFile, i) {
var desktopEntry = desktopFile.content['Desktop Entry'];
return <DesktopAppItem key={desktopFile.path} desktopEntry={desktopEntry} />;
});
return <DesktopAppItem theme={this.state.selectedTheme} key={desktopFile.path} desktopEntry={desktopEntry} />;
}.bind(this));
return (
<ul className="desktop-apps">
{items}
</ul>
<div>
<IconThemeSelector onThemeSelected={this.onThemeSelected} />
<ul className="desktop-apps">
{items}
</ul>
</div>
);
},
onThemeSelected: function(theme) {
console.log('Selected theme %s', theme);
this.setState({ selectedTheme: theme });
}
});

View File

@ -0,0 +1,45 @@
var React = require('react');
var Util = require('../util');
module.exports = React.createClass({
propsType: {
onThemeSelected: React.PropTypes.func.isRequired,
},
getInitialState: function() {
return { selectedTheme: null, availableThemes: [] };
},
componentDidMount: function() {
Util.DesktopApps.findIconThemes()
.then(function(themes) {
this.setState({ availableThemes: themes });
}.bind(this))
;
},
onChange: function(evt) {
var selectedTheme = evt.target.value;
this.setState({ selectedTheme: selectedTheme });
this.props.onThemeSelected(selectedTheme);
},
render: function() {
var selectedTheme = this.state.selectedTheme;
var options = this.state.availableThemes.map(function(theme) {
return (
<option key={theme} value={theme}>{theme}</option>
);
});
return (
<select value={selectedTheme} onChange={this.onChange}>
{options}
</select>
);
}
});

View File

@ -30,7 +30,7 @@ module.exports = {
var el = React.findDOMNode(this);
if(typeof this.onInViewport === 'function') {
el.parentNode.addEventListener('scroll', debounce(_onInViewport.bind(this), 250));
window.document.addEventListener('scroll', debounce(_onInViewport.bind(this), 250), true);
}
_onInViewport.call(this);

View File

@ -79,6 +79,7 @@ exports.findIcon = function(iconName, themeName, size, themeIgnore) {
themeIgnore = themeIgnore || [];
if(themeIgnore.indexOf(themeIgnore) !== -1) {
debug('Theme %s already processed, ignoring...', themeName);
return Promise.resolve(null);
}
themeIgnore.push(themeName);

View File

@ -52,28 +52,12 @@ exports.runApp = function(execPath) {
});
};
var _globCache = {
statCache: {},
cache: {},
realpathCache: {},
symlinks: {}
};
exports.findFiles = function(pattern, opts) {
return new Promise(function(resolve, reject) {
opts = opts || {};
opts.cache = _globCache.cache;
opts.statCache = _globCache.statCache;
opts.realpathCache = _globCache.realpathCache;
opts.symlinks = _globCache.symlinks;
glob(pattern, opts, function(err, files) {
if(err) return reject(err);
return resolve(files);
});
});
};

View File

@ -28,6 +28,7 @@
"ini": "^1.3.4",
"minimist": "^1.1.3",
"node-jsx": "^0.13.3",
"react": "^0.13.3"
"react": "^0.13.3",
"react-dnd": "^1.1.5"
}
}

View File

@ -21,7 +21,7 @@ DesktopSuite.findIconThemes = function(test) {
DesktopSuite.findIcon = function(test) {
DesktopApps.findIcon('atom')
DesktopApps.findIcon('phpmyadmin')
.then(function(iconPath) {
console.log('findIcon', iconPath);
test.done();