aboutsummaryrefslogtreecommitdiff
path: root/vnext/src/App.js
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2018-07-15 09:13:10 +0300
committerGravatar Vitaly Takmazov2023-01-13 10:37:53 +0300
commit07f74dd46ecb18eac2047d4042919f1b092b682d (patch)
tree5eb5a8380aba388dec2b49878e89d9c672f6bfc4 /vnext/src/App.js
parentc3f0a502db2f7766badee30c9a7836aff3b7cd67 (diff)
Move App to its own file
Diffstat (limited to 'vnext/src/App.js')
-rw-r--r--vnext/src/App.js232
1 files changed, 232 insertions, 0 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