aboutsummaryrefslogtreecommitdiff
path: root/vnext/src
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2018-12-10 15:46:33 +0300
committerGravatar Vitaly Takmazov2023-01-13 10:37:54 +0300
commit05f1cd52732b1fc57e13ea41239fbc10299a0e01 (patch)
tree2a3c8d99cb7b7a76319def26cc9ef1bb5703b3b4 /vnext/src
parent231f880af5634885bfa1a494eccef92bbf72c214 (diff)
ReactDOM.createPortal
Diffstat (limited to 'vnext/src')
-rw-r--r--vnext/src/App.js97
-rw-r--r--vnext/src/components/Header.js16
-rw-r--r--vnext/src/index.js27
-rw-r--r--vnext/src/style/main.css5
-rw-r--r--vnext/src/views/index.html2
5 files changed, 61 insertions, 86 deletions
diff --git a/vnext/src/App.js b/vnext/src/App.js
index 0764281a..e59fdb40 100644
--- a/vnext/src/App.js
+++ b/vnext/src/App.js
@@ -20,6 +20,8 @@ import cookies from 'react-cookies';
import { me } from './api';
+const app = document.getElementById('app');
+
export default class App extends React.Component {
constructor(props) {
super(props);
@@ -91,16 +93,18 @@ export default class App extends React.Component {
toggleSidebar = () => {
let width = this.sidebar.current.style.width;
this.sidebar.current.style.width = width === '248px' ? '0' : '248px';
+ let leftMargin = this.state.appMarginLeft === 'inherit' ? '250px' : 'inherit';
this.setState({
- appMarginLeft: this.state.appMarginLeft === 'inherit' ? '250px' : 'inherit'
+ appMarginLeft: leftMargin
});
+ app.style.marginLeft = leftMargin;
}
render() {
const user = this.state.visitor;
return (
<Router>
<>
- <Header style={{ marginLeft: this.state.appMarginLeft }}>
+ <Header>
<div id="header_wrapper">
<NavigationIcon onToggle={this.toggleSidebar} />
<div id="logo" className="desktop"><Link to="/">Juick</Link></div>
@@ -138,56 +142,45 @@ export default class App extends React.Component {
</nav>
</div>
</Header>
- <div id="wrapper" style={{ marginLeft: this.state.appMarginLeft }}>
- <section id="content">
- <Switch>
- <Route exact path="/" render={(props) => <Discussions visitor={user} {...props} />} />
- <Route exact path="/home" render={(props) => <Home visitor={user} {...props} />} />
- <Route exact path="/discover" render={(props) =>
- <Discover visitor={user} {...props} />
- } />
- <Route exact path="/settings" render={(props) =>
- <Settings visitor={user} {...props} />
- } />
- <Route exact path="/post" render={(props) => <Post visitor={user} {...props} />} />
- <Route exact path="/pm" render={(props) => <Contacts visitor={user} {...props} />} />
- <Route exact path="/pm/:user" render={(props) => <Chat ref={this.pm} visitor={user} {...props} />} />
- <Route exact path="/:user/friends" render={(props) => <Friends visitor={user} {...props} />} />
- <Route exact path="/:user/readers" render={(props) => <Readers visitor={user} {...props} />} />
- <Route exact path="/:user" render={(props) => <Blog key={props.match.params.user} visitor={user} {...props} />} />
- <Route exact path="/tag/:tag" render={(props) => <Tag visitor={user} {...props} />} />
- <Route exact path="/:user/:mid" render={(props) => <Thread ref={this.thread} visitor={user} {...props} />} />
- </Switch>
- </section>
- <aside id="sidebar" ref={this.sidebar}>
- <Avatar user={user} />
- <Link to="/?show=my">
- <Icon name="ei-clock" size="s" />
- <span className="desktop">My feed</span>
- </Link>
- <Link to="/pm">
- <Icon name="ei-envelope" size="s" />
- <span className="desktop">Messages</span>
- </Link>
- <Link to="/?show=discuss">
- <Icon name="ei-bell" size="s" />
- <span className="desktop">Discussions</span>
- </Link>
- <Link to="/settings" rel="nofollow">
- <Icon name="ei-gear" size="s" />
- <span className="desktop">Settings</span>
- </Link>
- </aside>
- </div>
- <div id="footer" style={{ marginLeft: this.state.appMarginLeft }}>
- <div id="footer-right"> &middot;
- <a href="/help/contacts" rel="nofollow">Contacts</a> &middot;
- <a href="/help/tos" rel="nofollow">TOS</a>
- </div>
- <div id="footer-left">juick.com &copy; 2008-2018
- <br />
- </div>
- </div>
+ <section id="content">
+ <Switch>
+ <Route exact path="/" render={(props) => <Discussions visitor={user} {...props} />} />
+ <Route exact path="/home" render={(props) => <Home visitor={user} {...props} />} />
+ <Route exact path="/discover" render={(props) =>
+ <Discover visitor={user} {...props} />
+ } />
+ <Route exact path="/settings" render={(props) =>
+ <Settings visitor={user} {...props} />
+ } />
+ <Route exact path="/post" render={(props) => <Post visitor={user} {...props} />} />
+ <Route exact path="/pm" render={(props) => <Contacts visitor={user} {...props} />} />
+ <Route exact path="/pm/:user" render={(props) => <Chat ref={this.pm} visitor={user} {...props} />} />
+ <Route exact path="/:user/friends" render={(props) => <Friends visitor={user} {...props} />} />
+ <Route exact path="/:user/readers" render={(props) => <Readers visitor={user} {...props} />} />
+ <Route exact path="/:user" render={(props) => <Blog key={props.match.params.user} visitor={user} {...props} />} />
+ <Route exact path="/tag/:tag" render={(props) => <Tag visitor={user} {...props} />} />
+ <Route exact path="/:user/:mid" render={(props) => <Thread ref={this.thread} visitor={user} {...props} />} />
+ </Switch>
+ </section>
+ <aside id="sidebar" ref={this.sidebar}>
+ <Avatar user={user} />
+ <Link to="/?show=my">
+ <Icon name="ei-clock" size="s" />
+ <span className="desktop">My feed</span>
+ </Link>
+ <Link to="/pm">
+ <Icon name="ei-envelope" size="s" />
+ <span className="desktop">Messages</span>
+ </Link>
+ <Link to="/?show=discuss">
+ <Icon name="ei-bell" size="s" />
+ <span className="desktop">Discussions</span>
+ </Link>
+ <Link to="/settings" rel="nofollow">
+ <Icon name="ei-gear" size="s" />
+ <span className="desktop">Settings</span>
+ </Link>
+ </aside>
</>
</Router>
);
diff --git a/vnext/src/components/Header.js b/vnext/src/components/Header.js
index 91fa02fd..282724b8 100644
--- a/vnext/src/components/Header.js
+++ b/vnext/src/components/Header.js
@@ -1,8 +1,10 @@
import React from 'react';
+import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
const elClassHidden = 'header--hidden';
-const elClassBackground = 'header--background';
+
+const header = document.getElementById('header');
export default class Header extends React.Component {
constructor(props) {
@@ -12,21 +14,21 @@ export default class Header extends React.Component {
this.wScrollCurrent = 0;
this.wScrollBefore = 0;
this.wScrollDiff = 0;
- this.header = React.createRef();
}
componentDidMount() {
+ header.removeChild(document.getElementById('header_wrapper'));
window.addEventListener('scroll', () => (!window.requestAnimationFrame)
? this.throttle(250, this.updateHeader)
: window.requestAnimationFrame(this.updateHeader), false);
}
throttle(delay, fn) {
var last, deferTimer;
- return function () {
+ return function() {
var context = this, args = arguments, now = +new Date;
if (last && now < last + delay) {
clearTimeout(deferTimer);
deferTimer = setTimeout(
- function () {
+ function() {
last = now;
fn.apply(context, args);
},
@@ -38,7 +40,6 @@ export default class Header extends React.Component {
};
}
updateHeader = () => {
- const header = this.header.current;
this.dHeight = document.body.offsetHeight;
this.wHeight = window.innerHeight;
this.wScrollCurrent = window.pageYOffset;
@@ -47,17 +48,14 @@ export default class Header extends React.Component {
if (this.wScrollCurrent <= 0) {
// scrolled to the very top; element sticks to the top
header.classList.remove(elClassHidden);
- header.classList.remove(elClassBackground);
} else if (this.wScrollDiff > 0 && header.classList.contains(elClassHidden)) {
// scrolled up; element slides in
header.classList.remove(elClassHidden);
- header.classList.add(elClassBackground);
} else if (this.wScrollDiff < 0) {
// scrolled down
if (this.wScrollCurrent + this.wHeight >= this.dHeight && header.classList.contains(elClassHidden)) {
// scrolled to the very bottom; element slides in
header.classList.remove(elClassHidden);
- header.classList.add(elClassBackground);
} else {
// scrolled down; element slides out
header.classList.add(elClassHidden);
@@ -66,7 +64,7 @@ export default class Header extends React.Component {
this.wScrollBefore = this.wScrollCurrent;
}
render() {
- return (<header id="header" ref={this.header} style={this.props.style || {}}>{this.props.children}</header>);
+ return ReactDOM.createPortal(this.props.children, header);
}
}
diff --git a/vnext/src/index.js b/vnext/src/index.js
index c2d2b6b7..482591c9 100644
--- a/vnext/src/index.js
+++ b/vnext/src/index.js
@@ -3,28 +3,9 @@ import ReactDOM from 'react-dom';
function LoadingView(props) {
return (
- <>
- <div id="header">
- <div id="header_wrapper">
- <div id="logo">
- <a href="/">Juick</a>
- </div>
- <div id="search">
- <form>
- <input name="search" className="text" placeholder="Search..." />
- </form>
- </div>
- <nav id="global">
- <a href="/">Loading...</a>
- </nav>
- </div>
- </div>
- <div id="wrapper">
- <div id="content">
- <div className="lds-ripple"><div></div><div></div></div>
- </div>
- </div>
- </>
+ <div id="content">
+ <div className="lds-ripple"><div></div><div></div></div>
+ </div>
);
}
@@ -36,4 +17,4 @@ const JuickApp = () => (
</Suspense>
);
-ReactDOM.render(<JuickApp />, document.getElementById('app'));
+ReactDOM.render(<JuickApp />, document.getElementById('wrapper'));
diff --git a/vnext/src/style/main.css b/vnext/src/style/main.css
index 964890c2..67527c37 100644
--- a/vnext/src/style/main.css
+++ b/vnext/src/style/main.css
@@ -55,9 +55,12 @@ img, hr {
grid-area: header;
background: #fff;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.28);
- transition: margin-left 0.4s;
+ transition: transform 0.4s;
overflow-x: hidden;
}
+.header--hidden {
+ transform: translateY(-100%);
+}
#header_wrapper, .footer_container {
display: flex;
diff --git a/vnext/src/views/index.html b/vnext/src/views/index.html
index 792424e2..3e0ddf6a 100644
--- a/vnext/src/views/index.html
+++ b/vnext/src/views/index.html
@@ -35,7 +35,7 @@
<div id="header_wrapper">
<div id="logo"><a href="/">Juick</a></div>
<nav id="global">
- <a href="/">Loading..</a>
+ <a href="/">Loading...</a>
</nav>
</div>
</div>