Sélecteur pour le thème d'icone
This commit is contained in:
parent
5cd3fafb5e
commit
1c0a4e9f13
@ -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 });
|
||||
});
|
||||
})
|
||||
;
|
||||
|
||||
|
@ -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 });
|
||||
}
|
||||
|
||||
});
|
||||
|
45
js/components/icon-theme-selector.jsx
Normal file
45
js/components/icon-theme-selector.jsx
Normal 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>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
});
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user