[Glitch] Fix scroll to top in single column UI
Port 2dee293c4c
to glitch-soc
Signed-off-by: Thibaut Girka <thib@sitedethib.com>
pull/1229/head
parent
fdadd520b1
commit
90bdbddbfe
|
@ -10,10 +10,11 @@ export default class Column extends React.PureComponent {
|
|||
extraClasses: PropTypes.string,
|
||||
name: PropTypes.string,
|
||||
label: PropTypes.string,
|
||||
bindToDocument: PropTypes.bool,
|
||||
};
|
||||
|
||||
scrollTop () {
|
||||
const scrollable = this.node.querySelector('.scrollable');
|
||||
const scrollable = this.props.bindToDocument ? document.scrollingElement : this.node.querySelector('.scrollable');
|
||||
|
||||
if (!scrollable) {
|
||||
return;
|
||||
|
@ -35,12 +36,20 @@ export default class Column extends React.PureComponent {
|
|||
}
|
||||
|
||||
componentDidMount () {
|
||||
if (this.props.bindToDocument) {
|
||||
document.addEventListener('wheel', this.handleWheel, detectPassiveEvents.hasSupport ? { passive: true } : false);
|
||||
} else {
|
||||
this.node.addEventListener('wheel', this.handleWheel, detectPassiveEvents.hasSupport ? { passive: true } : false);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
if (this.props.bindToDocument) {
|
||||
document.removeEventListener('wheel', this.handleWheel);
|
||||
} else {
|
||||
this.node.removeEventListener('wheel', this.handleWheel);
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { children, extraClasses, name, label } = this.props;
|
||||
|
|
|
@ -2,6 +2,7 @@ import React from 'react';
|
|||
import { FormattedMessage } from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
import Icon from 'flavours/glitch/components/icon';
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
export default class ColumnBackButton extends React.PureComponent {
|
||||
|
||||
|
@ -9,6 +10,10 @@ export default class ColumnBackButton extends React.PureComponent {
|
|||
router: PropTypes.object,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
multiColumn: PropTypes.bool,
|
||||
};
|
||||
|
||||
handleClick = (event) => {
|
||||
// if history is exhausted, or we would leave mastodon, just go to root.
|
||||
if (window.history.state) {
|
||||
|
@ -24,12 +29,20 @@ export default class ColumnBackButton extends React.PureComponent {
|
|||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
const { multiColumn } = this.props;
|
||||
|
||||
const component = (
|
||||
<button onClick={this.handleClick} className='column-back-button'>
|
||||
<Icon id='chevron-left' className='column-back-button__icon' fixedWidth />
|
||||
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
|
||||
</button>
|
||||
);
|
||||
|
||||
if (multiColumn) {
|
||||
return component;
|
||||
} else {
|
||||
return createPortal(component, document.getElementById('tabs-bar__portal'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,11 +12,12 @@ class ProfileColumnHeader extends React.PureComponent {
|
|||
|
||||
static propTypes = {
|
||||
onClick: PropTypes.func,
|
||||
multiColumn: PropTypes.bool,
|
||||
intl: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
render() {
|
||||
const { onClick, intl } = this.props;
|
||||
const { onClick, intl, multiColumn } = this.props;
|
||||
|
||||
return (
|
||||
<ColumnHeader
|
||||
|
@ -24,6 +25,7 @@ class ProfileColumnHeader extends React.PureComponent {
|
|||
title={intl.formatMessage(messages.profile)}
|
||||
onClick={onClick}
|
||||
showBackButton
|
||||
multiColumn={multiColumn}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ class AccountGallery extends ImmutablePureComponent {
|
|||
isLoading: PropTypes.bool,
|
||||
hasMore: PropTypes.bool,
|
||||
isAccount: PropTypes.bool,
|
||||
multiColumn: PropTypes.bool,
|
||||
};
|
||||
|
||||
state = {
|
||||
|
@ -130,7 +131,7 @@ class AccountGallery extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
render () {
|
||||
const { attachments, isLoading, hasMore, isAccount } = this.props;
|
||||
const { attachments, isLoading, hasMore, isAccount, multiColumn } = this.props;
|
||||
const { width } = this.state;
|
||||
|
||||
if (!isAccount) {
|
||||
|
@ -157,7 +158,7 @@ class AccountGallery extends ImmutablePureComponent {
|
|||
|
||||
return (
|
||||
<Column ref={this.setColumnRef}>
|
||||
<ProfileColumnHeader onClick={this.handleHeaderClick} />
|
||||
<ProfileColumnHeader onClick={this.handleHeaderClick} multiColumn={multiColumn} />
|
||||
|
||||
<ScrollContainer scrollKey='account_gallery' shouldUpdateScroll={this.shouldUpdateScroll}>
|
||||
<div className='scrollable scrollable--flex' onScroll={this.handleScroll}>
|
||||
|
|
|
@ -97,7 +97,7 @@ class AccountTimeline extends ImmutablePureComponent {
|
|||
|
||||
return (
|
||||
<Column ref={this.setRef} name='account'>
|
||||
<ProfileColumnHeader onClick={this.handleHeaderClick} />
|
||||
<ProfileColumnHeader onClick={this.handleHeaderClick} multiColumn={multiColumn} />
|
||||
|
||||
<StatusList
|
||||
prepend={<HeaderContainer accountId={this.props.params.accountId} />}
|
||||
|
|
|
@ -56,7 +56,7 @@ class Blocks extends ImmutablePureComponent {
|
|||
const emptyMessage = <FormattedMessage id='empty_column.blocks' defaultMessage="You haven't blocked any users yet." />;
|
||||
|
||||
return (
|
||||
<Column name='blocks' icon='ban' heading={intl.formatMessage(messages.heading)}>
|
||||
<Column name='blocks' bindToDocument={!multiColumn} icon='ban' heading={intl.formatMessage(messages.heading)}>
|
||||
<ColumnBackButtonSlim />
|
||||
<ScrollableList
|
||||
scrollKey='blocks'
|
||||
|
|
|
@ -105,7 +105,7 @@ class CommunityTimeline extends React.PureComponent {
|
|||
const pinned = !!columnId;
|
||||
|
||||
return (
|
||||
<Column ref={this.setRef} name='local' label={intl.formatMessage(messages.title)}>
|
||||
<Column ref={this.setRef} name='local' bindToDocument={!multiColumn} label={intl.formatMessage(messages.title)}>
|
||||
<ColumnHeader
|
||||
icon='users'
|
||||
active={hasUnread}
|
||||
|
|
|
@ -135,7 +135,7 @@ class DirectTimeline extends React.PureComponent {
|
|||
}
|
||||
|
||||
return (
|
||||
<Column ref={this.setRef} label={intl.formatMessage(messages.title)}>
|
||||
<Column bindToDocument={!multiColumn} ref={this.setRef} label={intl.formatMessage(messages.title)}>
|
||||
<ColumnHeader
|
||||
icon='envelope'
|
||||
active={hasUnread}
|
||||
|
|
|
@ -57,7 +57,7 @@ class Blocks extends ImmutablePureComponent {
|
|||
const emptyMessage = <FormattedMessage id='empty_column.domain_blocks' defaultMessage='There are no hidden domains yet.' />;
|
||||
|
||||
return (
|
||||
<Column icon='minus-circle' heading={intl.formatMessage(messages.heading)}>
|
||||
<Column bindToDocument={!multiColumn} icon='minus-circle' heading={intl.formatMessage(messages.heading)}>
|
||||
<ColumnBackButtonSlim />
|
||||
<ScrollableList
|
||||
scrollKey='domain_blocks'
|
||||
|
|
|
@ -73,7 +73,7 @@ class Favourites extends ImmutablePureComponent {
|
|||
const emptyMessage = <FormattedMessage id='empty_column.favourited_statuses' defaultMessage="You don't have any favourite toots yet. When you favourite one, it will show up here." />;
|
||||
|
||||
return (
|
||||
<Column ref={this.setRef} name='favourites' label={intl.formatMessage(messages.heading)}>
|
||||
<Column bindToDocument={!multiColumn} ref={this.setRef} name='favourites' label={intl.formatMessage(messages.heading)}>
|
||||
<ColumnHeader
|
||||
icon='star'
|
||||
title={intl.formatMessage(messages.heading)}
|
||||
|
|
|
@ -71,6 +71,7 @@ class Favourites extends ImmutablePureComponent {
|
|||
title={intl.formatMessage(messages.heading)}
|
||||
onClick={this.handleHeaderClick}
|
||||
showBackButton
|
||||
multiColumn={multiColumn}
|
||||
/>
|
||||
<ScrollableList
|
||||
scrollKey='favourites'
|
||||
|
|
|
@ -56,7 +56,7 @@ class FollowRequests extends ImmutablePureComponent {
|
|||
const emptyMessage = <FormattedMessage id='empty_column.follow_requests' defaultMessage="You don't have any follow requests yet. When you receive one, it will show up here." />;
|
||||
|
||||
return (
|
||||
<Column name='follow-requests' icon='user-plus' heading={intl.formatMessage(messages.heading)}>
|
||||
<Column bindToDocument={!multiColumn} name='follow-requests' icon='user-plus' heading={intl.formatMessage(messages.heading)}>
|
||||
<ColumnBackButtonSlim />
|
||||
|
||||
<ScrollableList
|
||||
|
|
|
@ -93,7 +93,7 @@ class Followers extends ImmutablePureComponent {
|
|||
|
||||
return (
|
||||
<Column ref={this.setRef}>
|
||||
<ProfileColumnHeader onClick={this.handleHeaderClick} />
|
||||
<ProfileColumnHeader onClick={this.handleHeaderClick} multiColumn={multiColumn} />
|
||||
|
||||
<ScrollableList
|
||||
scrollKey='followers'
|
||||
|
|
|
@ -93,7 +93,7 @@ class Following extends ImmutablePureComponent {
|
|||
|
||||
return (
|
||||
<Column ref={this.setRef}>
|
||||
<ProfileColumnHeader onClick={this.handleHeaderClick} />
|
||||
<ProfileColumnHeader onClick={this.handleHeaderClick} multiColumn={multiColumn} />
|
||||
|
||||
<ScrollableList
|
||||
scrollKey='following'
|
||||
|
|
|
@ -166,7 +166,7 @@ const NAVIGATION_PANEL_BREAKPOINT = 600 + (285 * 2) + (10 * 2);
|
|||
]);
|
||||
|
||||
return (
|
||||
<Column name='getting-started' icon='asterisk' heading={intl.formatMessage(messages.heading)} label={intl.formatMessage(messages.menu)} hideHeadingOnMobile>
|
||||
<Column bindToDocument={!multiColumn} name='getting-started' icon='asterisk' heading={intl.formatMessage(messages.heading)} label={intl.formatMessage(messages.menu)} hideHeadingOnMobile>
|
||||
<div className='scrollable optionally-scrollable'>
|
||||
<div className='getting-started__wrapper'>
|
||||
{!multiColumn && <NavigationBar account={myAccount} />}
|
||||
|
|
|
@ -145,6 +145,7 @@ class HashtagTimeline extends React.PureComponent {
|
|||
pinned={pinned}
|
||||
multiColumn={multiColumn}
|
||||
showBackButton
|
||||
bindToDocument={!multiColumn}
|
||||
>
|
||||
{columnId && <ColumnSettingsContainer columnId={columnId} />}
|
||||
</ColumnHeader>
|
||||
|
|
|
@ -97,7 +97,7 @@ class HomeTimeline extends React.PureComponent {
|
|||
const pinned = !!columnId;
|
||||
|
||||
return (
|
||||
<Column ref={this.setRef} name='home' label={intl.formatMessage(messages.title)}>
|
||||
<Column bindToDocument={!multiColumn} ref={this.setRef} name='home' label={intl.formatMessage(messages.title)}>
|
||||
<ColumnHeader
|
||||
icon='home'
|
||||
active={hasUnread}
|
||||
|
|
|
@ -25,10 +25,10 @@ class KeyboardShortcuts extends ImmutablePureComponent {
|
|||
};
|
||||
|
||||
render () {
|
||||
const { intl, collapseEnabled } = this.props;
|
||||
const { intl, collapseEnabled, multiColumn } = this.props;
|
||||
|
||||
return (
|
||||
<Column icon='question' heading={intl.formatMessage(messages.heading)}>
|
||||
<Column bindToDocument={!multiColumn} icon='question' heading={intl.formatMessage(messages.heading)}>
|
||||
<ColumnBackButtonSlim />
|
||||
<div className='keyboard-shortcuts scrollable optionally-scrollable'>
|
||||
<table>
|
||||
|
|
|
@ -174,6 +174,7 @@ class ListTimeline extends React.PureComponent {
|
|||
onClick={this.handleHeaderClick}
|
||||
pinned={pinned}
|
||||
multiColumn={multiColumn}
|
||||
bindToDocument={!multiColumn}
|
||||
>
|
||||
<div className='column-header__links'>
|
||||
<button className='text-btn column-header__setting-btn' tabIndex='0' onClick={this.handleEditClick}>
|
||||
|
|
|
@ -61,7 +61,7 @@ class Lists extends ImmutablePureComponent {
|
|||
const emptyMessage = <FormattedMessage id='empty_column.lists' defaultMessage="You don't have any lists yet. When you create one, it will show up here." />;
|
||||
|
||||
return (
|
||||
<Column icon='bars' heading={intl.formatMessage(messages.heading)}>
|
||||
<Column bindToDocument={!multiColumn} icon='bars' heading={intl.formatMessage(messages.heading)}>
|
||||
<ColumnBackButtonSlim />
|
||||
|
||||
<NewListForm />
|
||||
|
|
|
@ -56,7 +56,7 @@ class Mutes extends ImmutablePureComponent {
|
|||
const emptyMessage = <FormattedMessage id='empty_column.mutes' defaultMessage="You haven't muted any users yet." />;
|
||||
|
||||
return (
|
||||
<Column name='mutes' icon='volume-off' heading={intl.formatMessage(messages.heading)}>
|
||||
<Column bindToDocument={!multiColumn} name='mutes' icon='volume-off' heading={intl.formatMessage(messages.heading)}>
|
||||
<ColumnBackButtonSlim />
|
||||
<ScrollableList
|
||||
scrollKey='mutes'
|
||||
|
|
|
@ -234,6 +234,7 @@ class Notifications extends React.PureComponent {
|
|||
|
||||
return (
|
||||
<Column
|
||||
bindToDocument={!multiColumn}
|
||||
ref={this.setColumnRef}
|
||||
name='notifications'
|
||||
extraClasses={this.props.notifCleaningActive ? 'notif-cleaning' : null}
|
||||
|
|
|
@ -46,7 +46,7 @@ class PinnedStatuses extends ImmutablePureComponent {
|
|||
const { intl, statusIds, hasMore, multiColumn } = this.props;
|
||||
|
||||
return (
|
||||
<Column icon='thumb-tack' heading={intl.formatMessage(messages.heading)} ref={this.setRef}>
|
||||
<Column bindToDocument={!multiColumn} icon='thumb-tack' heading={intl.formatMessage(messages.heading)} ref={this.setRef}>
|
||||
<ColumnBackButtonSlim />
|
||||
<StatusList
|
||||
statusIds={statusIds}
|
||||
|
|
|
@ -104,7 +104,7 @@ class PublicTimeline extends React.PureComponent {
|
|||
const pinned = !!columnId;
|
||||
|
||||
return (
|
||||
<Column ref={this.setRef} name='federated' label={intl.formatMessage(messages.title)}>
|
||||
<Column bindToDocument={!multiColumn} ref={this.setRef} name='federated' label={intl.formatMessage(messages.title)}>
|
||||
<ColumnHeader
|
||||
icon='globe'
|
||||
active={hasUnread}
|
||||
|
|
|
@ -71,6 +71,7 @@ class Reblogs extends ImmutablePureComponent {
|
|||
title={intl.formatMessage(messages.heading)}
|
||||
onClick={this.handleHeaderClick}
|
||||
showBackButton
|
||||
multiColumn={multiColumn}
|
||||
/>
|
||||
|
||||
<ScrollableList
|
||||
|
|
|
@ -532,7 +532,7 @@ class Status extends ImmutablePureComponent {
|
|||
};
|
||||
|
||||
return (
|
||||
<Column ref={this.setColumnRef} label={intl.formatMessage(messages.detailedStatus)}>
|
||||
<Column bindToDocument={!multiColumn} ref={this.setColumnRef} label={intl.formatMessage(messages.detailedStatus)}>
|
||||
<ColumnHeader
|
||||
icon='comment'
|
||||
title={intl.formatMessage(messages.tootHeading)}
|
||||
|
|
|
@ -112,6 +112,8 @@
|
|||
}
|
||||
|
||||
.column-back-button {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
background: lighten($ui-base-color, 4%);
|
||||
color: $highlight-text-color;
|
||||
cursor: pointer;
|
||||
|
|
Loading…
Reference in New Issue