Scroll columns area to right when children property is changed (#4517)
The feature to pin column could hide the rightmost column, which is specified with children property of ColumnsArea. The user is likely to see the column when the property changed, so scroll the area in such cases.gh/stable
parent
400616813e
commit
9d1f8b9d6a
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import detectPassiveEvents from 'detect-passive-events';
|
import detectPassiveEvents from 'detect-passive-events';
|
||||||
import scrollTop from '../scroll';
|
import { scrollTop } from '../scroll';
|
||||||
|
|
||||||
export default class Column extends React.PureComponent {
|
export default class Column extends React.PureComponent {
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||||
import ColumnHeader from './column_header';
|
import ColumnHeader from './column_header';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
import scrollTop from '../../../scroll';
|
import { scrollTop } from '../../../scroll';
|
||||||
import { isMobile } from '../../../is_mobile';
|
import { isMobile } from '../../../is_mobile';
|
||||||
|
|
||||||
export default class Column extends React.PureComponent {
|
export default class Column extends React.PureComponent {
|
||||||
|
|
|
@ -12,6 +12,8 @@ import ColumnLoading from './column_loading';
|
||||||
import BundleColumnError from './bundle_column_error';
|
import BundleColumnError from './bundle_column_error';
|
||||||
import { Compose, Notifications, HomeTimeline, CommunityTimeline, PublicTimeline, HashtagTimeline, FavouritedStatuses } from '../../ui/util/async-components';
|
import { Compose, Notifications, HomeTimeline, CommunityTimeline, PublicTimeline, HashtagTimeline, FavouritedStatuses } from '../../ui/util/async-components';
|
||||||
|
|
||||||
|
import { scrollRight } from '../../../scroll';
|
||||||
|
|
||||||
const componentMap = {
|
const componentMap = {
|
||||||
'COMPOSE': Compose,
|
'COMPOSE': Compose,
|
||||||
'HOME': HomeTimeline,
|
'HOME': HomeTimeline,
|
||||||
|
@ -49,9 +51,13 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
||||||
this.setState({ shouldAnimate: true });
|
this.setState({ shouldAnimate: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate(prevProps) {
|
||||||
this.lastIndex = getIndex(this.context.router.history.location.pathname);
|
this.lastIndex = getIndex(this.context.router.history.location.pathname);
|
||||||
this.setState({ shouldAnimate: true });
|
this.setState({ shouldAnimate: true });
|
||||||
|
|
||||||
|
if (this.props.children !== prevProps.children) {
|
||||||
|
scrollRight(this.node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSwipe = (index) => {
|
handleSwipe = (index) => {
|
||||||
|
@ -74,6 +80,10 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setRef = (node) => {
|
||||||
|
this.node = node;
|
||||||
|
}
|
||||||
|
|
||||||
renderView = (link, index) => {
|
renderView = (link, index) => {
|
||||||
const columnIndex = getIndex(this.context.router.history.location.pathname);
|
const columnIndex = getIndex(this.context.router.history.location.pathname);
|
||||||
const title = this.props.intl.formatMessage({ id: link.props['data-preview-title-id'] });
|
const title = this.props.intl.formatMessage({ id: link.props['data-preview-title-id'] });
|
||||||
|
@ -114,7 +124,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='columns-area'>
|
<div className='columns-area' ref={this.setRef}>
|
||||||
{columns.map(column => {
|
{columns.map(column => {
|
||||||
const params = column.get('params', null) === null ? null : column.get('params').toJS();
|
const params = column.get('params', null) === null ? null : column.get('params').toJS();
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
const easingOutQuint = (x, t, b, c, d) => c * ((t = t / d - 1) * t * t * t * t + 1) + b;
|
const easingOutQuint = (x, t, b, c, d) => c * ((t = t / d - 1) * t * t * t * t + 1) + b;
|
||||||
|
|
||||||
const scrollTop = (node) => {
|
const scroll = (node, key, target) => {
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
const offset = node.scrollTop;
|
const offset = node[key];
|
||||||
const targetY = -offset;
|
const gap = target - offset;
|
||||||
const duration = 1000;
|
const duration = 1000;
|
||||||
let interrupt = false;
|
let interrupt = false;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ const scrollTop = (node) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
node.scrollTop = easingOutQuint(0, elapsed, offset, targetY, duration);
|
node[key] = easingOutQuint(0, elapsed, offset, gap, duration);
|
||||||
requestAnimationFrame(step);
|
requestAnimationFrame(step);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,4 +26,5 @@ const scrollTop = (node) => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default scrollTop;
|
export const scrollRight = (node) => scroll(node, 'scrollLeft', node.scrollWidth);
|
||||||
|
export const scrollTop = (node) => scroll(node, 'scrollTop', 0);
|
||||||
|
|
Reference in New Issue