Convert to state

This commit is contained in:
KyrneDev 2021-02-19 12:57:07 -08:00 committed by Alexander Skvortsov
parent b965a82bb1
commit 4464ab156f
3 changed files with 21 additions and 35 deletions

View File

@ -1,4 +1,5 @@
import Component from '../../common/Component';
import Button from '../../common/components/Button';
import icon from '../../common/helpers/icon';
import formatNumber from '../../common/utils/formatNumber';
import ScrollListener from '../../common/utils/ScrollListener';
@ -19,6 +20,8 @@ export default class PostStreamScrubber extends Component {
this.stream = this.attrs.stream;
this.handlers = {};
this.pendingMoveIndex = null;
this.scrollListener = new ScrollListener(this.updateScrubberValues.bind(this, { fromScroll: true, forceHeightChange: true }));
}
@ -32,9 +35,9 @@ export default class PostStreamScrubber extends Component {
});
const index = this.stream.index;
const previousIndex = this.stream.previousIndex;
const showBackButton =
this.lastPosition > count / 20 && this.lastPosition < count - count / 20 && 100 * Math.abs((index - this.lastPosition) / count) > 25;
const showBackButton = previousIndex > count / 20 && previousIndex < count - count / 20 && 100 * Math.abs((index - previousIndex) / count) > 25;
const unreadCount = this.stream.discussion.unreadCount();
const unreadPercent = count ? Math.min(count - index, unreadCount) / count : 0;
@ -57,6 +60,8 @@ export default class PostStreamScrubber extends Component {
const classNames = ['PostStreamScrubber', 'Dropdown'];
if (this.attrs.className) classNames.push(this.attrs.className);
console.log(showBackButton);
return (
<div className={classNames.join(' ')}>
<button className="Button Dropdown-toggle" data-toggle="dropdown">
@ -70,7 +75,11 @@ export default class PostStreamScrubber extends Component {
</a>
<div className="Scrubber-scrollbar">
{showBackButton ? this.backButton() : ''}
{showBackButton ? (
<a style={'top: ' + this.percentPerPost().index * this.stream.previousIndex + '%'} className="Scrubber-back" onclick={this.returnToLastPosition.bind(this)} title={app.translator.trans('core.forum.post_scrubber.back_title')}>
{icon('fas fa-chevron-left')}
</a>
) : ''}
<div className="Scrubber-before" />
<div className="Scrubber-handle">
<div className="Scrubber-bar" />
@ -95,22 +104,11 @@ export default class PostStreamScrubber extends Component {
);
}
backButton() {
return (
<div style={'top: ' + this.percentPerPost().index * this.lastPosition + '%'} className="Scrubber-back">
{icon('fas fa-minus')}
<button className="Button Button--primary" onclick={this.returnToLastPosition.bind(this)}>
{app.translator.trans('core.forum.post_scrubber.back')}
</button>
</div>
);
}
returnToLastPosition(e) {
// Don't fire the scrubber click event as well
e.stopPropagation();
this.stream.goToIndex(Math.floor(this.lastPosition));
this.stream.goToIndex(Math.floor(this.stream.previousIndex));
this.updateScrubberValues({ animate: true });
this.$().removeClass('open');
@ -184,7 +182,7 @@ export default class PostStreamScrubber extends Component {
* @param {Boolean} animate
*/
updateScrubberValues(options = {}) {
const index = this.stream.index;
const index = this.pendingMoveIndex || this.stream.index;
const count = this.stream.count();
const visible = this.stream.visible || 1;
const percentPerPost = this.percentPerPost();
@ -226,7 +224,6 @@ export default class PostStreamScrubber extends Component {
* Go to the first post in the discussion.
*/
goToFirst() {
this.lastPosition = this.stream.index;
this.stream.goToFirst();
this.updateScrubberValues({ animate: true, forceHeightChange: true });
}
@ -235,7 +232,6 @@ export default class PostStreamScrubber extends Component {
* Go to the last post in the discussion.
*/
goToLast() {
this.lastPosition = this.stream.index;
this.stream.goToLast();
this.updateScrubberValues({ animate: true, forceHeightChange: true });
}
@ -261,7 +257,6 @@ export default class PostStreamScrubber extends Component {
this.mouseStart = e.clientY || e.originalEvent.touches[0].clientY;
this.indexStart = this.stream.index;
this.dragging = true;
this.lastPosition = this.stream.index;
$('body').css('cursor', 'move');
this.$().toggleClass('dragging', this.dragging);
}
@ -278,7 +273,7 @@ export default class PostStreamScrubber extends Component {
const deltaIndex = deltaPercent / this.percentPerPost().index || 0;
const newIndex = Math.min(this.indexStart + deltaIndex, this.stream.count() - 1);
this.stream.index = Math.max(0, newIndex);
this.pendingMoveIndex = Math.max(0, newIndex);
this.updateScrubberValues();
}
@ -295,8 +290,9 @@ export default class PostStreamScrubber extends Component {
// If the index we've landed on is in a gap, then tell the stream-
// content that we want to load those posts.
const intIndex = Math.floor(this.stream.index);
const intIndex = Math.floor(this.pendingMoveIndex);
this.stream.goToIndex(intIndex);
this.pendingMoveIndex = null;
}
onclick(e) {
@ -308,7 +304,6 @@ export default class PostStreamScrubber extends Component {
const $scrollbar = this.$('.Scrubber-scrollbar');
const offsetPixels = (e.pageY || e.originalEvent.touches[0].pageY) - $scrollbar.offset().top + $('body').scrollTop();
let offsetPercent = (offsetPixels / $scrollbar.outerHeight()) * 100;
this.lastPosition = this.stream.index;
// 2. We want the handle of the scrollbar to end up centered on the click
// position. Thus, we calculate the height of the handle in percent and

View File

@ -22,6 +22,7 @@ class PostStreamState {
this.pagesLoading = 0;
this.index = 0;
this.previousIndex = 0;
this.number = 1;
/**
@ -137,6 +138,7 @@ class PostStreamState {
this.needsScroll = true;
this.targetPost = { index };
this.animateScroll = !noAnimation;
this.previousIndex = (index === this.previousIndex) ? index : this.index;
this.index = index;
m.redraw();

View File

@ -24,21 +24,10 @@
}
.Scrubber-back {
position: absolute;
left: 12.5px;
z-index: 1;
.icon {
margin-left: -0.35em;
color: @muted-color;
}
.Button {
padding: 5px;
position: absolute;
left: 15px;
top: -5px;
width: initial;
}
}
.Scrubber-unread {
position: absolute;
border-left: 1px solid lighten(@muted-color, 10%);