Restore scrubber behavior

This commit is contained in:
Alexander Skvortsov 2020-07-07 20:27:38 -04:00 committed by Franz Liedke
parent d20650fb42
commit cdcf64852e
No known key found for this signature in database
GPG Key ID: 9A0231A879B055F4
4 changed files with 39 additions and 15 deletions

View File

@ -3,7 +3,6 @@ import ScrollListener from '../../common/utils/ScrollListener';
import PostLoading from './LoadingPost';
import ReplyPlaceholder from './ReplyPlaceholder';
import Button from '../../common/components/Button';
import anchorScroll from '../../common/utils/anchorScroll';
/**
* The `PostStream` component displays an infinitely-scrollable wall of posts in
@ -219,13 +218,9 @@ export default class PostStream extends Component {
}
});
const indexChanged = Math.floor(this.state.index) != Math.floor(index);
this.state.index = index;
this.state.visible = visible;
this.state.visible(visible);
this.state.description = period ? dayjs(period).format('MMMM YYYY') : '';
if (indexChanged) {
m.redraw();
}
}
/**

View File

@ -1,6 +1,7 @@
import Component from '../../common/Component';
import icon from '../../common/helpers/icon';
import formatNumber from '../../common/utils/formatNumber';
import ScrollListener from '../../common/utils/ScrollListener';
/**
* The `PostStreamScrubber` component displays a scrubber which can be used to
@ -15,12 +16,14 @@ export default class PostStreamScrubber extends Component {
init() {
this.state = this.props.state;
this.handlers = {};
this.scrollListener = new ScrollListener(this.updateScrubberValues.bind(this));
}
view() {
const index = this.state.index;
const count = this.state.count();
const visible = this.state.visible || 1;
const visible = this.state.visible() || 1;
const unreadCount = this.state.discussion.unreadCount();
const unreadPercent = count ? Math.min(count - this.state.index, unreadCount) / count : 0;
@ -104,7 +107,7 @@ export default class PostStreamScrubber extends Component {
*/
percentPerPost() {
const count = this.state.count() || 1;
const visible = this.state.visible || 1;
const visible = this.state.visible() || 1;
// To stop the handle of the scrollbar from getting too small when there
// are many posts, we define a minimum percentage height for the handle
@ -179,9 +182,12 @@ export default class PostStreamScrubber extends Component {
$(document)
.on('mousemove touchmove', (this.handlers.onmousemove = this.onmousemove.bind(this)))
.on('mouseup touchend', (this.handlers.onmouseup = this.onmouseup.bind(this)));
setTimeout(() => this.scrollListener.start());
}
ondestroy() {
this.scrollListener.stop();
$(window).off('resize', this.handlers.onresize);
$(document).off('mousemove touchmove', this.handlers.onmousemove).off('mouseup touchend', this.handlers.onmouseup);
@ -208,6 +214,7 @@ export default class PostStreamScrubber extends Component {
this.indexStart = this.state.index;
this.dragging = true;
$('body').css('cursor', 'move');
this.$().toggleClass('dragging', this.dragging);
}
onmousemove(e) {
@ -223,10 +230,11 @@ export default class PostStreamScrubber extends Component {
const newIndex = Math.min(this.indexStart + deltaIndex, this.state.count() - 1);
this.state.index = Math.max(0, newIndex);
m.redraw();
this.updateScrubberValues();
}
onmouseup() {
this.$().toggleClass('dragging', this.dragging);
if (!this.dragging) return;
this.mouseStart = 0;
@ -264,4 +272,25 @@ export default class PostStreamScrubber extends Component {
this.$().removeClass('open');
}
updateScrubberValues() {
console.log(this.dragging);
const index = this.state.index;
const count = this.state.count();
const visible = this.state.visible() || 1;
const percentPerPost = this.percentPerPost();
this.$(`.Scrubber-index`).html(formatNumber(this.state.sanitizeIndex(index + 1)));
const heights = {};
heights.before = Math.max(0, percentPerPost.index * Math.min(index, count - visible));
heights.handle = Math.min(100 - heights.before, percentPerPost.visible * visible);
heights.after = 100 - heights.before - heights.handle;
for (const part in heights) {
this.$(`.Scrubber-${part}`).css('height', heights[part] + '%');
}
this.$().toggleClass('disabled', this.state.allVisible());
}
}

View File

@ -29,7 +29,7 @@ class PostStreamState {
*
* @type {Number}
*/
this.visible = 1;
this.visible = m.prop(1);
/**
* The description to render on the scrubber.
@ -173,7 +173,7 @@ class PostStreamState {
* @return {Boolean}
*/
allVisible() {
return this.visible >= this.count();
return this.visible() >= this.count();
}
/**

View File

@ -21,13 +21,13 @@
}
.Scrubber-before, .Scrubber-after {
border-left: 1px solid @control-bg;
transition: height 0.15s ease-out;
transition: height 0.15s linear;
}
.Scrubber-before, .Scrubber-after {
.Scrubber-handle {
border-left: 1px solid @control-bg;
transition: height 0.15s ease-out;
transition: height 0.25s ease-in;
}
.dragging .Scrubber-before, .dragging .Scrubber-after {
.dragging .Scrubber-before, .dragging .Scrubber-after, .dragging .Scrubber-handle {
transition: none;
}
.Scrubber-unread {