From 841ec978bae3297357c3157a3adf846648771770 Mon Sep 17 00:00:00 2001
From: Vitaly Takmazov
Date: Thu, 14 Nov 2019 13:44:52 +0300
Subject: react-router-dom hooks
---
vnext/src/ui/Chat.js | 15 ++++---
vnext/src/ui/Feeds.js | 111 ++++++++++++++++++++++++----------------------
vnext/src/ui/Header.js | 20 ++++++---
vnext/src/ui/Login.js | 12 ++---
vnext/src/ui/Post.js | 7 ++-
vnext/src/ui/SearchBox.js | 10 ++---
vnext/src/ui/Thread.js | 16 ++++---
vnext/src/ui/UserInfo.js | 28 +++++-------
vnext/src/ui/Users.js | 25 ++++++-----
9 files changed, 130 insertions(+), 114 deletions(-)
(limited to 'vnext/src/ui')
diff --git a/vnext/src/ui/Chat.js b/vnext/src/ui/Chat.js
index 00e8eb3c..90c99c27 100644
--- a/vnext/src/ui/Chat.js
+++ b/vnext/src/ui/Chat.js
@@ -1,4 +1,5 @@
import React, { useEffect, useState, useCallback } from 'react';
+import { useParams } from 'react-router-dom';
import moment from 'moment';
import PM from './PM';
@@ -13,7 +14,6 @@ import './Chat.css';
* @typedef {Object} ChatProps
* @property {import('../api').SecureUser} visitor
* @property {EventSource} connection
- * @property {import('react-router').match} match
*/
/**
@@ -22,6 +22,7 @@ import './Chat.css';
*/
export default function Chat(props) {
const [chats, setChats] = useState([]);
+ const params = useParams();
let loadChat = useCallback((uname) => {
const { hash } = props.visitor;
@@ -36,32 +37,32 @@ export default function Chat(props) {
let onMessage = useCallback((json) => {
const msg = JSON.parse(json.data);
- if (msg.user.uname === props.match.params.user) {
+ if (msg.user.uname === params.user) {
setChats((oldChat) => {
return [msg, ...oldChat];
});
}
- }, [props.match.params.user]);
+ }, [params.user]);
let onSend = (template) => {
pm(template.to.uname, template.body)
.then(res => {
- loadChat(props.match.params.user);
+ loadChat(params.user);
}).catch(console.log);
};
useEffect(() => {
if (props.connection.addEventListener) {
props.connection.addEventListener('msg', onMessage);
}
- loadChat(props.match.params.user);
+ loadChat(params.user);
console.log(props.connection);
return () => {
if (props.connection.removeEventListener) {
props.connection.removeEventListener('msg', onMessage);
}
};
- }, [props.connection, onMessage, loadChat, props.match.params.user]);
- const uname = props.match.params.user;
+ }, [props.connection, onMessage, loadChat, params.user]);
+ const uname = params.user;
return (
diff --git a/vnext/src/ui/Feeds.js b/vnext/src/ui/Feeds.js
index e687f1e2..27a8376f 100644
--- a/vnext/src/ui/Feeds.js
+++ b/vnext/src/ui/Feeds.js
@@ -1,6 +1,6 @@
-import React, { useState, useEffect, useRef } from 'react';
+import React, { useState, useEffect } from 'react';
+import { Link, useLocation, useHistory, useParams } from 'react-router-dom';
-import { Link } from 'react-router-dom';
import qs from 'qs';
import moment from 'moment';
@@ -20,9 +20,6 @@ import { getMessages } from '../api';
/**
* @typedef {Object} PageProps
- * @property {import('history').History} history
- * @property {import('history').Location} location
- * @property {import('react-router').match} match
* @property {string=} search
* @property {import('../api').SecureUser} visitor
* @property {import('../api').Message[]=} msgs
@@ -31,34 +28,38 @@ import { getMessages } from '../api';
/**
* @param {PageProps} props
*/
-export function Discover(props) {
- let search = qs.parse(props.location.search.substring(1));
+export function Discover({ visitor }) {
+ const location = useLocation();
+ let search = qs.parse(location.search.substring(1));
const query = {
baseUrl: '/api/messages',
search: search,
pageParam: search.search ? 'page' : 'before_mid'
};
- return (
);
+ return (
);
}
/**
* @param {PageProps} props
*/
-export function Discussions(props) {
+export function Discussions({ visitor }) {
const query = {
baseUrl: '/api/messages/discussions',
pageParam: 'to'
};
- return (
);
+ return (
);
}
/**
* @param {PageProps} props
*/
-export function Blog(props) {
- const { user } = props.match.params;
- let search = qs.parse(props.location.search.substring(1));
- search.uname = user;
+export function Blog({ visitor }) {
+ const { user } = useParams();
+ const location = useLocation();
+ const search = {
+ ...qs.parse(location.search.substring(1)),
+ uname: user
+ };
const query = {
baseUrl: '/api/messages',
search: search,
@@ -67,9 +68,9 @@ export function Blog(props) {
return (
<>
-
+
-
+
>
);
}
@@ -77,8 +78,9 @@ export function Blog(props) {
/**
* @param {PageProps} props
*/
-export function Tag(props) {
- const { tag } = props.match.params;
+export function Tag({ visitor }) {
+ const params = useParams();
+ const { tag } = params;
const query = {
baseUrl: '/api/messages',
search: {
@@ -86,50 +88,47 @@ export function Tag(props) {
},
pageParam: 'before_mid'
};
- return (
);
+ return (
);
}
/**
* @param {PageProps} props
*/
-export function Home(props) {
+export function Home({ visitor }) {
const query = {
baseUrl: '/api/home',
pageParam: 'before_mid'
};
- return (
);
+ return (
);
}
/**
* @typedef {Object} FeedState
* @property authRequired?: boolean
* @property visitor: import('../api').SecureUser
- * @property history: import('history').History
- * @property location: import('history').Location
* @property msgs: import('../api').Message[]
- * @property query: Query
+ * @property { Query} query
*/
/**
* @param {FeedState} props
*/
-function Feed(props) {
+function Feed({ visitor, query, authRequired }) {
+ const location = useLocation();
+ const history = useHistory();
const [state, setState] = useState({
- history: props.history,
- authRequired: props.authRequired,
- query: props.query,
- hash: props.visitor.hash,
- filter: props.location.search.substring(1),
+ authRequired: authRequired,
+ hash: visitor.hash,
msgs: [],
- loading: true,
nextpage: null,
error: false,
tag: ''
});
-
- const stateRef = useRef(state);
+ const [loading, setLoading] = useState(false);
useEffect(() => {
+ setLoading(true);
+ const filter = location.search.substring(1);
let getPageParam = (pageParam, lastMessage, filterParams) => {
const pageValue = pageParam === 'before_mid' ? lastMessage.mid : pageParam === 'page' ? (Number(filterParams.page) || 0) + 1 : moment.utc(lastMessage.updated).valueOf();
let newFilter = { ...filterParams };
@@ -138,35 +137,39 @@ function Feed(props) {
};
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
- const filterParams = qs.parse(stateRef.current.filter);
- let params = Object.assign({}, filterParams || {}, stateRef.current.query.search || {});
- let url = stateRef.current.query.baseUrl;
- if (stateRef.current.hash) {
- params.hash = stateRef.current.hash;
+ const filterParams = qs.parse(filter);
+ let params = Object.assign({}, filterParams || {}, query.search || {});
+ let url = query.baseUrl;
+ if (state.hash) {
+ params.hash = state.hash;
}
- if (!params.hash && stateRef.current.authRequired) {
- stateRef.current.history.push('/');
+ if (!params.hash && state.authRequired) {
+ history.push('/');
}
getMessages(url, params)
.then(response => {
const { data } = response;
- const { pageParam } = stateRef.current.query;
+ const { pageParam } = query;
const lastMessage = data.slice(-1)[0] || {};
const nextpage = getPageParam(pageParam, lastMessage, filterParams);
- setState({
- ...stateRef.current,
- msgs: data,
- loading: false,
- nextpage: nextpage,
- tag: qs.parse(location.search.substring(1))['tag'] || ''
+ setState((prevState) => {
+ return {
+ ...prevState,
+ msgs: data,
+ nextpage: nextpage,
+ tag: qs.parse(location.search.substring(1))['tag'] || ''
+ };
});
+ setLoading(false);
}).catch(ex => {
- setState({
- ...stateRef.current,
- error: true
+ setState((prevState) => {
+ return {
+ ...prevState,
+ error: true
+ };
});
});
- }, []);
+ }, [location.search, state.hash, state.authRequired, history, query]);
return (state.msgs.length > 0 ? (
{
@@ -180,16 +183,16 @@ function Feed(props) {
}
{
state.msgs.map(msg =>
-
)
+
)
}
{
state.msgs.length >= 20 && (
- Next →
+ Next →
)
}
- ) : state.error ?
error
: state.loading ?
:
No more messages
+ ) : state.error ?
error
: loading ?
:
No more messages
);
}
diff --git a/vnext/src/ui/Header.js b/vnext/src/ui/Header.js
index a7663dd3..d8fe23e0 100644
--- a/vnext/src/ui/Header.js
+++ b/vnext/src/ui/Header.js
@@ -1,11 +1,21 @@
-import React, { memo } from 'react';
-import { Link, withRouter } from 'react-router-dom';
+import React, { memo, useCallback } from 'react';
+import { Link, useHistory } from 'react-router-dom';
import Icon from './Icon';
import { UserLink } from './UserInfo';
import SearchBox from './SearchBox';
-function Header({ visitor, search, className }) {
+function Header({ visitor, className }) {
+ const history = useHistory();
+ /**
+ * @param {string} searchString
+ */
+ let searchAll = useCallback((searchString) => {
+ let location = {};
+ location.pathname = '/discover';
+ location.search = `?search=${searchString}`;
+ history.push(location);
+ }, [history]);
return (