mirror of
https://github.com/flarum/core.git
synced 2025-08-07 08:56:38 +02:00
Start decoupling scrolling from state
This commit is contained in:
@@ -109,7 +109,12 @@ export default class DiscussionPage extends Page {
|
||||
<ul>{listItems(this.sidebarItems().toArray())}</ul>
|
||||
</nav>
|
||||
<div className="DiscussionPage-stream">
|
||||
{PostStream.component({ discussion, stream: this.stream, onPositionChange: this.positionChanged.bind(this) })}
|
||||
{PostStream.component({
|
||||
discussion,
|
||||
stream: this.stream,
|
||||
targetPost: this.stream.targetPost,
|
||||
onPositionChange: this.positionChanged.bind(this),
|
||||
})}
|
||||
</div>
|
||||
</div>,
|
||||
]
|
||||
|
@@ -12,6 +12,7 @@ import Button from '../../common/components/Button';
|
||||
*
|
||||
* - `discussion`
|
||||
* - `stream`
|
||||
* - `targetPost`
|
||||
* - `onPositionChange`
|
||||
*/
|
||||
export default class PostStream extends Component {
|
||||
@@ -102,14 +103,7 @@ export default class PostStream extends Component {
|
||||
}
|
||||
|
||||
config(isInitialized, context) {
|
||||
this.stream.scrollEffect((type, position, animate) => {
|
||||
if (type === 'number') {
|
||||
this.scrollToNumber(position, animate);
|
||||
} else if (type === 'index') {
|
||||
const backwards = position === this.stream.count() - 1;
|
||||
this.scrollToIndex(position, animate, backwards);
|
||||
}
|
||||
});
|
||||
this.triggerScroll();
|
||||
|
||||
if (isInitialized) return;
|
||||
|
||||
@@ -123,6 +117,30 @@ export default class PostStream extends Component {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Start scrolling, if appropriate, to a newly-targeted post.
|
||||
*/
|
||||
triggerScroll() {
|
||||
if (!this.props.targetPost) return;
|
||||
|
||||
const oldTarget = this.prevTarget;
|
||||
const newTarget = this.props.targetPost;
|
||||
|
||||
if (oldTarget) {
|
||||
if ('number' in oldTarget && oldTarget.number === newTarget.number) return;
|
||||
if ('index' in oldTarget && oldTarget.index === newTarget.index) return;
|
||||
}
|
||||
|
||||
if ('number' in newTarget) {
|
||||
this.scrollToNumber(newTarget.number, this.stream.noAnimationScroll);
|
||||
} else if ('index' in newTarget) {
|
||||
const backwards = newTarget.index === this.stream.count() - 1;
|
||||
this.scrollToIndex(newTarget.index, this.stream.noAnimationScroll, backwards);
|
||||
}
|
||||
|
||||
this.prevTarget = newTarget;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the window is scrolled, check if either extreme of the post stream is
|
||||
* in the viewport, and if so, trigger loading the next/previous page.
|
||||
|
@@ -20,7 +20,6 @@ class PostStreamState {
|
||||
this.loadPageTimeouts = {};
|
||||
this.pagesLoading = 0;
|
||||
|
||||
this.locationType = null;
|
||||
this.index = 0;
|
||||
this.number = 1;
|
||||
|
||||
@@ -92,9 +91,8 @@ class PostStreamState {
|
||||
|
||||
this.loadPromise = this.loadNearNumber(number);
|
||||
|
||||
this.needsScroll = true;
|
||||
this.targetPost = { number };
|
||||
this.noAnimationScroll = noAnimation;
|
||||
this.locationType = 'number';
|
||||
this.number = number;
|
||||
|
||||
// In this case, the redraw is only called after the response has been loaded
|
||||
@@ -117,9 +115,8 @@ class PostStreamState {
|
||||
|
||||
this.loadPromise = this.loadNearIndex(index);
|
||||
|
||||
this.needsScroll = true;
|
||||
this.targetPost = { index };
|
||||
this.noAnimationScroll = noAnimation;
|
||||
this.locationType = 'index';
|
||||
this.index = index;
|
||||
|
||||
m.redraw();
|
||||
@@ -127,28 +124,6 @@ class PostStreamState {
|
||||
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.
|
||||
* If the post with the given number is already loaded, the promise will be
|
||||
|
Reference in New Issue
Block a user