Hide some components rather than unmounting (#2271)
Hide some components rather than unmounting them to allow to show again quickly and keep the view state such as the scrolled offset.
This commit is contained in:
		
							parent
							
								
									72c984e105
								
							
						
					
					
						commit
						cf845fed38
					
				@ -60,7 +60,7 @@ class StatusList extends React.PureComponent {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  render () {
 | 
					  render () {
 | 
				
			||||||
    const { statusIds, onScrollToBottom, trackScroll, isLoading, isUnread, hasMore, prepend, emptyMessage } = this.props;
 | 
					    const { statusIds, onScrollToBottom, scrollKey, shouldUpdateScroll, isLoading, isUnread, hasMore, prepend, emptyMessage } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let loadMore       = '';
 | 
					    let loadMore       = '';
 | 
				
			||||||
    let scrollableArea = '';
 | 
					    let scrollableArea = '';
 | 
				
			||||||
@ -98,25 +98,22 @@ class StatusList extends React.PureComponent {
 | 
				
			|||||||
      );
 | 
					      );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (trackScroll) {
 | 
					    return (
 | 
				
			||||||
      return (
 | 
					      <ScrollContainer scrollKey={scrollKey} shouldUpdateScroll={shouldUpdateScroll}>
 | 
				
			||||||
        <ScrollContainer scrollKey='status-list'>
 | 
					        {scrollableArea}
 | 
				
			||||||
          {scrollableArea}
 | 
					      </ScrollContainer>
 | 
				
			||||||
        </ScrollContainer>
 | 
					    );
 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      return scrollableArea;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
StatusList.propTypes = {
 | 
					StatusList.propTypes = {
 | 
				
			||||||
 | 
					  scrollKey: PropTypes.string.isRequired,
 | 
				
			||||||
  statusIds: ImmutablePropTypes.list.isRequired,
 | 
					  statusIds: ImmutablePropTypes.list.isRequired,
 | 
				
			||||||
  onScrollToBottom: PropTypes.func,
 | 
					  onScrollToBottom: PropTypes.func,
 | 
				
			||||||
  onScrollToTop: PropTypes.func,
 | 
					  onScrollToTop: PropTypes.func,
 | 
				
			||||||
  onScroll: PropTypes.func,
 | 
					  onScroll: PropTypes.func,
 | 
				
			||||||
  trackScroll: PropTypes.bool,
 | 
					  shouldUpdateScroll: PropTypes.func,
 | 
				
			||||||
  isLoading: PropTypes.bool,
 | 
					  isLoading: PropTypes.bool,
 | 
				
			||||||
  isUnread: PropTypes.bool,
 | 
					  isUnread: PropTypes.bool,
 | 
				
			||||||
  hasMore: PropTypes.bool,
 | 
					  hasMore: PropTypes.bool,
 | 
				
			||||||
 | 
				
			|||||||
@ -99,6 +99,125 @@ addLocaleData([
 | 
				
			|||||||
  ...id,
 | 
					  ...id,
 | 
				
			||||||
]);
 | 
					]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getTopWhenReplacing = (previous, { location }) => location && location.action === 'REPLACE' && [0, 0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const hiddenColumnContainerStyle = {
 | 
				
			||||||
 | 
					  position: 'absolute',
 | 
				
			||||||
 | 
					  left: '0',
 | 
				
			||||||
 | 
					  top:  '0',
 | 
				
			||||||
 | 
					  visibility: 'hidden'
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Container extends React.PureComponent {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(props) {
 | 
				
			||||||
 | 
					    super(props);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.state = {
 | 
				
			||||||
 | 
					      renderedPersistents: [],
 | 
				
			||||||
 | 
					      unrenderedPersistents: [],
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  componentWillMount () {
 | 
				
			||||||
 | 
					    this.unlistenHistory = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.setState(() => {
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        mountImpersistent: false,
 | 
				
			||||||
 | 
					        renderedPersistents: [],
 | 
				
			||||||
 | 
					        unrenderedPersistents: [
 | 
				
			||||||
 | 
					          {pathname: '/timelines/home', component: HomeTimeline},
 | 
				
			||||||
 | 
					          {pathname: '/timelines/public', component: PublicTimeline},
 | 
				
			||||||
 | 
					          {pathname: '/timelines/public/local', component: CommunityTimeline},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          {pathname: '/notifications', component: Notifications},
 | 
				
			||||||
 | 
					          {pathname: '/favourites', component: FavouritedStatuses}
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    }, () => {
 | 
				
			||||||
 | 
					      if (this.unlistenHistory) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      this.unlistenHistory = browserHistory.listen(location => {
 | 
				
			||||||
 | 
					        const pathname = location.pathname.replace(/\/$/, '').toLowerCase();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.setState(oldState => {
 | 
				
			||||||
 | 
					          let persistentMatched = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          const newState = {
 | 
				
			||||||
 | 
					            renderedPersistents: oldState.renderedPersistents.map(persistent => {
 | 
				
			||||||
 | 
					              const givenMatched = persistent.pathname === pathname;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              if (givenMatched) {
 | 
				
			||||||
 | 
					                persistentMatched = true;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              return {
 | 
				
			||||||
 | 
					                hidden: !givenMatched,
 | 
				
			||||||
 | 
					                pathname: persistent.pathname,
 | 
				
			||||||
 | 
					                component: persistent.component
 | 
				
			||||||
 | 
					              };
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (!persistentMatched) {
 | 
				
			||||||
 | 
					            newState.unrenderedPersistents = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            oldState.unrenderedPersistents.forEach(persistent => {
 | 
				
			||||||
 | 
					              if (persistent.pathname === pathname) {
 | 
				
			||||||
 | 
					                persistentMatched = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                newState.renderedPersistents.push({
 | 
				
			||||||
 | 
					                  hidden: false,
 | 
				
			||||||
 | 
					                  pathname: persistent.pathname,
 | 
				
			||||||
 | 
					                  component: persistent.component
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					              } else {
 | 
				
			||||||
 | 
					                newState.unrenderedPersistents.push(persistent);
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          newState.mountImpersistent = !persistentMatched;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          return newState;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  componentWillUnmount () {
 | 
				
			||||||
 | 
					    if (this.unlistenHistory) {
 | 
				
			||||||
 | 
					      this.unlistenHistory();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.unlistenHistory = "done";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  render () {
 | 
				
			||||||
 | 
					    // Hide some components rather than unmounting them to allow to show again
 | 
				
			||||||
 | 
					    // quickly and keep the view state such as the scrolled offset.
 | 
				
			||||||
 | 
					    const persistentsView = this.state.renderedPersistents.map((persistent) =>
 | 
				
			||||||
 | 
					      <div aria-hidden={persistent.hidden} key={persistent.pathname} className='mastodon-column-container' style={persistent.hidden ? hiddenColumnContainerStyle : null}>
 | 
				
			||||||
 | 
					        <persistent.component shouldUpdateScroll={persistent.hidden ? Function.prototype : getTopWhenReplacing} />
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <UI>
 | 
				
			||||||
 | 
					        {this.state.mountImpersistent && this.props.children}
 | 
				
			||||||
 | 
					        {persistentsView}
 | 
				
			||||||
 | 
					      </UI>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Container.propTypes = {
 | 
				
			||||||
 | 
					  children: PropTypes.node,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Mastodon extends React.Component {
 | 
					class Mastodon extends React.Component {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  componentDidMount() {
 | 
					  componentDidMount() {
 | 
				
			||||||
@ -160,18 +279,12 @@ class Mastodon extends React.Component {
 | 
				
			|||||||
      <IntlProvider locale={locale} messages={getMessagesForLocale(locale)}>
 | 
					      <IntlProvider locale={locale} messages={getMessagesForLocale(locale)}>
 | 
				
			||||||
        <Provider store={store}>
 | 
					        <Provider store={store}>
 | 
				
			||||||
          <Router history={browserHistory} render={applyRouterMiddleware(useScroll())}>
 | 
					          <Router history={browserHistory} render={applyRouterMiddleware(useScroll())}>
 | 
				
			||||||
            <Route path='/' component={UI}>
 | 
					            <Route path='/' component={Container}>
 | 
				
			||||||
              <IndexRedirect to="/getting-started" />
 | 
					              <IndexRedirect to="/getting-started" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              <Route path='getting-started' component={GettingStarted} />
 | 
					              <Route path='getting-started' component={GettingStarted} />
 | 
				
			||||||
              <Route path='timelines/home' component={HomeTimeline} />
 | 
					 | 
				
			||||||
              <Route path='timelines/public' component={PublicTimeline} />
 | 
					 | 
				
			||||||
              <Route path='timelines/public/local' component={CommunityTimeline} />
 | 
					 | 
				
			||||||
              <Route path='timelines/tag/:id' component={HashtagTimeline} />
 | 
					              <Route path='timelines/tag/:id' component={HashtagTimeline} />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              <Route path='notifications' component={Notifications} />
 | 
					 | 
				
			||||||
              <Route path='favourites' component={FavouritedStatuses} />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              <Route path='statuses/new' component={Compose} />
 | 
					              <Route path='statuses/new' component={Compose} />
 | 
				
			||||||
              <Route path='statuses/:statusId' component={Status} />
 | 
					              <Route path='statuses/:statusId' component={Status} />
 | 
				
			||||||
              <Route path='statuses/:statusId/reblogs' component={Reblogs} />
 | 
					              <Route path='statuses/:statusId/reblogs' component={Reblogs} />
 | 
				
			||||||
 | 
				
			|||||||
@ -62,6 +62,7 @@ class AccountTimeline extends React.PureComponent {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        <StatusList
 | 
					        <StatusList
 | 
				
			||||||
          prepend={<HeaderContainer accountId={this.props.params.accountId} />}
 | 
					          prepend={<HeaderContainer accountId={this.props.params.accountId} />}
 | 
				
			||||||
 | 
					          scrollKey='account_timeline'
 | 
				
			||||||
          statusIds={statusIds}
 | 
					          statusIds={statusIds}
 | 
				
			||||||
          isLoading={isLoading}
 | 
					          isLoading={isLoading}
 | 
				
			||||||
          hasMore={hasMore}
 | 
					          hasMore={hasMore}
 | 
				
			||||||
 | 
				
			|||||||
@ -77,7 +77,7 @@ class CommunityTimeline extends React.PureComponent {
 | 
				
			|||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <Column icon='users' active={hasUnread} heading={intl.formatMessage(messages.title)}>
 | 
					      <Column icon='users' active={hasUnread} heading={intl.formatMessage(messages.title)}>
 | 
				
			||||||
        <ColumnBackButtonSlim />
 | 
					        <ColumnBackButtonSlim />
 | 
				
			||||||
        <StatusListContainer type='community' emptyMessage={<FormattedMessage id='empty_column.community' defaultMessage='The local timeline is empty. Write something publicly to get the ball rolling!' />} />
 | 
					        <StatusListContainer {...this.props} scrollKey='community_timeline' type='community' emptyMessage={<FormattedMessage id='empty_column.community' defaultMessage='The local timeline is empty. Write something publicly to get the ball rolling!' />} />
 | 
				
			||||||
      </Column>
 | 
					      </Column>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -47,7 +47,7 @@ class Favourites extends React.PureComponent {
 | 
				
			|||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <Column icon='star' heading={intl.formatMessage(messages.heading)}>
 | 
					      <Column icon='star' heading={intl.formatMessage(messages.heading)}>
 | 
				
			||||||
        <ColumnBackButtonSlim />
 | 
					        <ColumnBackButtonSlim />
 | 
				
			||||||
        <StatusList statusIds={statusIds} me={me} onScrollToBottom={this.handleScrollToBottom} />
 | 
					        <StatusList {...this.props} onScrollToBottom={this.handleScrollToBottom} />
 | 
				
			||||||
      </Column>
 | 
					      </Column>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -71,7 +71,7 @@ class HashtagTimeline extends React.PureComponent {
 | 
				
			|||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <Column icon='hashtag' active={hasUnread} heading={id}>
 | 
					      <Column icon='hashtag' active={hasUnread} heading={id}>
 | 
				
			||||||
        <ColumnBackButtonSlim />
 | 
					        <ColumnBackButtonSlim />
 | 
				
			||||||
        <StatusListContainer type='tag' id={id} emptyMessage={<FormattedMessage id='empty_column.hashtag' defaultMessage='There is nothing in this hashtag yet.' />} />
 | 
					        <StatusListContainer scrollKey='hashtag_timeline' type='tag' id={id} emptyMessage={<FormattedMessage id='empty_column.hashtag' defaultMessage='There is nothing in this hashtag yet.' />} />
 | 
				
			||||||
      </Column>
 | 
					      </Column>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,7 @@ class HomeTimeline extends React.PureComponent {
 | 
				
			|||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <Column icon='home' active={hasUnread} heading={intl.formatMessage(messages.title)}>
 | 
					      <Column icon='home' active={hasUnread} heading={intl.formatMessage(messages.title)}>
 | 
				
			||||||
        <ColumnSettingsContainer />
 | 
					        <ColumnSettingsContainer />
 | 
				
			||||||
        <StatusListContainer {...this.props} type='home' emptyMessage={<FormattedMessage id='empty_column.home' defaultMessage="You aren't following anyone yet. Visit {public} or use search to get started and meet other users." values={{ public: <Link to='/timelines/public'><FormattedMessage id='empty_column.home.public_timeline' defaultMessage='the public timeline' /></Link> }} />} />
 | 
					        <StatusListContainer {...this.props} scrollKey='home_timeline' type='home' emptyMessage={<FormattedMessage id='empty_column.home' defaultMessage="You aren't following anyone yet. Visit {public} or use search to get started and meet other users." values={{ public: <Link to='/timelines/public'><FormattedMessage id='empty_column.home.public_timeline' defaultMessage='the public timeline' /></Link> }} />} />
 | 
				
			||||||
      </Column>
 | 
					      </Column>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -80,7 +80,7 @@ class Notifications extends React.PureComponent {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  render () {
 | 
					  render () {
 | 
				
			||||||
    const { intl, notifications, trackScroll, isLoading, isUnread } = this.props;
 | 
					    const { intl, notifications, shouldUpdateScroll, isLoading, isUnread } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let loadMore       = '';
 | 
					    let loadMore       = '';
 | 
				
			||||||
    let scrollableArea = '';
 | 
					    let scrollableArea = '';
 | 
				
			||||||
@ -113,25 +113,15 @@ class Notifications extends React.PureComponent {
 | 
				
			|||||||
      );
 | 
					      );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (trackScroll) {
 | 
					    return (
 | 
				
			||||||
      return (
 | 
					      <Column icon='bell' active={isUnread} heading={intl.formatMessage(messages.title)}>
 | 
				
			||||||
        <Column icon='bell' active={isUnread} heading={intl.formatMessage(messages.title)}>
 | 
					        <ColumnSettingsContainer />
 | 
				
			||||||
          <ColumnSettingsContainer />
 | 
					        <ClearColumnButton onClick={this.handleClear} />
 | 
				
			||||||
          <ClearColumnButton onClick={this.handleClear} />
 | 
					        <ScrollContainer scrollKey='notifications' shouldUpdateScroll={shouldUpdateScroll}>
 | 
				
			||||||
          <ScrollContainer scrollKey='notifications'>
 | 
					 | 
				
			||||||
            {scrollableArea}
 | 
					 | 
				
			||||||
          </ScrollContainer>
 | 
					 | 
				
			||||||
        </Column>
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      return (
 | 
					 | 
				
			||||||
        <Column icon='bell' active={isUnread} heading={intl.formatMessage(messages.title)}>
 | 
					 | 
				
			||||||
          <ColumnSettingsContainer />
 | 
					 | 
				
			||||||
          <ClearColumnButton onClick={this.handleClear} />
 | 
					 | 
				
			||||||
          {scrollableArea}
 | 
					          {scrollableArea}
 | 
				
			||||||
        </Column>
 | 
					        </ScrollContainer>
 | 
				
			||||||
      );
 | 
					      </Column>
 | 
				
			||||||
    }
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -139,7 +129,7 @@ class Notifications extends React.PureComponent {
 | 
				
			|||||||
Notifications.propTypes = {
 | 
					Notifications.propTypes = {
 | 
				
			||||||
  notifications: ImmutablePropTypes.list.isRequired,
 | 
					  notifications: ImmutablePropTypes.list.isRequired,
 | 
				
			||||||
  dispatch: PropTypes.func.isRequired,
 | 
					  dispatch: PropTypes.func.isRequired,
 | 
				
			||||||
  trackScroll: PropTypes.bool,
 | 
					  shouldUpdateScroll: PropTypes.func,
 | 
				
			||||||
  intl: PropTypes.object.isRequired,
 | 
					  intl: PropTypes.object.isRequired,
 | 
				
			||||||
  isLoading: PropTypes.bool,
 | 
					  isLoading: PropTypes.bool,
 | 
				
			||||||
  isUnread: PropTypes.bool
 | 
					  isUnread: PropTypes.bool
 | 
				
			||||||
 | 
				
			|||||||
@ -77,7 +77,7 @@ class PublicTimeline extends React.PureComponent {
 | 
				
			|||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <Column icon='globe' active={hasUnread} heading={intl.formatMessage(messages.title)}>
 | 
					      <Column icon='globe' active={hasUnread} heading={intl.formatMessage(messages.title)}>
 | 
				
			||||||
        <ColumnBackButtonSlim />
 | 
					        <ColumnBackButtonSlim />
 | 
				
			||||||
        <StatusListContainer type='public' emptyMessage={<FormattedMessage id='empty_column.public' defaultMessage='There is nothing here! Write something publicly, or manually follow users from other instances to fill it up' />} />
 | 
					        <StatusListContainer {...this.props} type='public' scrollKey='public_timeline' emptyMessage={<FormattedMessage id='empty_column.public' defaultMessage='There is nothing here! Write something publicly, or manually follow users from other instances to fill it up' />} />
 | 
				
			||||||
      </Column>
 | 
					      </Column>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -40,6 +40,8 @@ const makeMapStateToProps = () => {
 | 
				
			|||||||
  const getStatusIds = makeGetStatusIds();
 | 
					  const getStatusIds = makeGetStatusIds();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const mapStateToProps = (state, props) => ({
 | 
					  const mapStateToProps = (state, props) => ({
 | 
				
			||||||
 | 
					    scrollKey: props.scrollKey,
 | 
				
			||||||
 | 
					    shouldUpdateScroll: props.shouldUpdateScroll,
 | 
				
			||||||
    statusIds: getStatusIds(state, props),
 | 
					    statusIds: getStatusIds(state, props),
 | 
				
			||||||
    isLoading: state.getIn(['timelines', props.type, 'isLoading'], true),
 | 
					    isLoading: state.getIn(['timelines', props.type, 'isLoading'], true),
 | 
				
			||||||
    isUnread: state.getIn(['timelines', props.type, 'unread']) > 0,
 | 
					    isUnread: state.getIn(['timelines', props.type, 'unread']) > 0,
 | 
				
			||||||
 | 
				
			|||||||
@ -127,9 +127,9 @@ class UI extends React.PureComponent {
 | 
				
			|||||||
      mountedColumns = (
 | 
					      mountedColumns = (
 | 
				
			||||||
        <ColumnsArea>
 | 
					        <ColumnsArea>
 | 
				
			||||||
          <Compose withHeader={true} />
 | 
					          <Compose withHeader={true} />
 | 
				
			||||||
          <HomeTimeline trackScroll={false} />
 | 
					          <HomeTimeline shouldUpdateScroll={() => false} />
 | 
				
			||||||
          <Notifications trackScroll={false} />
 | 
					          <Notifications shouldUpdateScroll={() => false} />
 | 
				
			||||||
          {children}
 | 
					          <div style={{display: 'flex', flex: '1 1 auto', position: 'relative'}}>{children}</div>
 | 
				
			||||||
        </ColumnsArea>
 | 
					        </ColumnsArea>
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -89,11 +89,11 @@
 | 
				
			|||||||
  border: none;
 | 
					  border: none;
 | 
				
			||||||
  background: transparent;
 | 
					  background: transparent;
 | 
				
			||||||
  cursor: pointer;
 | 
					  cursor: pointer;
 | 
				
			||||||
  transition: all 100ms ease-in;
 | 
					  transition: color 100ms ease-in;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &:hover, &:active, &:focus {
 | 
					  &:hover, &:active, &:focus {
 | 
				
			||||||
    color: lighten($color1, 33%);
 | 
					    color: lighten($color1, 33%);
 | 
				
			||||||
    transition: all 200ms ease-out;
 | 
					    transition: color 200ms ease-out;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &.disabled {
 | 
					  &.disabled {
 | 
				
			||||||
@ -152,11 +152,11 @@
 | 
				
			|||||||
  padding: 0 3px;
 | 
					  padding: 0 3px;
 | 
				
			||||||
  line-height: 27px;
 | 
					  line-height: 27px;
 | 
				
			||||||
  outline: 0;
 | 
					  outline: 0;
 | 
				
			||||||
  transition: all 100ms ease-in;
 | 
					  transition: color 100ms ease-in;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &:hover, &:active, &:focus {
 | 
					  &:hover, &:active, &:focus {
 | 
				
			||||||
    color: lighten($color1, 26%);
 | 
					    color: lighten($color1, 26%);
 | 
				
			||||||
    transition: all 200ms ease-out;
 | 
					    transition: color 200ms ease-out;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &.disabled {
 | 
					  &.disabled {
 | 
				
			||||||
@ -1100,6 +1100,7 @@ a.status__content__spoiler-link {
 | 
				
			|||||||
  flex-direction: row;
 | 
					  flex-direction: row;
 | 
				
			||||||
  justify-content: flex-start;
 | 
					  justify-content: flex-start;
 | 
				
			||||||
  overflow-x: auto;
 | 
					  overflow-x: auto;
 | 
				
			||||||
 | 
					  position:   relative;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@media screen and (min-width: 360px) {
 | 
					@media screen and (min-width: 360px) {
 | 
				
			||||||
@ -1257,11 +1258,11 @@ a.status__content__spoiler-link {
 | 
				
			|||||||
  flex-direction: row;
 | 
					  flex-direction: row;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  a {
 | 
					  a {
 | 
				
			||||||
    transition: all 100ms ease-in;
 | 
					    transition: background 100ms ease-in;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    &:hover {
 | 
					    &:hover {
 | 
				
			||||||
      background: lighten($color1, 3%);
 | 
					      background: lighten($color1, 3%);
 | 
				
			||||||
      transition: all 200ms ease-out;
 | 
					      transition: background 200ms ease-out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,16 @@
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.mastodon-column-container {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  height: 100%;
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 707568 - height 100% doesn't work on child of a flex item - chromium - Monorail
 | 
				
			||||||
 | 
					  // https://bugs.chromium.org/p/chromium/issues/detail?id=707568
 | 
				
			||||||
 | 
					  flex: 1 1 auto;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.logo-container {
 | 
					.logo-container {
 | 
				
			||||||
  max-width: 400px;
 | 
					  max-width: 400px;
 | 
				
			||||||
  margin: 100px auto;
 | 
					  margin: 100px auto;
 | 
				
			||||||
@ -40,7 +50,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      img {
 | 
					      img {
 | 
				
			||||||
        opacity: 0.8;
 | 
					        opacity: 0.8;
 | 
				
			||||||
        transition: all 0.8s ease;
 | 
					        transition: opacity 0.8s ease;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      &:hover {
 | 
					      &:hover {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user