]> cat aescling's git repositories - mastodon.git/commitdiff
[Glitch] Fix scroll to top in single column UI
authorEugen Rochko <eugen@zeonfederated.com>
Thu, 1 Aug 2019 17:17:17 +0000 (19:17 +0200)
committerThibaut Girka <thib@sitedethib.com>
Sat, 5 Oct 2019 22:32:06 +0000 (00:32 +0200)
Port 2dee293c4c98486d387105224023fad02b8b0d96 to glitch-soc

Signed-off-by: Thibaut Girka <thib@sitedethib.com>
27 files changed:
app/javascript/flavours/glitch/components/column.js
app/javascript/flavours/glitch/components/column_back_button.js
app/javascript/flavours/glitch/features/account/components/profile_column_header.js
app/javascript/flavours/glitch/features/account_gallery/index.js
app/javascript/flavours/glitch/features/account_timeline/index.js
app/javascript/flavours/glitch/features/blocks/index.js
app/javascript/flavours/glitch/features/community_timeline/index.js
app/javascript/flavours/glitch/features/direct_timeline/index.js
app/javascript/flavours/glitch/features/domain_blocks/index.js
app/javascript/flavours/glitch/features/favourited_statuses/index.js
app/javascript/flavours/glitch/features/favourites/index.js
app/javascript/flavours/glitch/features/follow_requests/index.js
app/javascript/flavours/glitch/features/followers/index.js
app/javascript/flavours/glitch/features/following/index.js
app/javascript/flavours/glitch/features/getting_started/index.js
app/javascript/flavours/glitch/features/hashtag_timeline/index.js
app/javascript/flavours/glitch/features/home_timeline/index.js
app/javascript/flavours/glitch/features/keyboard_shortcuts/index.js
app/javascript/flavours/glitch/features/list_timeline/index.js
app/javascript/flavours/glitch/features/lists/index.js
app/javascript/flavours/glitch/features/mutes/index.js
app/javascript/flavours/glitch/features/notifications/index.js
app/javascript/flavours/glitch/features/pinned_statuses/index.js
app/javascript/flavours/glitch/features/public_timeline/index.js
app/javascript/flavours/glitch/features/reblogs/index.js
app/javascript/flavours/glitch/features/status/index.js
app/javascript/flavours/glitch/styles/components/columns.scss

index dc87818a519719823fea5314249ee9df05e35412..5819d5362cf9e822d923d5d993e057875babce01 100644 (file)
@@ -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,11 +36,19 @@ export default class Column extends React.PureComponent {
   }
 
   componentDidMount () {
-    this.node.addEventListener('wheel', this.handleWheel,  detectPassiveEvents.hasSupport ? { passive: true } : false);
+    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 () {
-    this.node.removeEventListener('wheel', this.handleWheel);
+    if (this.props.bindToDocument) {
+      document.removeEventListener('wheel', this.handleWheel);
+    } else {
+      this.node.removeEventListener('wheel', this.handleWheel);
+    }
   }
 
   render () {
index a0260e5af7b5055cbc7c0c60f31c82eaddda2166..8326cbb79da6282802afbd017b50e22cc4dbe89a 100644 (file)
@@ -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'));
+    }
   }
 
 }
index b6d373a2c48bb250eb55e498ffff111a180c3ad5..17c08e375adefc0e07cddff8c086e4dda6feb1a5 100644 (file)
@@ -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}
       />
     );
   }
index ff39764bb9f7c157e94f2f262f668d3a40ca00e4..f5fe6c930c764e2295aaea0e8362998c4d737734 100644 (file)
@@ -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}>
index a6ed4564c5c4e64274362742ed6b979d17abb56f..1f02c1be5256c787175d860c5257546e89c9f6f1 100644 (file)
@@ -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} />}
index ae0cdf2fedf330987c86af2b3f9a333c10c607d2..9eb6fe02ed5df8820ab60f348a9412dc022cf149 100644 (file)
@@ -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'
index ca437d2b092b238c81fc2bfd9a64cb96b96128a9..c548824ce3165e11a7efeeb9f6a5f456a4481f6f 100644 (file)
@@ -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}
index e2c0a439a81ce5b3593c8fe550288d5ed7b0574b..7741c69220f433225691a9709fb88fe47562933a 100644 (file)
@@ -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}
index b92ce349b46522d64b3727b0cc0e92f316d5afe0..cd105a49bdebfe1d0c605dafdcc0100694c180fd 100644 (file)
@@ -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'
index 99b532294c9cd03eeb9446de6cac7f776c67253a..c6470ba749ee22d6992558f5be20aee9e6d9b53f 100644 (file)
@@ -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)}
index 3c0c2a905d8a04789f898b030f5c3608d41fc57b..da118899e9baa7da517610bc502a67d474ff2daa 100644 (file)
@@ -71,6 +71,7 @@ class Favourites extends ImmutablePureComponent {
           title={intl.formatMessage(messages.heading)}
           onClick={this.handleHeaderClick}
           showBackButton
+          multiColumn={multiColumn}
         />
         <ScrollableList
           scrollKey='favourites'
index 04c1f36350945fede78359604897de8e76fd1b76..36770aaceed852c7626e44652272926df5aaf5b6 100644 (file)
@@ -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
index 39fdffae6d8344b725ec3663173ffdf7794c1b40..c78dcc8e445d5b3c66b66e391bab1e614011105e 100644 (file)
@@ -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'
index 493f86a6651ad62c971aff34ab65e24f1db33373..df7c19c22bb892485bfa0c0305b053b6b4fa8605 100644 (file)
@@ -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'
index a5095fbd99cda94999e7185373ee3d53707df5f3..d8a51c6892f6f088a3a2c87a2e94346589377102 100644 (file)
@@ -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} />}
index b64b4bf13889c54f91a618f97c261f0212d9577d..16dd80c4fc812aa4d4b01f49f367a8ac0d3232f5 100644 (file)
@@ -145,6 +145,7 @@ class HashtagTimeline extends React.PureComponent {
           pinned={pinned}
           multiColumn={multiColumn}
           showBackButton
+          bindToDocument={!multiColumn}
         >
           {columnId && <ColumnSettingsContainer columnId={columnId} />}
         </ColumnHeader>
index b01c8cced29ab932b2d6d489216f856dd8010e93..9b71a44040325806aa028dccab913c59df4e2ea6 100644 (file)
@@ -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}
index 95daa69075f20ad49837297c6d79281574f87209..e40dbf44e64cc16e7078efc1322131d6e9c2db83 100644 (file)
@@ -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>
index f4b926e3c07784210abc96255708895e90a08bce..908a655970516afff7707d0b134bfcc458aea2c2 100644 (file)
@@ -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}>
index 8d1b9d3ff8a9c65c3760bf47ab2edbe19f042a91..adde3dd5c81ccbc7ec347b622b35c6df77565218 100644 (file)
@@ -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 />
index e5a8010b4c4ef428b1dabbad8c2fe423435d388d..c27a530d50b835e417ac00eef158702a45102c33 100644 (file)
@@ -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'
index 785a7dc5105161e5389ee64cdb0b3c4eec3e552c..7f06d70c58a8acd01eff20a48cb75955038ab912 100644 (file)
@@ -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}
index b0db90c2ca8998efa666b63accea431d0635f91d..34d8e465f7577096917006b877dcfd757ad127ef 100644 (file)
@@ -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}
index b64c634ac27b8e21a0713f05a652e37d3ad796ba..49a5011c000186214e12adf707ec5898875316ed 100644 (file)
@@ -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}
index 808b25b9e36947efe4d87d86c475ba9a439415b3..c842c4ec048ded8d0ba22098f4c52e3da34adfde 100644 (file)
@@ -71,6 +71,7 @@ class Reblogs extends ImmutablePureComponent {
           title={intl.formatMessage(messages.heading)}
           onClick={this.handleHeaderClick}
           showBackButton
+          multiColumn={multiColumn}
         />
 
         <ScrollableList
index ba5025b19702c6f195fd07ca5705efa2e63503f9..508510c4ef33b06792a592340dc4428caa9dc604 100644 (file)
@@ -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)}
index 1ff4ac5544dbd59fc40c993c436eb94708614531..2498e5d03cafdc09a518461945fd9e72d3d06870 100644 (file)
 }
 
 .column-back-button {
+  box-sizing: border-box;
+  width: 100%;
   background: lighten($ui-base-color, 4%);
   color: $highlight-text-color;
   cursor: pointer;