Add some tolerances to breadcrumb scrolling

See https://github.com/vector-im/riot-web/issues/9400
See https://github.com/vector-im/riot-web/issues/9394

Tolerances are defined as a device-only setting to give advanced users an option to override the values. No UI is exposed for this. 

The default values are picked for assumptions on comfort, however as people change the tolerances themselves the defaults may need to change.
This commit is contained in:
Travis Ralston 2019-04-08 10:53:09 -06:00
parent 054011f5f8
commit aa96fd27cc
3 changed files with 36 additions and 3 deletions

View file

@ -29,6 +29,13 @@ export default class IndicatorScrollbar extends React.Component {
// scroll horizontally rather than vertically. This should only be used on components // scroll horizontally rather than vertically. This should only be used on components
// with no vertical scroll opportunity. // with no vertical scroll opportunity.
verticalScrollsHorizontally: PropTypes.bool, verticalScrollsHorizontally: PropTypes.bool,
// An object containing 2 numbers: xyThreshold and yReduction. xyThreshold is the amount
// of horizontal movement required in order to ignore any vertical changes in scroll, and
// only applies when verticalScrollsHorizontally is true. yReduction is the factor to
// multiply the vertical delta by when verticalScrollsHorizontally is true. The default
// behaviour is to have an xyThreshold of infinity and a yReduction of 0.8
scrollTolerances: PropTypes.object,
}; };
constructor(props) { constructor(props) {
@ -120,8 +127,20 @@ export default class IndicatorScrollbar extends React.Component {
onMouseWheel = (e) => { onMouseWheel = (e) => {
if (this.props.verticalScrollsHorizontally && this._scrollElement) { if (this.props.verticalScrollsHorizontally && this._scrollElement) {
const xyThreshold = this.props.scrollTolerances
? this.props.scrollTolerances.xyThreshold
: Number.MAX_SAFE_INTEGER;
const yReduction = this.props.scrollTolerances
? this.props.scrollTolerances.yReduction
: 0.8;
// Don't apply vertical motion to horizontal scrolls. This is meant to eliminate
// trackpads causing excessive scroll motion.
if (e.deltaX >= xyThreshold) return;
// noinspection JSSuspiciousNameCombination // noinspection JSSuspiciousNameCombination
this._scrollElement.scrollLeft += e.deltaY / 2; // divide by 2 to reduce harshness this._scrollElement.scrollLeft += e.deltaY * yReduction;
} }
}; };

View file

@ -33,7 +33,13 @@ const MAX_ROOMS = 20;
export default class RoomBreadcrumbs extends React.Component { export default class RoomBreadcrumbs extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = {rooms: []};
const tolerances = SettingsStore.getValue("breadcrumb_scroll_tolerances");
this.state = {rooms: [], scrollTolerances: tolerances};
// Record this for debugging purposes
console.log("Breadcrumbs scroll tolerances:", tolerances);
this.onAction = this.onAction.bind(this); this.onAction = this.onAction.bind(this);
this._dispatcherRef = null; this._dispatcherRef = null;
} }
@ -334,7 +340,8 @@ export default class RoomBreadcrumbs extends React.Component {
}); });
return ( return (
<IndicatorScrollbar ref="scroller" className="mx_RoomBreadcrumbs" <IndicatorScrollbar ref="scroller" className="mx_RoomBreadcrumbs"
trackHorizontalOverflow={true} verticalScrollsHorizontally={true}> trackHorizontalOverflow={true} verticalScrollsHorizontally={true}
scrollTolerances={this.state.scrollTolerances}>
{ avatars } { avatars }
</IndicatorScrollbar> </IndicatorScrollbar>
); );

View file

@ -262,6 +262,13 @@ export const SETTINGS = {
supportedLevels: ['account'], supportedLevels: ['account'],
default: [], default: [],
}, },
"breadcrumb_scroll_tolerances": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
default: {
xyThreshold: 10,
yReduction: 0.8,
},
},
"analyticsOptIn": { "analyticsOptIn": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
displayName: _td('Send analytics data'), displayName: _td('Send analytics data'),