Add fake scrolling padding for better torrent list performance

This commit is contained in:
John F
2015-04-19 02:01:51 -04:00
parent 21d5f2c1eb
commit 2778fa83a2
3 changed files with 81 additions and 22 deletions
-3
View File
@@ -62,9 +62,7 @@ gulp.task('scripts', function() {
bundler.transform(reactify);
function rebundle() {
var stream = bundler.bundle();
return stream.on('error', handleErrors)
.pipe(source('app.js'))
.pipe(gulp.dest(destDir + 'scripts/'));
@@ -87,7 +85,6 @@ gulp.task('svg', function() {
gulp.task('watch', function () {
gulp.watch(sourceDir + 'scripts/**/*.js', ['scripts', reload]);
gulp.watch(sourceDir + 'sass/**/*.scss', ['styles', reload]);
});
+9 -7
View File
@@ -1,5 +1,6 @@
.torrent {
cursor: default;
padding: 10px 20px;
transition: background 0.25s;
&:hover {
@@ -13,7 +14,6 @@
}
.torrent {
padding: 10px 20px;
&__header,
&__details {
@@ -89,11 +89,6 @@
}
&__list {
overflow: auto;
position: relative;
}
&__details {
margin-bottom: 4px;
}
@@ -107,6 +102,11 @@
list-style: none;
}
&__list {
overflow: auto;
position: relative;
}
&__detail {
&--primary,
@@ -119,7 +119,9 @@
.torrent & {
color: $torrent--primary--foreground;
font-size: 1.1em;
font-size: 1em;
overflow: hidden;
white-space: nowrap;
}
}
@@ -5,8 +5,11 @@ var UIStore = require('../../stores/UIStore');
var getTorrentList = function() {
var torrentList = TorrentStore.getAll();
return {
allTorrents: TorrentStore.getAll()
allTorrents: torrentList,
spacerBottom: getSpacerBottom(this.state.maxTorrentIndex, torrentList.length, this.state.torrentHeight)
}
};
@@ -17,20 +20,51 @@ var getSelectedTorrents = function() {
}
};
var getSpacerTop = function(minVisible, height) {
var invisible = minVisible;
var spacerHeight = 0;
if (invisible > 0) {
spacerHeight = invisible * height;
}
return spacerHeight;
};
var getSpacerBottom = function(maxVisible, count, height) {
var invisible = count - maxVisible;
var spacerHeight = 0;
if (invisible > 0) {
spacerHeight = invisible * height
}
return spacerHeight;
};
var TorrentList = React.createClass({
getInitialState: function() {
// recalculate these values when appropriate
return {
allTorrents: [],
selectedTorrents: []
selectedTorrents: [],
torrentHeight: 53,
viewportHeight: 265,
minTorrentIndex: 0,
maxTorrentIndex: 4,
spacerTop: 0,
spacerBottom: 0
};
},
componentDidMount: function() {
TorrentStore.addChangeListener(this._onTorrentStoreChange);
UIStore.addChangeListener(this._onUIStoreChange);
},
componentWillUnmount: function() {
@@ -44,23 +78,29 @@ var TorrentList = React.createClass({
var that = this;
var torrentList = torrents.map(function(torrent) {
var torrentList = torrents.map(function(torrent, index) {
var isSelected = false;
var hash = torrent.hash;
if (index >= that.state.minTorrentIndex && index <= that.state.maxTorrentIndex) {
if (that.state.selectedTorrents.indexOf(hash) > -1) {
isSelected = true;
var isSelected = false;
var hash = torrent.hash;
if (that.state.selectedTorrents.indexOf(hash) > -1) {
isSelected = true;
}
return (
<Torrent key={hash} data={torrent} selected={isSelected} />
);
}
return (
<Torrent key={hash} data={torrent} selected={isSelected} />
);
});
return (
<ul className="torrent__list">
<ul className="torrent__list" ref="torrentList" onScroll={this._onScroll}>
<li className="torrent__spacer torrent__spacer--top" style={{height: this.state.spacerTop + 'px'}}></li>
{torrentList}
<li className="torrent__spacer torrent__spacer--bottom" style={{height: this.state.spacerBottom + 'px'}}></li>
</ul>
);
},
@@ -71,6 +111,26 @@ var TorrentList = React.createClass({
_onUIStoreChange: function() {
this.setState(getSelectedTorrents);
},
_onScroll: function(event) {
// debounce this event
var buffer = 1;
var scrolledPosition = event.target.scrollTop;
var totalTorrents = this.state.allTorrents.length;
var elementsInView = Math.floor(this.state.viewportHeight / this.state.torrentHeight);
var hiddenItemsTop = Math.floor(scrolledPosition / this.state.torrentHeight) - buffer;
var hiddenItemsBottom = hiddenItemsTop + elementsInView + buffer;
this.setState({
minTorrentIndex: hiddenItemsTop,
maxTorrentIndex: hiddenItemsBottom,
spacerTop: getSpacerTop(hiddenItemsTop, this.state.torrentHeight),
spacerBottom: getSpacerBottom(hiddenItemsBottom, totalTorrents, this.state.torrentHeight)
});
}
});