aboutsummaryrefslogtreecommitdiff
path: root/vnext/src
diff options
context:
space:
mode:
Diffstat (limited to 'vnext/src')
-rw-r--r--vnext/src/App.js58
-rw-r--r--vnext/src/ui/Feeds.js49
-rw-r--r--vnext/src/ui/Header.js8
-rw-r--r--vnext/src/ui/Login.js8
-rw-r--r--vnext/src/ui/Post.js6
5 files changed, 55 insertions, 74 deletions
diff --git a/vnext/src/App.js b/vnext/src/App.js
index b56e0300..79fde2d1 100644
--- a/vnext/src/App.js
+++ b/vnext/src/App.js
@@ -1,5 +1,5 @@
import { useState, useEffect, useRef } from 'react';
-import { Route, Link, Switch } from 'react-router-dom';
+import { Route, Link, Routes } from 'react-router-dom';
import { useScroll, useRafState } from 'react-use';
import qs from 'qs';
@@ -183,47 +183,21 @@ export default function App({ footer }) {
</aside>
}
<section id="content" ref={contentRef} className={scrollState.top ? elClassTop : ''}>
- <Switch>
- <Route exact path="/">
- <Discussions visitor={visitor} />
- </Route>
- <Route exact path="/home">
- <Home visitor={visitor} />
- </Route>
- <Route exact path="/discover">
- <Discover visitor={visitor} />
- </Route>
- <Route exact path="/settings">
- <Settings visitor={visitor} onChange={auth} />
- </Route>
- <Route exact path="/login">
- <Login visitor={visitor} onAuth={auth} />
- </Route>
- <Route exact path="/post">
- <Post visitor={visitor} />
- </Route>
- <Route exact path="/pm">
- <Contacts visitor={visitor} />
- </Route>
- <Route exact path="/pm/:user">
- <Chat connection={eventSource} visitor={visitor} />
- </Route>
- <Route exact path="/:user/friends">
- <Friends />
- </Route>
- <Route exact path="/:user/readers">
- <Readers />
- </Route>
- <Route exact path="/:user">
- <Blog visitor={visitor} />
- </Route>
- <Route exact path="/tag/:tag">
- <Tag visitor={visitor} />
- </Route>
- <Route exact path="/:user/:mid">
- <Thread connection={eventSource} visitor={visitor} />
- </Route>
- </Switch>
+ <Routes>
+ <Route exact path="/" element={<Discussions visitor={visitor} />} />
+ <Route exact path="/home" element={<Home visitor={visitor} />} />
+ <Route exact path="/discover" element={<Discover visitor={visitor} />} />
+ <Route exact path="/settings" element={<Settings visitor={visitor} onChange={auth} />} />
+ <Route exact path="/login" element={<Login visitor={visitor} onAuth={auth} />} />
+ <Route exact path="/post" element={<Post visitor={visitor} />} />
+ <Route exact path="/pm" element={<Contacts visitor={visitor} />} />
+ <Route exact path="/pm/:user" element={<Chat connection={eventSource} visitor={visitor} />} />
+ <Route exact path="/:user/friends" element={<Friends />} />
+ <Route exact path="/:user/readers" element={<Readers />} />
+ <Route exact path="/:user" element={<Blog visitor={visitor} />} />
+ <Route exact path="/tag/:tag" element={<Tag visitor={visitor} />} />
+ <Route exact path="/:user/:mid" element={<Thread connection={eventSource} visitor={visitor} />} />
+ </Routes>
</section>
</div>
</>
diff --git a/vnext/src/ui/Feeds.js b/vnext/src/ui/Feeds.js
index d6813130..c9199fa6 100644
--- a/vnext/src/ui/Feeds.js
+++ b/vnext/src/ui/Feeds.js
@@ -1,5 +1,5 @@
-import { useState, useEffect } from 'react';
-import { Link, useLocation, useHistory, useParams } from 'react-router-dom';
+import { useState, useEffect, useLayoutEffect } from 'react';
+import { Link, useLocation, useParams, Navigate } from 'react-router-dom';
import qs from 'qs';
import moment from 'moment';
@@ -25,6 +25,19 @@ import { getMessages } from '../api';
* @property {import('../api').Message[]=} msgs
*/
+function RequireAuth({ visitor, children }) {
+ let location = useLocation();
+ if (!visitor.hash) {
+ // Redirect them to the /login page, but save the current location they were
+ // trying to go to when they were redirected. This allows us to send them
+ // along to that page after they login, which is a nicer user experience
+ // than dropping them off on the home page.
+ return <Navigate to="/login" state={{ from: location }} />;
+ }
+
+ return children;
+}
+
/**
* @param {PageProps} props
*/
@@ -36,7 +49,7 @@ export function Discover({ visitor }) {
search: search,
pageParam: search.search ? 'page' : 'before_mid'
};
- return (<Feed authRequired={false} query={query} visitor={visitor} />);
+ return (<Feed query={query} visitor={visitor} />);
}
/**
@@ -47,7 +60,7 @@ export function Discussions({ visitor }) {
baseUrl: '/api/messages/discussions',
pageParam: 'to'
};
- return (<Feed authRequired={false} query={query} visitor={visitor} />);
+ return (<Feed query={query} visitor={visitor} />);
}
/**
@@ -70,7 +83,7 @@ export function Blog({ visitor }) {
<div className="msg-cont">
<UserInfo uname={user} />
</div>
- <Feed authRequired={false} query={query} visitor={visitor} />
+ <Feed query={query} visitor={visitor} />
</>
);
}
@@ -88,7 +101,7 @@ export function Tag({ visitor }) {
},
pageParam: 'before_mid'
};
- return (<Feed authRequired={false} query={query} visitor={visitor} />);
+ return (<Feed query={query} visitor={visitor} />);
}
/**
@@ -99,12 +112,15 @@ export function Home({ visitor }) {
baseUrl: '/api/home',
pageParam: 'before_mid'
};
- return (<Feed authRequired={true} query={query} visitor={visitor} />);
+ return (
+ <RequireAuth visitor={visitor}>
+ <Feed query={query} visitor={visitor} />
+ </RequireAuth>
+ );
}
/**
* @typedef {Object} FeedState
- * @property { boolean } authRequired
* @property { import('../api').SecureUser } visitor
* @property { import('../api').Message[]= } msgs
* @property { Query} query
@@ -113,11 +129,9 @@ export function Home({ visitor }) {
/**
* @param {FeedState} props
*/
-function Feed({ visitor, query, authRequired }) {
+function Feed({ visitor, query }) {
const location = useLocation();
- const history = useHistory();
const [state, setState] = useState({
- authRequired: authRequired,
hash: visitor.hash,
msgs: [],
nextpage: null,
@@ -125,7 +139,6 @@ function Feed({ visitor, query, authRequired }) {
tag: ''
});
const [loading, setLoading] = useState(true);
-
useEffect(() => {
setLoading(true);
const filter = location.search.substring(1);
@@ -135,23 +148,17 @@ function Feed({ visitor, query, authRequired }) {
newFilter[pageParam] = pageValue;
return `?${qs.stringify(newFilter)}`;
};
- document.body.scrollTop = 0;
- document.documentElement.scrollTop = 0;
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 && state.authRequired) {
- history.push('/');
- }
getMessages(url, params)
.then(response => {
const { data } = response;
const { pageParam } = query;
const lastMessage = data.slice(-1)[0] || {};
const nextpage = getPageParam(pageParam, lastMessage, filterParams);
+ document.body.scrollTop = 0;
+ document.documentElement.scrollTop = 0;
setState((prevState) => {
return {
...prevState,
@@ -169,7 +176,7 @@ function Feed({ visitor, query, authRequired }) {
};
});
});
- }, [location.search, state.hash, state.authRequired, history, query]);
+ }, [location.search, query]);
return (state.msgs.length > 0 ? (
<div className="msgs">
{
diff --git a/vnext/src/ui/Header.js b/vnext/src/ui/Header.js
index 1574a489..3162c9ea 100644
--- a/vnext/src/ui/Header.js
+++ b/vnext/src/ui/Header.js
@@ -1,12 +1,12 @@
import { memo, useCallback } from 'react';
-import { Link, useHistory } from 'react-router-dom';
+import { Link, useNavigate } from 'react-router-dom';
import Icon from './Icon';
import { UserLink } from './UserInfo';
import SearchBox from './SearchBox';
function Header({ visitor, className }) {
- const history = useHistory();
+ const navigate = useNavigate();
/**
* @param {string} searchString
*/
@@ -14,8 +14,8 @@ function Header({ visitor, className }) {
let location = {};
location.pathname = '/discover';
location.search = `?search=${searchString}`;
- history.push(location);
- }, [history]);
+ navigate(location);
+ }, [navigate]);
return (
<div id="header" className={className}>
<div id="header_wrapper">
diff --git a/vnext/src/ui/Login.js b/vnext/src/ui/Login.js
index fc3922c8..5a96c822 100644
--- a/vnext/src/ui/Login.js
+++ b/vnext/src/ui/Login.js
@@ -1,5 +1,5 @@
import { useEffect } from 'react';
-import { useLocation, useHistory } from 'react-router-dom';
+import { useLocation, useNavigate } from 'react-router-dom';
import Icon from './Icon';
import Button from './Button';
@@ -22,15 +22,15 @@ import './Login.css';
function Login({ visitor, onAuth }) {
const location = useLocation();
- const history = useHistory();
+ const navigate = useNavigate();
useEffect(() => {
if (visitor.hash) {
const {retpath } = location.state || '/';
console.log(retpath);
- history.push(retpath);
+ navigate(retpath);
}
- }, [history, location.state, visitor]);
+ }, [navigate, location.state, visitor]);
const { register, handleSubmit, formState: { errors }, } = useForm();
diff --git a/vnext/src/ui/Post.js b/vnext/src/ui/Post.js
index d8d841e1..a1d14ea0 100644
--- a/vnext/src/ui/Post.js
+++ b/vnext/src/ui/Post.js
@@ -1,5 +1,5 @@
import { useState } from 'react';
-import { useLocation, useHistory } from 'react-router-dom';
+import { useLocation, useNavigate } from 'react-router-dom';
import qs from 'qs';
@@ -13,7 +13,7 @@ import { post, update } from '../api';
*/
export default function Post({ visitor }) {
const location = useLocation();
- const history = useHistory();
+ const navigate = useNavigate();
let draftMessage = (location.state || {}).draft || {};
let [draft, setDraft] = useState(draftMessage.body);
let params = qs.parse(window.location.search.substring(1));
@@ -24,7 +24,7 @@ export default function Post({ visitor }) {
.then(response => {
if (response.status === 200) {
const msg = response.data.newMessage;
- history.push(`/${visitor.uname}/${msg.mid}`);
+ navigate(`/${visitor.uname}/${msg.mid}`);
}
}).catch(console.log);
};