aboutsummaryrefslogtreecommitdiff
path: root/vnext/src/App.js
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2019-04-08 15:42:24 +0300
committerGravatar Vitaly Takmazov2023-01-13 10:37:54 +0300
commitfccc23c05712b0b54e77daefd4b74855e52f08b6 (patch)
treee42ce2dc6595efb036b809f4a730160bbf3ec8d5 /vnext/src/App.js
parentbbfb81c2bc8d6afba550299e7138eeb2c58956d3 (diff)
App, Chat, Thread using hooks
Diffstat (limited to 'vnext/src/App.js')
-rw-r--r--vnext/src/App.js282
1 files changed, 126 insertions, 156 deletions
diff --git a/vnext/src/App.js b/vnext/src/App.js
index 7978abe5..6fcf3d9c 100644
--- a/vnext/src/App.js
+++ b/vnext/src/App.js
@@ -1,6 +1,6 @@
-import React from 'react';
+import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';
-import * as qs from 'qs';
+import qs from 'qs';
import Icon from './components/Icon';
import { Discover, Discussions, Blog, Tag, Home } from './components/Feeds';
@@ -11,179 +11,149 @@ import Chat from './components/Chat';
import Post from './components/Post';
import Thread from './components/Thread';
import LoginButton from './components/LoginButton';
-import Avatar from './components/Avatar';
import { UserLink } from './components/UserInfo';
import Header from './components/Header';
import SearchBox from './components/SearchBox';
-import NavigationIcon from './components/NavigationIcon';
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);
- let params = qs.parse(window.location.search.substring(1));
- if (params.hash) {
- cookies.save('hash', params.hash, { path: '/' });
- window.history.replaceState({}, document.title, `${window.location.protocol}//${window.location.host}${window.location.pathname}`);
- }
- this.state = {
- visitor: {
- uid: 0,
- hash: cookies.load('hash')
- },
- appMarginLeft: 'inherit'
- };
- this.pm = React.createRef();
- this.thread = React.createRef();
- this.sidebar = React.createRef();
+export default function App(props) {
+ let params = qs.parse(window.location.search.substring(1));
+ if (params.hash) {
+ cookies.save('hash', params.hash, { path: '/' });
+ window.history.replaceState({}, document.title, `${window.location.protocol}//${window.location.host}${window.location.pathname}`);
}
+ const [visitor, setVisitor] = useState({
+ uid: 0,
+ hash: cookies.load('hash')
+ });
+
+ let updateStatus = () => {
+ // refresh server visitor state (unread counters)
+ me().then(visitor => {
+ setVisitor(visitor);
+ });
+ };
- initES = () => {
- if (!('EventSource' in window)) {
- return;
+ const [es, setEs] = useState();
+ useEffect(() => {
+ const { hash } = visitor;
+ if (hash) {
+ me().then(visitor => auth(visitor));
}
- const params = { hash: this.state.visitor.hash };
- let url = new URL(`https://api.juick.com/events?${qs.stringify(params)}`);
- this.es = new EventSource(url);
- this.es.onopen = () => {
+ const eventParams = { hash: visitor.hash };
+ let url = new URL(`https://api.juick.com/events?${qs.stringify(eventParams)}`);
+ let es = new EventSource(url);
+ es.onopen = () => {
console.log('online');
+ es.addEventListener('read', updateStatus);
};
- this.es.addEventListener('msg', msg => {
- 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);
- }
- } catch (err) {
- console.log(err);
- }
- });
- }
-
- componentDidMount() {
- const { hash } = this.state.visitor;
- this.initES();
- if (hash) {
- me().then(visitor => this.auth(visitor));
+ es.onerror = () => {
+ es.removeEventListener('read', updateStatus);
}
- }
- search = (history, pathname, searchString) => {
+ setEs(es);
+ }, []);
+
+
+ let search = (history, pathname, searchString) => {
let location = {};
location.pathname = pathname;
location.search = `?search=${searchString}`;
history.push(location);
}
- render() {
- const user = this.state.visitor;
- return (
- <Router>
- <>
- <Header>
- <div id="header_wrapper">
- {
- user.uid > 0 ?
- <UserLink user={user} />
- : <div id="logo">
- <Link to="/">Juick</Link>
- </div>
- }
- <div id="search" className="desktop">
- <SearchBox pathname="/discover" onSearch={this.search} {...this.props} />
- </div>
- <nav id="global">
- {user.uid > 0 ?
- <Link to={{ pathname: '/' }}>
- <Icon name="ei-bell" size="s" /><span className="desktop">Discuss</span>
- {
- user.unreadCount &&
- <span className="badge">{user.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>
-
- {user.uid > 0 ?
- <Link to={{ pathname: '/post' }}>
- <Icon name="ei-pencil" size="s" />
- <span className="desktop">Post</span>
- </Link>
- :
- <LoginButton title="Login" onAuth={this.auth} />
- }
- </nav>
+ let auth = (visitor) => {
+ setVisitor(visitor);
+ }
+ return (
+ <Router>
+ <>
+ <Header>
+ <div id="header_wrapper">
+ {
+ visitor.uid > 0 ?
+ <UserLink user={visitor} />
+ : <div id="logo">
+ <Link to="/">Juick</Link>
+ </div>
+ }
+ <div id="search" className="desktop">
+ <SearchBox pathname="/discover" onSearch={search} {...props} />
</div>
- </Header>
- <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} onChange={this.auth} />
- } />
- <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 connection={this.es} visitor={user} {...props} />} />
- <Route exact path="/:user/friends" render={(props) => <Friends user={props.match.params.user} {...props} />} />
- <Route exact path="/:user/readers" render={(props) => <Readers user={props.match.params.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 connection={this.es} visitor={user} {...props} />} />
- </Switch>
- </section>
- {
- user.uid > 0 &&
- <aside id="sidebar" ref={this.sidebar}>
- <Link to="/?show=my" onClick={this.toggleSidebar}>
- <Icon name="ei-clock" size="s" />
- <span className="desktop">My feed</span>
- </Link>
- <Link to="/pm" onClick={this.toggleSidebar}>
- <Icon name="ei-envelope" size="s" />
- <span className="desktop">Messages</span>
- </Link>
- <Link to="/?show=discuss" onClick={this.toggleSidebar}>
- <Icon name="ei-bell" size="s" />
- <span className="desktop">Discussions</span>
- </Link>
- <Link to="/settings" rel="nofollow" onClick={this.toggleSidebar}>
- <Icon name="ei-gear" size="s" />
- <span className="desktop">Settings</span>
+ <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>
- </aside>
- }
- </>
- </Router>
- );
- }
- auth = (visitor) => {
- this.setState({
- visitor: visitor
- });
- }
+
+ {visitor.uid > 0 ?
+ <Link to={{ pathname: '/post' }}>
+ <Icon name="ei-pencil" size="s" />
+ <span className="desktop">Post</span>
+ </Link>
+ :
+ <LoginButton title="Login" onAuth={auth} />
+ }
+ </nav>
+ </div>
+ </Header>
+ <section id="content">
+ <Switch>
+ <Route exact path="/" render={(props) => <Discussions visitor={visitor} {...props} />} />
+ <Route exact path="/home" render={(props) => <Home visitor={visitor} {...props} />} />
+ <Route exact path="/discover" render={(props) =>
+ <Discover visitor={visitor} {...props} />
+ } />
+ <Route exact path="/settings" render={(props) =>
+ <Settings visitor={visitor} {...props} onChange={auth} />
+ } />
+ <Route exact path="/post" render={(props) => <Post visitor={visitor} {...props} />} />
+ <Route exact path="/pm" render={(props) => <Contacts visitor={visitor} {...props} />} />
+ <Route exact path="/pm/:user" render={(props) => <Chat connection={es} visitor={visitor} {...props} />} />
+ <Route exact path="/:user/friends" render={(props) => <Friends user={props.match.params.user} {...props} />} />
+ <Route exact path="/:user/readers" render={(props) => <Readers user={props.match.params.user} {...props} />} />
+ <Route exact path="/:user" render={(props) => <Blog key={props.match.params.user} visitor={visitor} {...props} />} />
+ <Route exact path="/tag/:tag" render={(props) => <Tag visitor={visitor} {...props} />} />
+ <Route exact path="/:user/:mid" render={(props) => <Thread connection={es} visitor={visitor} {...props} />} />
+ </Switch>
+ </section>
+ {
+ visitor.uid > 0 &&
+ <aside id="sidebar">
+ <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>
+ );
}