diff options
Diffstat (limited to 'vnext/src/index.js')
-rw-r--r-- | vnext/src/index.js | 156 |
1 files changed, 112 insertions, 44 deletions
diff --git a/vnext/src/index.js b/vnext/src/index.js index 9317c8b6..bf1d78ac 100644 --- a/vnext/src/index.js +++ b/vnext/src/index.js @@ -8,64 +8,127 @@ import Thread from './components/Thread'; import LoginButton from './components/LoginButton'; import Footer from './components/Footer'; +const elClassHidden = 'header--hidden' +const elClassBackground = 'header--background'; + class App extends React.Component { constructor(props) { super(props); this.auth = this.auth.bind(this); this.state = { - visitor: { uid: 0 } + visitor: { uid: 0 }, + headerClassName: '' }; + this.dHeight = 0; + this.wHeight = 0; + this.wScrollCurrent = 0; + this.wScrollBefore = 0; + this.wScrollDiff = 0; + + window.addEventListener('scroll', this.throttle(500, () => { + this.dHeight = document.body.offsetHeight; + this.wHeight = window.innerHeight; + this.wScrollCurrent = window.pageYOffset; + this.wScrollDiff = this.wScrollBefore - this.wScrollCurrent; + + if (this.wScrollCurrent <= 0) { + // scrolled to the very top; element sticks to the top + this.setState({ + headerClassName: '' + }) + } else if (this.wScrollDiff > 0 && this.state.headerClassName.indexOf(elClassHidden) >=0) { + // scrolled up; element slides in + this.setState({ + headerClassName: elClassBackground + }) + } else if (this.wScrollDiff < 0) { + // scrolled down + if (this.wScrollCurrent + this.wHeight >= this.dHeight && this.state.headerClassName.indexOf(elClassHidden) >=0) { + // scrolled to the very bottom; element slides in + this.setState({ + headerClassName: elClassBackground + }) + } else { + // scrolled down; element slides out + this.setState({ + headerClassName: [elClassHidden, elClassBackground].join(' ') + }) + } + } + this.wScrollBefore = this.wScrollCurrent; + })); this.auth(window.localStorage.hash || '') } + throttle(delay, fn) { + var last, deferTimer; + return function () { + var context = this, args = arguments, now = +new Date; + if (last && now < last + delay) { + clearTimeout(deferTimer); + deferTimer = setTimeout( + function () { + last = now; + fn.apply(context, args); + }, + delay); + } else { + last = now; + fn.apply(context, args); + } + }; + }; render() { return ( - <React.Fragment> - <Router> - <div className="wrapper"> - <header> - <div id="header_wrapper"> - {this.state.visitor.uid > 0 ? - <div id="ctitle"> - <a href={`/${this.state.visitor.uname}`}> - <img src={`//i.juick.com/a/${this.state.visitor.uid}.png`} alt="" />{this.state.visitor.uname} - </a> - </div> - : - <div id="logo"><Link to="/">Juick</Link></div> - } - <div id="search"> - <form action="/"> - <input name="search" className="text" - placeholder="Search..." /> - </form> + <Router> + <React.Fragment> + <header className={this.state.headerClassName}> + <div id="header_wrapper"> + {this.state.visitor.uid > 0 ? + <div id="ctitle"> + <a href={`/${this.state.visitor.uname}`}> + <img src={`//i.juick.com/a/${this.state.visitor.uid}.png`} alt="" />{this.state.visitor.uname} + </a> </div> - <nav id="global"> - <ul> + : + <div id="logo"><Link to="/">Juick</Link></div> + } + <div id="search"> + <form action="/"> + <input name="search" className="text" + placeholder="Search..." /> + </form> + </div> + <nav id="global"> + <ul> + {this.state.visitor.uid > 0 ? + <li><Link to={{ pathname: '/discussions' }}><Icon name="ei-comment" size="s" />Discuss</Link></li> + : + <li><Link to='/?media=1' rel="nofollow"><Icon name="ei-camera" size="s" />Photos</Link></li> + } + <li><Link to={{ pathname: '/' }} rel="nofollow"><Icon name="ei-search" size="s" />Discover</Link></li> + <li> {this.state.visitor.uid > 0 ? - <li><Link to={{ pathname: '/discussions' }}><Icon name="ei-comment" size="s" />Discuss</Link></li> + <Link to={{ pathname: '/post' }}><Icon name="ei-pencil" size="s" />Post</Link> : - <li><Link to='/?media=1' rel="nofollow"><Icon name="ei-camera" size="s" />Photos</Link></li> + <LoginButton title="Login" onAuth={this.auth.bind(this)} /> } - <li><Link to={{ pathname: '/' }} rel="nofollow"><Icon name="ei-search" size="s" />Discover</Link></li> - <li> - {this.state.visitor.uid > 0 ? - <Link to={{ pathname: '/post' }}><Icon name="ei-pencil" size="s" />Post</Link> - : - <LoginButton title="Login" onAuth={this.auth.bind(this)} /> - } - </li> - </ul> - </nav> - </div> - </header> - <Route exact path="/" render={(props) => <Discover visitor={this.state.visitor} {...props} />} /> - <Route exact path="/discussions" render={(props) => <Discussions visitor={this.state.visitor} {...props} />} /> - <Route exact path="/:user/:mid" render={(props) => <Thread visitor={this.state.visitor} {...props} />} /> - <Route exact path="/post" render={(props) => <Post visitor={this.state.visitor} {...props} />} /> + </li> + </ul> + </nav> + </div> + </header> + <div id="wrapper"> + <section id="content"> + <Route exact path="/" render={(props) => <Discover visitor={this.state.visitor} {...props} />} /> + <Route exact path="/discussions" render={(props) => <Discussions visitor={this.state.visitor} {...props} />} /> + <Route exact path="/:user/:mid" render={(props) => <Thread visitor={this.state.visitor} {...props} />} /> + <Route exact path="/post" render={(props) => <Post visitor={this.state.visitor} {...props} />} /> + </section> + <aside id="column"></aside> </div> - </Router> - <Footer /> - </React.Fragment> + <Footer /> + </React.Fragment> + </Router> ) } auth(data) { @@ -86,5 +149,10 @@ class App extends React.Component { } } +let container = document.createElement('div'); +ReactDOM.render(<App />, container); +let body = document.getElementById('wrapper').parentNode; +body.replaceChild(container.getElementsByTagName('header')[0], body.querySelector('#header')); +body.replaceChild(container.querySelector('#wrapper'), body.querySelector('#wrapper')); +body.replaceChild(container.querySelector('#footer'), body.querySelector('#footer')); -ReactDOM.render(<App />, document.getElementById('wrapper')); |