diff options
-rw-r--r-- | vnext/src/App.js | 232 | ||||
-rw-r--r-- | vnext/src/index.js | 231 |
2 files changed, 233 insertions, 230 deletions
diff --git a/vnext/src/App.js b/vnext/src/App.js new file mode 100644 index 00000000..14ae7d5e --- /dev/null +++ b/vnext/src/App.js @@ -0,0 +1,232 @@ +import React from 'react'; +import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom'; +import * as qs from 'query-string'; + +import Icon from './components/Icon'; +import { Discover, Discussions, Blog, Tag, Home } from './components/Feeds'; +import Settings from './components/Settings'; +import Contacts from './components/Contacts'; +import Chat from './components/Chat'; +import Post from './components/Post'; +import Thread from './components/Thread'; +import LoginButton from './components/LoginButton'; +import Footer from './components/Footer'; +import Avatar from './components/Avatar'; +import Header from './components/Header'; +import SearchBox from './components/SearchBox'; + +import { me } from './api'; + +export default class App extends React.Component { + constructor(props) { + super(props); + let params = qs.parse(window.location.search); + if (params.hash) { + localStorage.visitor = JSON.stringify({ uid: 0, hash: params.hash }); + window.history.replaceState({}, document.title, `${window.location.protocol}//${window.location.host}${window.location.pathname}`); + } + this.state = { + visitor: localStorage.visitor ? JSON.parse(localStorage.visitor) : { + uid: 0, + hash: params.hash || '' + } + }; + this.pm = React.createRef(); + this.thread = React.createRef(); + } + + initWS = () => { + const proto = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; + const params = { hash: this.state.visitor.hash }; + let url = `${proto}//api.juick.com/ws/?${qs.stringify(params)}`; + this.ws = new WebSocket(url); + this.ws.onopen = () => { + console.log('online'); + }; + this.ws.onclose = () => { + console.log('offline'); + this.ws = false; + setTimeout(function () { + this.initWS(); + }, 2000); + }; + this.ws.onmessage = (msg) => { + if (msg.data == ' ') { + this.ws.send(' '); + } else { + try { + var jsonMsg = JSON.parse(msg.data); + console.log('data: ' + msg.data); + // refresh server visitor state (unread counters) + me().then(visitor => { + this.setState({ + visitor: visitor + }); + }); + if (jsonMsg.service) { + return; + } + if (!jsonMsg.mid) { + this.pm.current.onMessage(jsonMsg); + } + if (jsonMsg.rid && this.thread.current) { + this.thread.current.onReply(jsonMsg); + } + } catch (err) { + console.log(err); + } + } + }; + setInterval(this.wsSendKeepAlive, 90000); + } + + wsSendKeepAlive = () => { + if (this.ws) { + this.ws.send(' '); + } + } + + componentDidMount() { + const { hash, uid } = this.state.visitor; + this.initWS(); + if (hash) { + me().then(visitor => this.auth(visitor)); + } + } + search = (searchString) => { + console.log(searchString); + } + render() { + const user = this.state.visitor; + return ( + <Router> + <React.Fragment> + <Header> + <div id="header_wrapper"> + {user.uid > 0 ? + <div id="ctitle"> + {user.uname ? <Avatar user={user} /> : <Icon name="ei-spinner" size="m" />} + </div> + : + <div id="logo"><Link to="/">Juick</Link></div> + } + <div id="search"> + <SearchBox onSearch={this.search} /> + </div> + <nav id="global"> + <ul> + {user.uid > 0 ? + <li> + <Link to={{ pathname: '/discussions' }}> + <Icon name="ei-comment" size="s" /><span>Discuss</span> + { + user.unreadCount && + <span className="badge">{user.unreadCount}</span> + } + </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> + {user.uid > 0 ? + <Link to={{ pathname: '/post' }}><Icon name="ei-pencil" size="s" />Post</Link> + : + <LoginButton title="Login" onAuth={this.auth} /> + } + </li> + </ul> + </nav> + </div> + </Header> + <div id="wrapper"> + <section id="content"> + <Switch> + <Route exact path="/" render={(props) => <Discover visitor={user} {...props} />} /> + <Route exact path="/home" render={(props) => <Home visitor={user} {...props} />} /> + <Route exact path="/discussions" render={(props) => + <Discussions 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" render={(props) => <Blog 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="column"> + { + user.uid > 0 && + <React.Fragment> + <ul> + <li> + <Link to="/home"> + <Icon name="ei-clock" size="s" />My feed + </Link> + </li> + <li> + <Link to="/pm"> + <Icon name="ei-envelope" size="s" />PM + </Link> + </li> + <li> + <Link to={`/${user.uname}/?show=recomm`} rel="nofollow"> + <Icon name="ei-heart" size="s" />Recommendations + </Link> + </li> + <li> + <Link to={`/${user.uname}/?media=1`} rel="nofollow"> + <Icon name="ei-camera" size="s" />Photos + </Link> + </li> + <li> + <Link to="/settings" rel="nofollow"> + <Icon name="ei-gear" size="s" />Settings + </Link> + </li> + </ul> + <hr /> + <form> + <p><input type="text" name="search" className="inp" placeholder="Search..." /></p> + </form> + <hr /> + <div id="ustats"> + <ul> + <li><Link to={`/${user.uname}/friends`}>I read: {user.statsIRead}</Link></li> + <li><Link to={`/${user.uname}/readers`}>My readers: {user.statsMyReaders}</Link></li> + { + user.statsMyBL && + <li><Link to={`/${user.uname}/bl`}>My blacklist: {user.statsMyBL}</Link></li> + } + <li>Messages: {user.statsMessages}</li> + <li>Comments: {user.statsReplies}</li> + </ul> + { + user.iread && + <div className="iread"> + { + user.iread.map(u => <Avatar user={u} key={u.uid} />) + } + </div> + } + </div> + </React.Fragment> + } + </aside> + </div> + <Footer /> + </React.Fragment> + </Router> + ); + } + auth = (visitor) => { + this.setState({ + visitor: visitor + }); + } +}
\ No newline at end of file diff --git a/vnext/src/index.js b/vnext/src/index.js index 6f8c1cc0..be14cfb8 100644 --- a/vnext/src/index.js +++ b/vnext/src/index.js @@ -1,236 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import { BrowserRouter as Router, Route, Link, Switch, Redirect } from 'react-router-dom'; -import * as qs from 'query-string'; -import Icon from './components/Icon'; -import { Discover, Discussions, Blog, Tag, Home } from './components/Feeds'; -import Settings from './components/Settings'; -import Contacts from './components/Contacts'; -import Chat from './components/Chat'; -import Post from './components/Post'; -import Thread from './components/Thread'; -import LoginButton from './components/LoginButton'; -import Footer from './components/Footer'; -import Avatar from './components/Avatar'; -import Header from './components/Header'; -import SearchBox from './components/SearchBox'; - -import { me } from './api'; - -class App extends React.Component { - constructor(props) { - super(props); - let params = qs.parse(window.location.search); - if (params.hash) { - localStorage.visitor = JSON.stringify({ uid: 0, hash: params.hash }); - window.history.replaceState({}, document.title, `${window.location.protocol}//${window.location.host}${window.location.pathname}`); - } - this.state = { - visitor: localStorage.visitor ? JSON.parse(localStorage.visitor) : { - uid: 0, - hash: params.hash || '' - } - }; - this.pm = React.createRef(); - this.thread = React.createRef(); - } - - initWS = () => { - const proto = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; - const params = { hash: this.state.visitor.hash }; - let url = `${proto}//api.juick.com/ws/?${qs.stringify(params)}`; - this.ws = new WebSocket(url); - this.ws.onopen = () => { - console.log('online'); - }; - this.ws.onclose = () => { - console.log('offline'); - this.ws = false; - setTimeout(function () { - this.initWS(); - }, 2000); - }; - this.ws.onmessage = (msg) => { - if (msg.data == ' ') { - this.ws.send(' '); - } else { - try { - var jsonMsg = JSON.parse(msg.data); - console.log('data: ' + msg.data); - // refresh server visitor state (unread counters) - me().then(visitor => { - this.setState({ - visitor: visitor - }); - }); - if (jsonMsg.service) { - return; - } - if (!jsonMsg.mid) { - this.pm.current.onMessage(jsonMsg); - } - if (jsonMsg.rid && this.thread.current) { - this.thread.current.onReply(jsonMsg); - } - } catch (err) { - console.log(err); - } - } - }; - setInterval(this.wsSendKeepAlive, 90000); - } - - wsSendKeepAlive = () => { - if (this.ws) { - this.ws.send(' '); - } - } - - componentDidMount() { - const { hash, uid } = this.state.visitor; - this.initWS(); - if (hash) { - me().then(visitor => this.auth(visitor)); - } - } - search = (searchString) => { - console.log(searchString); - } - render() { - const user = this.state.visitor; - return ( - <Router> - <React.Fragment> - <Header> - <div id="header_wrapper"> - {user.uid > 0 ? - <div id="ctitle"> - {user.uname ? <Avatar user={user} /> : <Icon name="ei-spinner" size="m" />} - </div> - : - <div id="logo"><Link to="/">Juick</Link></div> - } - <div id="search"> - <SearchBox onSearch={this.search} /> - </div> - <nav id="global"> - <ul> - {user.uid > 0 ? - <li> - <Link to={{ pathname: '/discussions' }}> - <Icon name="ei-comment" size="s" /><span>Discuss</span> - { - user.unreadCount && - <span className="badge">{user.unreadCount}</span> - } - </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> - {user.uid > 0 ? - <Link to={{ pathname: '/post' }}><Icon name="ei-pencil" size="s" />Post</Link> - : - <LoginButton title="Login" onAuth={this.auth} /> - } - </li> - </ul> - </nav> - </div> - </Header> - <div id="wrapper"> - <section id="content"> - <Switch> - <Route exact path="/" render={(props) => <Discover visitor={user} {...props} />} /> - <Route exact path="/home" render={(props) => <Home visitor={user} {...props} />} /> - <Route exact path="/discussions" render={(props) => - <Discussions 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" render={(props) => <Blog 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="column"> - { - user.uid > 0 && - <React.Fragment> - <ul> - <li> - <Link to="/home"> - <Icon name="ei-clock" size="s" />My feed - </Link> - </li> - <li> - <Link to="/pm"> - <Icon name="ei-envelope" size="s" />PM - </Link> - </li> - <li> - <Link to={`/${user.uname}/?show=recomm`} rel="nofollow"> - <Icon name="ei-heart" size="s" />Recommendations - </Link> - </li> - <li> - <Link to={`/${user.uname}/?media=1`} rel="nofollow"> - <Icon name="ei-camera" size="s" />Photos - </Link> - </li> - <li> - <Link to="/settings" rel="nofollow"> - <Icon name="ei-gear" size="s" />Settings - </Link> - </li> - </ul> - <hr /> - <form> - <p><input type="text" name="search" className="inp" placeholder="Search..." /></p> - </form> - <hr /> - <div id="ustats"> - <ul> - <li><Link to={`/${user.uname}/friends`}>I read: {user.statsIRead}</Link></li> - <li><Link to={`/${user.uname}/readers`}>My readers: {user.statsMyReaders}</Link></li> - { - user.statsMyBL && - <li><Link to={`/${user.uname}/bl`}>My blacklist: {user.statsMyBL}</Link></li> - } - <li>Messages: {user.statsMessages}</li> - <li>Comments: {user.statsReplies}</li> - </ul> - { - user.iread && - <div className="iread"> - { - user.iread.map(u => <Avatar user={u} key={u.uid} />) - } - </div> - } - </div> - </React.Fragment> - } - </aside> - </div> - <Footer /> - </React.Fragment> - </Router> - ); - } - auth = (visitor) => { - this.setState({ - visitor: visitor - }); - } -} +import App from './App'; let container = document.createElement('div'); ReactDOM.render(<App />, container); |