diff options
author | Vitaly Takmazov | 2019-10-29 17:11:07 +0300 |
---|---|---|
committer | Vitaly Takmazov | 2023-01-13 10:37:55 +0300 |
commit | 522a1cdbaf0f478fb23a9f770b9caf732ea13803 (patch) | |
tree | 2baf7497f4c4717ee423c227e2ba24a22b44c27c /vnext/src/App.js | |
parent | 713566a435fea6c00cbd2e37d7c8c2a54ef2895d (diff) |
Hide header on scroll (mobile only)
Diffstat (limited to 'vnext/src/App.js')
-rw-r--r-- | vnext/src/App.js | 115 |
1 files changed, 53 insertions, 62 deletions
diff --git a/vnext/src/App.js b/vnext/src/App.js index f39875c1..011e5cbd 100644 --- a/vnext/src/App.js +++ b/vnext/src/App.js @@ -1,5 +1,6 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom'; +import { useScroll, useRafState } from 'react-use'; import qs from 'qs'; import svg4everybody from 'svg4everybody'; @@ -10,18 +11,23 @@ import { Friends, Readers } from './ui/Users'; import Settings from './ui/Settings'; import Contacts from './ui/Contacts'; import Chat from './ui/Chat'; +import Header from './ui/Header'; import Post from './ui/Post'; import Thread from './ui/Thread'; import Login from './ui/Login'; -import { UserLink } from './ui/UserInfo'; -import SearchBox from './ui/SearchBox'; import cookie from 'react-cookies'; import { me } from './api'; +const elClassHidden = 'header--hidden'; + +const elClassFull = 'content--full'; + export default function App() { + let contentRef = useRef(null); + useEffect(() => { svg4everybody(); }, []); @@ -49,6 +55,48 @@ export default function App() { }); }; + const [scrollState, setScrollState] = useRafState({ + hidden: false, + bottom: false, + prevScroll: 0 + }); + + let { x, y } = useScroll(contentRef); + + useEffect(() => { + let dHeight = contentRef.current.scrollHeight; + let wHeight = contentRef.current.clientHeight; + setScrollState((scrollState) => { + let wScrollDiff = scrollState.prevScroll - y; + let hidden = scrollState.hidden; + let bottom = scrollState.bottom; + if (y <= 0) { + // scrolled to the very top; element sticks to the top + hidden = false; + bottom = false; + } else if ((wScrollDiff > 0) && hidden) { + // scrolled up; element slides in + hidden = false; + bottom = false; + } else if (wScrollDiff < 0) { + // scrolled down + if ((y + wHeight) >= dHeight && hidden) { + // scrolled to the very bottom; element slides in + hidden = false; + bottom = true; + } else { + // scrolled down; element slides out + hidden = true; + bottom = false; + } + } + return { + hidden: hidden, + bottom: bottom, + prevScroll: y + }; + }); + }, [x, y, setScrollState]); const [hash, setHash] = useState(cookie.load('hash')); const [eventSource, setEventSource] = useState({}); @@ -111,66 +159,9 @@ export default function App() { return ( <Router> <> - <div id="header"> - <div id="header_wrapper"> - { - visitor.uid < 0 ? - <> - <div id="logo"><a href="/" /></div> - <nav id="global"> - <a href="/">Loading...</a> - </nav> - </> - : visitor.uid > 0 ? - <UserLink user={visitor} /> - : <div id="logo"> - <Link to="/">Juick</Link> - </div> - } - { - visitor.uid >= 0 && - <> - <div id="search" className="desktop"> - <SearchBox pathname="/discover" onSearch={search} /> - </div> - <nav id="global"> - {visitor.uid > 0 ? - <Link to={{ pathname: '/' }}> - <Icon name="ei-bell" size="s" /><span className="desktop">Discuss</span> - { - visitor.unreadCount && - <span className="badge">{visitor.unreadCount}</span> - } - </Link> - : - <Link to='/?media=1' rel="nofollow"> - <Icon name="ei-camera" size="s" /> - <span className="desktop">Photos</span> - </Link> - } - <Link to={{ pathname: '/discover' }} rel="nofollow"> - <Icon name="ei-search" size="s" /> - <span className="desktop">Discover</span> - </Link> - - {visitor.uid > 0 ? - <Link to={{ pathname: '/post' }}> - <Icon name="ei-pencil" size="s" /> - <span className="desktop">Post</span> - </Link> - : - <Link to={{ pathname: '/login', state: { retpath: window.location.pathname } }}> - <Icon name="ei-user" size="s" /> - <span className="desktop">Login</span> - </Link> - } - </nav> - </> - } - </div> - </div> + <Header visitor={visitor} className={scrollState.hidden ? elClassHidden : ''} /> <div id="wrapper"> - <section id="content"> + <section id="content" ref={contentRef} className={scrollState.hidden || scrollState.bottom ? elClassFull : ''}> <Switch> <Route exact path="/" render={(props) => <Discussions visitor={visitor} {...props} />} /> <Route exact path="/home" render={(props) => <Home visitor={visitor} {...props} />} /> |