mirror of
https://github.com/flarum/core.git
synced 2025-08-07 17:07:19 +02:00
Encapsulate a bit more logic in the state
This commit is contained in:
@@ -102,20 +102,17 @@ export default class PostStream extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
config(isInitialized, context) {
|
config(isInitialized, context) {
|
||||||
if (this.stream.needsScroll) {
|
this.stream.scrollEffect((type, position, animate) => {
|
||||||
this.stream.needsScroll = false;
|
if (type === 'number') {
|
||||||
const locationType = this.stream.locationType;
|
this.scrollToNumber(position, animate);
|
||||||
if (locationType == 'number') {
|
} else if (type === 'index') {
|
||||||
this.scrollToNumber(this.stream.number, this.stream.noAnimationScroll);
|
const backwards = position === this.stream.count() - 1;
|
||||||
} else if (locationType == 'index') {
|
this.scrollToIndex(position, animate, backwards);
|
||||||
const index = this.stream.sanitizeIndex(this.stream.index);
|
|
||||||
const backwards = index == this.stream.count() - 1;
|
|
||||||
this.scrollToIndex(index, this.stream.noAnimationScroll, backwards);
|
|
||||||
}
|
}
|
||||||
this[locationType] = this.stream[locationType];
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (isInitialized) return;
|
if (isInitialized) return;
|
||||||
|
|
||||||
// This is wrapped in setTimeout due to the following Mithril issue:
|
// This is wrapped in setTimeout due to the following Mithril issue:
|
||||||
// https://github.com/lhorie/mithril.js/issues/637
|
// https://github.com/lhorie/mithril.js/issues/637
|
||||||
setTimeout(() => this.scrollListener.start());
|
setTimeout(() => this.scrollListener.start());
|
||||||
@@ -274,28 +271,28 @@ export default class PostStream extends Component {
|
|||||||
* Scroll down to a certain post by number and 'flash' it.
|
* Scroll down to a certain post by number and 'flash' it.
|
||||||
*
|
*
|
||||||
* @param {Integer} number
|
* @param {Integer} number
|
||||||
* @param {Boolean} noAnimation
|
* @param {Boolean} animate
|
||||||
* @return {jQuery.Deferred}
|
* @return {jQuery.Deferred}
|
||||||
*/
|
*/
|
||||||
scrollToNumber(number, noAnimation) {
|
scrollToNumber(number, animate) {
|
||||||
const $item = this.$(`.PostStream-item[data-number=${number}]`);
|
const $item = this.$(`.PostStream-item[data-number=${number}]`);
|
||||||
|
|
||||||
return this.scrollToItem($item, noAnimation).then(this.flashItem.bind(this, $item));
|
return this.scrollToItem($item, animate).then(this.flashItem.bind(this, $item));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scroll down to a certain post by index.
|
* Scroll down to a certain post by index.
|
||||||
*
|
*
|
||||||
* @param {Integer} index
|
* @param {Integer} index
|
||||||
* @param {Boolean} noAnimation
|
* @param {Boolean} animate
|
||||||
* @param {Boolean} bottom Whether or not to scroll to the bottom of the post
|
* @param {Boolean} bottom Whether or not to scroll to the bottom of the post
|
||||||
* at the given index, instead of the top of it.
|
* at the given index, instead of the top of it.
|
||||||
* @return {jQuery.Deferred}
|
* @return {jQuery.Deferred}
|
||||||
*/
|
*/
|
||||||
scrollToIndex(index, noAnimation, bottom) {
|
scrollToIndex(index, animate, bottom) {
|
||||||
const $item = this.$(`.PostStream-item[data-index=${index}]`);
|
const $item = this.$(`.PostStream-item[data-index=${index}]`);
|
||||||
|
|
||||||
return this.scrollToItem($item, noAnimation, true, bottom).then(() => {
|
return this.scrollToItem($item, animate, true, bottom).then(() => {
|
||||||
if (index == this.stream.count() - 1) {
|
if (index == this.stream.count() - 1) {
|
||||||
this.flashItem(this.$('.PostStream-item:last-child'));
|
this.flashItem(this.$('.PostStream-item:last-child'));
|
||||||
}
|
}
|
||||||
@@ -306,14 +303,14 @@ export default class PostStream extends Component {
|
|||||||
* Scroll down to the given post.
|
* Scroll down to the given post.
|
||||||
*
|
*
|
||||||
* @param {jQuery} $item
|
* @param {jQuery} $item
|
||||||
* @param {Boolean} noAnimation
|
* @param {Boolean} animate
|
||||||
* @param {Boolean} force Whether or not to force scrolling to the item, even
|
* @param {Boolean} force Whether or not to force scrolling to the item, even
|
||||||
* if it is already in the viewport.
|
* if it is already in the viewport.
|
||||||
* @param {Boolean} bottom Whether or not to scroll to the bottom of the post
|
* @param {Boolean} bottom Whether or not to scroll to the bottom of the post
|
||||||
* at the given index, instead of the top of it.
|
* at the given index, instead of the top of it.
|
||||||
* @return {jQuery.Deferred}
|
* @return {jQuery.Deferred}
|
||||||
*/
|
*/
|
||||||
scrollToItem($item, noAnimation, force, bottom) {
|
scrollToItem($item, animate, force, bottom) {
|
||||||
const $container = $('html, body').stop(true);
|
const $container = $('html, body').stop(true);
|
||||||
|
|
||||||
if ($item.length) {
|
if ($item.length) {
|
||||||
@@ -328,7 +325,7 @@ export default class PostStream extends Component {
|
|||||||
if (force || itemTop < scrollTop || itemBottom > scrollBottom) {
|
if (force || itemTop < scrollTop || itemBottom > scrollBottom) {
|
||||||
const top = bottom ? itemBottom - $(window).height() + app.composer.computedHeight() : $item.is(':first-child') ? 0 : itemTop;
|
const top = bottom ? itemBottom - $(window).height() + app.composer.computedHeight() : $item.is(':first-child') ? 0 : itemTop;
|
||||||
|
|
||||||
if (noAnimation) {
|
if (!animate) {
|
||||||
$container.scrollTop(top);
|
$container.scrollTop(top);
|
||||||
} else if (top !== scrollTop) {
|
} else if (top !== scrollTop) {
|
||||||
$container.animate({ scrollTop: top }, 'fast');
|
$container.animate({ scrollTop: top }, 'fast');
|
||||||
|
@@ -127,6 +127,28 @@ class PostStreamState {
|
|||||||
return this.loadPromise;
|
return this.loadPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a callback when necessary because the scroll position changed.
|
||||||
|
*
|
||||||
|
* The callback will be called with three arguments:
|
||||||
|
* - the "type" of position to jump to ("number" or "index")
|
||||||
|
* - the corresponding position
|
||||||
|
* - whether scrolling should be animated
|
||||||
|
*
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
scrollEffect(callback) {
|
||||||
|
if (!this.needsScroll) return;
|
||||||
|
|
||||||
|
if (this.locationType === 'number') {
|
||||||
|
callback('number', this.number, !this.noAnimationScroll);
|
||||||
|
} else {
|
||||||
|
callback('index', this.sanitizeIndex(this.index), !this.noAnimationScroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.needsScroll = false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the stream and load posts near a certain number. Returns a promise.
|
* Clear the stream and load posts near a certain number. Returns a promise.
|
||||||
* If the post with the given number is already loaded, the promise will be
|
* If the post with the given number is already loaded, the promise will be
|
||||||
|
Reference in New Issue
Block a user