From b1da9dc4552760efdaf42e0f2cf87bb4d67be70a Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 15 Oct 2021 21:55:11 -0500 Subject: [PATCH] Add scrolling SubNavigation to Home and Account timelines --- app/soapbox/components/sub_navigation.js | 34 +++++++++--- .../components/column_settings.js | 55 ++++++++++++------- .../features/account_timeline/index.js | 34 +++--------- app/soapbox/features/home_timeline/index.js | 13 ++++- app/styles/components/account-header.scss | 10 ++++ app/styles/components/columns.scss | 6 +- .../components/timeline-queue-header.scss | 2 +- app/styles/components/wtf-panel.scss | 2 +- app/styles/navigation.scss | 18 +++++- 9 files changed, 112 insertions(+), 62 deletions(-) diff --git a/app/soapbox/components/sub_navigation.js b/app/soapbox/components/sub_navigation.js index 33287befa..ef672035f 100644 --- a/app/soapbox/components/sub_navigation.js +++ b/app/soapbox/components/sub_navigation.js @@ -31,6 +31,8 @@ class SubNavigation extends React.PureComponent { message: PropTypes.string, settings: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), onOpenSettings: PropTypes.func.isRequired, + className: PropTypes.string, + showAfter: PropTypes.number, } static contextTypes = { @@ -38,7 +40,8 @@ class SubNavigation extends React.PureComponent { } state = { - scrolled: false, + sticking: false, + visible: typeof this.props.showAfter !== 'number', } handleBackClick = () => { @@ -71,16 +74,33 @@ class SubNavigation extends React.PureComponent { window.removeEventListener('scroll', this.handleScroll); } - handleScroll = throttle(() => { + updateSticking = () => { if (this.node) { const { top } = this.node.getBoundingClientRect(); if (top <= 50) { - this.setState({ scrolled: true }); + this.setState({ sticking: true }); } else { - this.setState({ scrolled: false }); + this.setState({ sticking: false }); } } + } + + updateVisibile = () => { + const { showAfter } = this.props; + + if (typeof showAfter === 'number') { + if (document.documentElement.scrollTop >= showAfter) { + this.setState({ visible: true }); + } else { + this.setState({ visible: false }); + } + } + } + + handleScroll = throttle(() => { + this.updateSticking(); + this.updateVisibile(); }, 150, { trailing: true }); handleOpenSettings = () => { @@ -92,11 +112,11 @@ class SubNavigation extends React.PureComponent { } render() { - const { intl, message, settings: Settings } = this.props; - const { scrolled } = this.state; + const { intl, message, settings: Settings, className, showAfter } = this.props; + const { sticking, visible } = this.state; return ( -
+
-
-
-
-
- {(!collapsed || animating) && } -
+ {showSuggestions ? ( {Component => } - ) : ( + ) : (<> + }} />} /> - )} + )} ); } diff --git a/app/styles/components/account-header.scss b/app/styles/components/account-header.scss index 401e3fcc5..fe4c09b99 100644 --- a/app/styles/components/account-header.scss +++ b/app/styles/components/account-header.scss @@ -335,3 +335,13 @@ } } } + +.account__sub-navigation { + display: none; + + @media (max-width: 897px) { + display: flex; + position: fixed; + margin: 0; + } +} diff --git a/app/styles/components/columns.scss b/app/styles/components/columns.scss index 61c3ab489..7ae141104 100644 --- a/app/styles/components/columns.scss +++ b/app/styles/components/columns.scss @@ -924,8 +924,8 @@ } // Make MaterialStatus flush against SubNavigation -.sub-navigation ~ .slist .item-list > article:first-child .material-status__status, -.sub-navigation ~ .material-status:not(.material-status + .material-status) .material-status__status { +.sub-navigation:not(.sub-navigation--hidden) ~ .slist .item-list > article:first-child .material-status__status, +.sub-navigation:not(.sub-navigation--hidden) ~ .material-status:not(.material-status + .material-status) .material-status__status { border-top-left-radius: 0; border-top-right-radius: 0; } @@ -940,7 +940,7 @@ } } - .sub-navigation ~ .slist .slist__append { + .sub-navigation:not(.sub-navigation--hidden) ~ .slist .slist__append { border-top-left-radius: 0; border-top-right-radius: 0; } diff --git a/app/styles/components/timeline-queue-header.scss b/app/styles/components/timeline-queue-header.scss index 93cf73d6f..da3c6b65e 100644 --- a/app/styles/components/timeline-queue-header.scss +++ b/app/styles/components/timeline-queue-header.scss @@ -15,7 +15,7 @@ padding: 0 10px; z-index: 500; - .sub-navigation ~ & { + .sub-navigation:not(.sub-navigation--hidden) ~ & { top: calc(60px + 41px); } diff --git a/app/styles/components/wtf-panel.scss b/app/styles/components/wtf-panel.scss index b76e7a6e4..367cab868 100644 --- a/app/styles/components/wtf-panel.scss +++ b/app/styles/components/wtf-panel.scss @@ -162,7 +162,7 @@ } } -.column .sub-navigation ~ .wtf-panel { +.column .sub-navigation:not(.sub-navigation--hidden) ~ .wtf-panel { border-top-left-radius: 0; border-top-right-radius: 0; } diff --git a/app/styles/navigation.scss b/app/styles/navigation.scss index 9a8a48a44..f097876cc 100644 --- a/app/styles/navigation.scss +++ b/app/styles/navigation.scss @@ -128,11 +128,22 @@ align-items: center; justify-content: center; z-index: 999; + transition: transform 0.2s, border-radius 0.2s; - &--scrolled { + &--sticking { border-radius: 0 !important; } + &--show-after { + transform: translateY(-41px) scaleY(0); + margin-top: -1041px; + margin-bottom: 1000px; + + &.sub-navigation--visible { + transform: translateY(0) scaleY(1); + } + } + &__content { width: 100%; height: 100%; @@ -170,6 +181,7 @@ display: flex; align-items: center; justify-content: center; + margin-left: auto; .svg-icon { width: 20px; @@ -182,3 +194,7 @@ border-top-right-radius: 10px; } } + +.home-timeline .sub-navigation__back { + display: none; +}