Cloak posts as they scroll off the screen for memory reasons

This commit is contained in:
Robin Ward 2016-02-24 17:15:25 -05:00
parent 4c93a411f4
commit cc5ca90ac6
2 changed files with 47 additions and 7 deletions

View File

@ -1,6 +1,7 @@
import DiscourseURL from 'discourse/lib/url';
import { keyDirty } from 'discourse/widgets/widget';
import MountWidget from 'discourse/components/mount-widget';
import { cloak, uncloak } from 'discourse/widgets/post-stream';
function findTopView($posts, viewportTop, min, max) {
if (max < min) { return min; }
@ -45,7 +46,7 @@ export default MountWidget.extend({
let windowTop = $w.scrollTop();
const $posts = this.$('.onscreen-post');
const $posts = this.$('.onscreen-post, .cloaked-post');
const viewportTop = windowTop - slack;
const topView = findTopView($posts, viewportTop, 0, $posts.length-1);
@ -64,7 +65,7 @@ export default MountWidget.extend({
if (!$post) { break; }
const viewTop = $post.offset().top;
const viewBottom = viewTop + $post.height();
const viewBottom = viewTop + $post.height() + 100;
if (viewTop > viewportBottom) { break; }
@ -76,9 +77,8 @@ export default MountWidget.extend({
}
const posts = this.posts;
if (onscreen.length) {
const refresh = cb => this.queueRerender(cb);
if (onscreen.length) {
const first = posts.objectAt(onscreen[0]);
if (this._topVisible !== first) {
this._topVisible = first;
@ -113,7 +113,21 @@ export default MountWidget.extend({
this._bottomVisible = null;
}
const onscreenPostNumbers = onscreen.map(idx => posts.objectAt(idx).post_number);
const onscreenPostNumbers = [];
const prev = this._previouslyOnscreen;
const newPrev = {};
onscreen.forEach(idx => {
const post = posts.objectAt(idx);
const postNumber = post.post_number;
delete prev[postNumber];
onscreenPostNumbers.push(postNumber);
newPrev[postNumber] = post;
uncloak(post, this);
});
Object.keys(prev).forEach(pn => cloak(prev[pn], this));
this._previouslyOnscreen = newPrev;
this.screenTrack.setOnscreen(onscreenPostNumbers);
},
@ -125,6 +139,8 @@ export default MountWidget.extend({
this._super();
const debouncedScroll = () => Ember.run.debounce(this, this._scrollTriggered, 10);
this._previouslyOnscreen = {};
this.appEvents.on('post-stream:refresh', debouncedScroll);
$(document).bind('touchmove.post-stream', debouncedScroll);
$(window).bind('scroll.post-stream', debouncedScroll);

View File

@ -1,9 +1,30 @@
import { createWidget } from 'discourse/widgets/widget';
import transformPost from 'discourse/lib/transform-post';
import { Placeholder } from 'discourse/lib/posts-with-placeholders';
import { h } from 'virtual-dom';
import { addWidgetCleanCallback } from 'discourse/components/mount-widget';
const CLOAKING_ENABLED = true;
const DAY = 1000 * 60 * 60 * 24;
let _cloaked = {};
export function cloak(post, component) {
if (!CLOAKING_ENABLED || _cloaked[post.id]) { return; }
const $post = $(`#post_${post.post_number}`);
_cloaked[post.id] = $post.height();
Ember.run.debounce(component, 'queueRerender', 1000);
}
export function uncloak(post, component) {
if (!CLOAKING_ENABLED || !_cloaked[post.id]) { return; }
_cloaked[post.id] = null;
component.queueRerender();
}
addWidgetCleanCallback('post-stream', () => _cloaked = {});
export default createWidget('post-stream', {
tagName: 'div.post-stream',
@ -63,8 +84,11 @@ export default createWidget('post-stream', {
}
prevDate = curTime;
// actual post contents
if (transformed.isSmallAction) {
const height = _cloaked[post.id];
if (height) {
result.push(h('div.cloaked-post', { id: `post_${post.post_number}`,
attributes: { style: `height: ${height}px` } }));
} else if (transformed.isSmallAction) {
result.push(this.attach('post-small-action', transformed, { model: post }));
} else {
result.push(this.attach('post', transformed, { model: post }));