aboutsummaryrefslogtreecommitdiff
path: root/vnext/src/App.js
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2019-10-29 17:11:07 +0300
committerGravatar Vitaly Takmazov2023-01-13 10:37:55 +0300
commit522a1cdbaf0f478fb23a9f770b9caf732ea13803 (patch)
tree2baf7497f4c4717ee423c227e2ba24a22b44c27c /vnext/src/App.js
parent713566a435fea6c00cbd2e37d7c8c2a54ef2895d (diff)
Hide header on scroll (mobile only)
Diffstat (limited to 'vnext/src/App.js')
-rw-r--r--vnext/src/App.js115
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} />} />