Added new menu animations
This commit is contained in:
parent
bc514b1d5c
commit
7418e27994
5 changed files with 166 additions and 101 deletions
|
@ -122,33 +122,41 @@ function Page(props: Props) {
|
|||
>
|
||||
{getSideNavElem()}
|
||||
|
||||
<main
|
||||
id={'main-content'}
|
||||
className={classnames(MAIN_CLASS, className, {
|
||||
'main--full-width': fullWidthPage,
|
||||
'main--auth-page': authPage,
|
||||
'main--file-page': filePage,
|
||||
'main--settings-page': settingsPage,
|
||||
'main--markdown': isMarkdown,
|
||||
'main--theater-mode': isOnFilePage && videoTheaterMode && !livestream,
|
||||
'main--livestream': livestream && !chatDisabled,
|
||||
<div
|
||||
className={classnames({
|
||||
'sidebar--pusher': fullWidthPage,
|
||||
'sidebar--pusher--open': sidebarOpen && fullWidthPage,
|
||||
'sidebar--pusher--filepage': !fullWidthPage,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
<main
|
||||
id={'main-content'}
|
||||
className={classnames(MAIN_CLASS, className, {
|
||||
'main--full-width': fullWidthPage,
|
||||
'main--auth-page': authPage,
|
||||
'main--file-page': filePage,
|
||||
'main--settings-page': settingsPage,
|
||||
'main--markdown': isMarkdown,
|
||||
'main--theater-mode': isOnFilePage && videoTheaterMode && !livestream,
|
||||
'main--livestream': livestream && !chatDisabled,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
|
||||
{!isMobile && rightSide && <div className="main__right-side">{rightSide}</div>}
|
||||
</main>
|
||||
{!isMobile && rightSide && <div className="main__right-side">{rightSide}</div>}
|
||||
</main>
|
||||
{/* @if TARGET='web' */}
|
||||
{!noFooter && (
|
||||
<React.Suspense fallback={null}>
|
||||
<Footer />
|
||||
</React.Suspense>
|
||||
)}
|
||||
{/* @endif */}
|
||||
</div>
|
||||
{/* @if TARGET='app' */}
|
||||
<StatusBar />
|
||||
{/* @endif */}
|
||||
</div>
|
||||
{/* @if TARGET='web' */}
|
||||
{!noFooter && (
|
||||
<React.Suspense fallback={null}>
|
||||
<Footer />
|
||||
</React.Suspense>
|
||||
)}
|
||||
{/* @endif */}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import Icon from 'component/common/icon';
|
|||
import NotificationBubble from 'component/notificationBubble';
|
||||
import I18nMessage from 'component/i18nMessage';
|
||||
import ChannelThumbnail from 'component/channelThumbnail';
|
||||
import { useIsLargeScreen } from 'effects/use-screensize';
|
||||
import { useIsMobile, useIsLargeScreen } from 'effects/use-screensize';
|
||||
import { GetLinksData } from 'util/buildHomepage';
|
||||
import { DOMAIN, ENABLE_UI_NOTIFICATIONS, ENABLE_NO_SOURCE_CLAIMS, CHANNEL_STAKED_LEVEL_LIVESTREAM } from 'config';
|
||||
|
||||
|
@ -219,9 +219,33 @@ function SideNavigation(props: Props) {
|
|||
|
||||
const isPersonalized = !IS_WEB || isAuthenticated;
|
||||
const isAbsolute = isOnFilePage || isMediumScreen;
|
||||
const microNavigation = !sidebarOpen || isMediumScreen;
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const showSubscriptionSection = sidebarOpen && isPersonalized && subscriptions && subscriptions.length > 0;
|
||||
const menuCanCloseCompletey = livestreamEnabled || isOnFilePage || isMobile;
|
||||
const hideMenuFromView = menuCanCloseCompletey && !sidebarOpen;
|
||||
|
||||
const [canDisposeMenu, setCanDisposeMenu] = React.useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (hideMenuFromView) {
|
||||
const handler = setTimeout(() => {
|
||||
setCanDisposeMenu(true);
|
||||
}, 250);
|
||||
return () => {
|
||||
clearTimeout(handler);
|
||||
};
|
||||
} else {
|
||||
setCanDisposeMenu(false);
|
||||
}
|
||||
}, [hideMenuFromView]);
|
||||
|
||||
const shouldRenderLargeMenuPushorAbsolute = menuCanCloseCompletey || sidebarOpen;
|
||||
|
||||
const showMicroMenu = !sidebarOpen && !menuCanCloseCompletey;
|
||||
const showPushMenu = sidebarOpen && !menuCanCloseCompletey;
|
||||
|
||||
const showSubscriptionSection =
|
||||
shouldRenderLargeMenuPushorAbsolute && isPersonalized && subscriptions && subscriptions.length > 0;
|
||||
const showTagSection = sidebarOpen && isPersonalized && followedTags && followedTags.length;
|
||||
|
||||
let displayedSubscriptions = subscriptions;
|
||||
|
@ -388,25 +412,42 @@ function SideNavigation(props: Props) {
|
|||
return (
|
||||
<div
|
||||
className={classnames('navigation__wrapper', {
|
||||
'navigation__wrapper--micro': microNavigation && !isOnFilePage,
|
||||
'navigation__wrapper--micro': showMicroMenu,
|
||||
'navigation__wrapper--absolute': isAbsolute,
|
||||
})}
|
||||
>
|
||||
{!isOnFilePage && (
|
||||
<nav
|
||||
aria-label={'Sidebar'}
|
||||
className={classnames('navigation', {
|
||||
'navigation--micro': microNavigation,
|
||||
})}
|
||||
>
|
||||
<div>
|
||||
<ul className={classnames('navigation-links', { 'navigation-links--micro': !sidebarOpen })}>
|
||||
<nav
|
||||
aria-label={'Sidebar'}
|
||||
className={classnames('navigation', {
|
||||
'navigation--micro': showMicroMenu,
|
||||
'navigation--push': showPushMenu,
|
||||
'navigation-file-page-and-mobile': hideMenuFromView,
|
||||
})}
|
||||
>
|
||||
{(!canDisposeMenu || sidebarOpen) && (
|
||||
<div className="navigation-inner-container">
|
||||
<ul className="navigation-links--absolute mobile-only">
|
||||
{notificationsEnabled && getLink(NOTIFICATIONS)}
|
||||
{email && livestreamEnabled && getLink(GO_LIVE)}
|
||||
</ul>
|
||||
|
||||
<ul
|
||||
className={classnames('navigation-links', {
|
||||
'navigation-links--micro': showMicroMenu,
|
||||
'navigation-links--absolute': shouldRenderLargeMenuPushorAbsolute,
|
||||
})}
|
||||
>
|
||||
{getLink(HOME)}
|
||||
{getLink(RECENT_FROM_FOLLOWING)}
|
||||
{getLink(PLAYLISTS)}
|
||||
</ul>
|
||||
|
||||
<ul className={classnames('navigation-links', { 'navigation-links--micro': !sidebarOpen })}>
|
||||
<ul
|
||||
className={classnames('navigation-links', {
|
||||
'navigation-links--micro': showMicroMenu,
|
||||
'navigation-links--absolute': shouldRenderLargeMenuPushorAbsolute,
|
||||
})}
|
||||
>
|
||||
{EXTRA_SIDEBAR_LINKS && (
|
||||
<>
|
||||
{/* $FlowFixMe -- GetLinksData should fix it's data type */}
|
||||
|
@ -416,54 +457,24 @@ function SideNavigation(props: Props) {
|
|||
)}
|
||||
</ul>
|
||||
|
||||
<ul className="navigation-links--absolute mobile-only">
|
||||
{email && MOBILE_LINKS.map((linkProps) => getLink(linkProps))}
|
||||
{!email && UNAUTH_LINKS.map((linkProps) => getLink(linkProps))}
|
||||
</ul>
|
||||
|
||||
{getSubscriptionSection()}
|
||||
{getFollowedTagsSection()}
|
||||
{!isAuthenticated && sidebarOpen && unAuthNudge}
|
||||
</div>
|
||||
|
||||
{sidebarOpen && helpLinks}
|
||||
</nav>
|
||||
)}
|
||||
|
||||
{(isOnFilePage || isMediumScreen) && sidebarOpen && (
|
||||
<>
|
||||
<nav className="navigation--absolute">
|
||||
<div>
|
||||
<ul className="navigation-links--absolute mobile-only">
|
||||
{notificationsEnabled && getLink(NOTIFICATIONS)}
|
||||
{email && livestreamEnabled && getLink(GO_LIVE)}
|
||||
</ul>
|
||||
|
||||
<ul className="navigation-links--absolute">
|
||||
{getLink(HOME)}
|
||||
{getLink(RECENT_FROM_FOLLOWING)}
|
||||
{getLink(PLAYLISTS)}
|
||||
</ul>
|
||||
|
||||
<ul className="navigation-links--absolute">
|
||||
{EXTRA_SIDEBAR_LINKS && (
|
||||
<>
|
||||
{/* $FlowFixMe -- GetLinksData should fix it's data type */}
|
||||
{EXTRA_SIDEBAR_LINKS.map((linkProps) => getLink(linkProps))}
|
||||
{getLink(WILD_WEST)}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
|
||||
<ul className="navigation-links--absolute mobile-only">
|
||||
{email && MOBILE_LINKS.map((linkProps) => getLink(linkProps))}
|
||||
{!email && UNAUTH_LINKS.map((linkProps) => getLink(linkProps))}
|
||||
</ul>
|
||||
|
||||
{getSubscriptionSection()}
|
||||
{getFollowedTagsSection()}
|
||||
{!isAuthenticated && unAuthNudge}
|
||||
{helpLinks}
|
||||
</div>
|
||||
</nav>
|
||||
<div className="navigation__overlay" onClick={() => setSidebarOpen(false)} />
|
||||
</>
|
||||
)}
|
||||
)}
|
||||
{(!canDisposeMenu || sidebarOpen) && shouldRenderLargeMenuPushorAbsolute && helpLinks}
|
||||
</nav>
|
||||
<div
|
||||
className={classnames('navigation__overlay', {
|
||||
'navigation__overlay--active': isAbsolute && sidebarOpen,
|
||||
})}
|
||||
onClick={() => setSidebarOpen(false)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -47,19 +47,43 @@
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar--pusher {
|
||||
animation-timing-function: var(--resizing-animation-function);
|
||||
transition: transform var(--resizing-animation-timing);
|
||||
transform-origin: left;
|
||||
position: absolute;
|
||||
|
||||
@media (max-width: $breakpoint-small) {
|
||||
transform: translateX(0);
|
||||
width: calc(100% - var(--spacing-m));
|
||||
}
|
||||
|
||||
@media (min-width: $breakpoint-small) {
|
||||
transform: translateX(var(--side-nav-width--micro));
|
||||
width: calc(100% - ((var(--side-nav-width--micro))));
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar--pusher--filepage {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sidebar--pusher--open {
|
||||
@media (min-width: $breakpoint-medium) {
|
||||
transform: translateX(var(--side-nav-width));
|
||||
width: calc(100% - var(--side-nav-width));
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
position: relative;
|
||||
width: calc(100% - var(--side-nav-width) - var(--spacing-l));
|
||||
width: calc(100% - 2 * var(--spacing-l));
|
||||
max-width: var(--page-max-width);
|
||||
z-index: 0;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
|
||||
@media (max-width: $breakpoint-medium) and (min-width: $breakpoint-small) {
|
||||
margin: 0 var(--spacing-l);
|
||||
}
|
||||
|
||||
@media (max-width: $breakpoint-medium) {
|
||||
@media (max-width: $breakpoint-small) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
@ -254,12 +278,7 @@
|
|||
|
||||
.main--full-width {
|
||||
@extend .main;
|
||||
|
||||
@media (min-width: $breakpoint-large) {
|
||||
max-width: none;
|
||||
width: 100%;
|
||||
margin: 0 var(--spacing-l);
|
||||
}
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.main--auth-page {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
position: fixed;
|
||||
left: 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
top: var(--header-height);
|
||||
width: var(--side-nav-width);
|
||||
height: calc(100vh - var(--header-height));
|
||||
|
@ -30,6 +31,13 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
animation-timing-function: var(--resizing-animation-function);
|
||||
transition: transform var(--resizing-animation-timing);
|
||||
z-index: 4;
|
||||
background-color: var(--color-card-background);
|
||||
transform: translateX(0);
|
||||
transform-origin: left;
|
||||
|
||||
@media (min-width: $breakpoint-small) {
|
||||
overflow-y: hidden;
|
||||
justify-content: space-between;
|
||||
|
@ -45,25 +53,25 @@
|
|||
}
|
||||
}
|
||||
|
||||
.navigation--push-back {
|
||||
transform: translateX(calc(-1 * (var(--side-nav-width) - var(--side-nav-width--micro))));
|
||||
}
|
||||
|
||||
.navigation--push {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.navigation--mac {
|
||||
top: calc(var(--header-height) + var(--mac-titlebar-height));
|
||||
}
|
||||
|
||||
.navigation--absolute {
|
||||
@extend .navigation;
|
||||
z-index: 4;
|
||||
width: var(--side-nav-width);
|
||||
background-color: var(--color-card-background);
|
||||
box-shadow: var(--card-box-shadow);
|
||||
|
||||
.navigation-link {
|
||||
padding-left: var(--spacing-m);
|
||||
}
|
||||
.navigation-file-page-and-mobile {
|
||||
transform: translateX(calc(-1 * var(--side-nav-width)));
|
||||
}
|
||||
|
||||
.navigation--micro {
|
||||
@extend .navigation;
|
||||
width: var(--side-nav-width--micro);
|
||||
transform: translateX(calc(-1 * (var(--side-nav-width) - var(--side-nav-width--micro))));
|
||||
|
||||
@media (max-width: $breakpoint-small) {
|
||||
display: none;
|
||||
|
@ -101,6 +109,7 @@
|
|||
}
|
||||
|
||||
.button__content {
|
||||
margin-left: auto;
|
||||
padding: var(--spacing-s);
|
||||
justify-content: flex-start;
|
||||
flex-direction: column;
|
||||
|
@ -188,6 +197,10 @@
|
|||
list-style: none;
|
||||
}
|
||||
|
||||
.navigation-inner-container {
|
||||
width: var(--side-nav-width);
|
||||
}
|
||||
|
||||
.navigation-links--micro {
|
||||
.icon {
|
||||
height: 1.5rem;
|
||||
|
@ -271,12 +284,22 @@
|
|||
z-index: 3;
|
||||
left: 0;
|
||||
top: var(--header-height);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
animation-timing-function: var(--resizing-animation-function);
|
||||
transition: visibility var(--resizing-animation-timing), opacity var(--resizing-animation-timing);
|
||||
|
||||
&.navigation__overlay--mac {
|
||||
top: calc(var(--header-height) + var(--mac-titlebar-height));
|
||||
}
|
||||
}
|
||||
|
||||
.navigation__overlay--active {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
animation: fadeIn var(--resizing-animation-timing) var(--resizing-animation-function);
|
||||
}
|
||||
|
||||
.navigation__auth-nudge {
|
||||
@extend .card;
|
||||
margin: var(--spacing-s);
|
||||
|
|
|
@ -100,6 +100,10 @@ $breakpoint-large: 1600px;
|
|||
--tag-height: 1.5rem;
|
||||
|
||||
--livestream-comments-width: 30rem;
|
||||
|
||||
// Animations
|
||||
--resizing-animation-function: ease-in;
|
||||
--resizing-animation-timing: 180ms;
|
||||
}
|
||||
|
||||
@media (max-width: $breakpoint-small) {
|
||||
|
|
Loading…
Reference in a new issue