fix user rerender race condition
This commit is contained in:
1 parent
d2ec08159d
commit
0e3c272adc
3 files changed
+48
-31
No files matched your search
+9
-1
@@ -66,6 +66,9 @@ export default function createRpc(log: Log, pg: Pg, user: User, ws, discogs, off
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function onConnection() {
|
async function onConnection() {
|
||||||
|
const userMsg: UserMessage = [RpcMessageType.User, user];
|
||||||
|
send(userMsg);
|
||||||
|
|
||||||
const wants = await pg.userWants(user);
|
const wants = await pg.userWants(user);
|
||||||
const wantsMsg: WantsMessage = [RpcMessageType.Wants, wants];
|
const wantsMsg: WantsMessage = [RpcMessageType.Wants, wants];
|
||||||
send(wantsMsg);
|
send(wantsMsg);
|
||||||
@@ -93,17 +96,20 @@ export enum RpcMessageType {
|
|||||||
Bundles = 'Bundles',
|
Bundles = 'Bundles',
|
||||||
Offers = 'Offers',
|
Offers = 'Offers',
|
||||||
List = 'List',
|
List = 'List',
|
||||||
|
Wants = 'Wants',
|
||||||
|
User = 'User',
|
||||||
|
|
||||||
Error = 'Error',
|
Error = 'Error',
|
||||||
|
|
||||||
OfferStatusSet = 'OfferStatusSet',
|
OfferStatusSet = 'OfferStatusSet',
|
||||||
|
|
||||||
Wants = 'Wants',
|
|
||||||
WantRm = 'WantRm',
|
WantRm = 'WantRm',
|
||||||
}
|
}
|
||||||
|
|
||||||
type ErrorMessage = [RpcMessageType.Error, string];
|
type ErrorMessage = [RpcMessageType.Error, string];
|
||||||
type PongMessage = [RpcMessageType.Pong, []];
|
type PongMessage = [RpcMessageType.Pong, []];
|
||||||
type PingMessage = [RpcMessageType.Ping, []];
|
type PingMessage = [RpcMessageType.Ping, []];
|
||||||
|
type UserMessage = [RpcMessageType.User, User];
|
||||||
type WantsMessage = [RpcMessageType.Wants, Want[]];
|
type WantsMessage = [RpcMessageType.Wants, Want[]];
|
||||||
type OffersMessage = [RpcMessageType.Offers, Offer[]];
|
type OffersMessage = [RpcMessageType.Offers, Offer[]];
|
||||||
type OfferStatusSetMessage = [RpcMessageType.OfferStatusSet, Offer[]];
|
type OfferStatusSetMessage = [RpcMessageType.OfferStatusSet, Offer[]];
|
||||||
@@ -112,6 +118,8 @@ export type RpcMessage =
|
|||||||
PingMessage |
|
PingMessage |
|
||||||
PongMessage |
|
PongMessage |
|
||||||
|
|
||||||
|
UserMessage |
|
||||||
|
|
||||||
WantsMessage |
|
WantsMessage |
|
||||||
|
|
||||||
OffersMessage |
|
OffersMessage |
|
||||||
|
|||||||
+30
-26
@@ -1,5 +1,6 @@
|
|||||||
import { h } from 'preact';
|
import { h } from 'preact';
|
||||||
import { useState, useEffect } from 'preact/hooks';
|
import { useState, useEffect } from 'preact/hooks';
|
||||||
|
import { useSelector, useDispatch } from 'react-redux'
|
||||||
import { Route, Router, route } from 'preact-router';
|
import { Route, Router, route } from 'preact-router';
|
||||||
import { Provider } from 'react-redux'
|
import { Provider } from 'react-redux'
|
||||||
|
|
||||||
@@ -15,38 +16,41 @@ import Login from './routes/login';
|
|||||||
import Search from './routes/search';
|
import Search from './routes/search';
|
||||||
import List from './routes/list';
|
import List from './routes/list';
|
||||||
|
|
||||||
import store, { userState, wsState } from './store'
|
import store, { userState, wsState, State } from './store'
|
||||||
|
|
||||||
const ws = createWs(store);
|
const Main = () => {
|
||||||
ws.connect();
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
// dodgy, doesn't cause the header to rerender
|
// i have no idea why this is needed,
|
||||||
async function init() {
|
// but it makes sure the user changes actually rerender
|
||||||
const [error, user] = await http.getLogin();
|
useEffect(() => {
|
||||||
if (error) return route('/login');
|
const ws = createWs(dispatch);
|
||||||
route('/bundles');
|
ws.connect();
|
||||||
store.dispatch(userState.actions.set(user));
|
dispatch(wsState.actions.set(ws));
|
||||||
store.dispatch(wsState.actions.set(ws));
|
}, [dispatch])
|
||||||
}
|
|
||||||
init();
|
return (
|
||||||
|
<main id="app">
|
||||||
|
<Header />
|
||||||
|
<Router>
|
||||||
|
<Route path="/" component={Home} />
|
||||||
|
<Route path="/login" component={Login} mode="login" />
|
||||||
|
<Route path="/register" component={Login} mode="register" />
|
||||||
|
<Route path="/search" component={Search} />
|
||||||
|
<Route path="/list" component={List} />
|
||||||
|
|
||||||
|
{/* ACP */}
|
||||||
|
<Route path="/bundles" component={Bundles} />
|
||||||
|
<Route path="/offers/acp" component={Admin} />
|
||||||
|
</Router>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<main id="app">
|
<Main />
|
||||||
<Header />
|
|
||||||
<Router>
|
|
||||||
<Route path="/" component={Home} />
|
|
||||||
<Route path="/login" component={Login} mode="login" />
|
|
||||||
<Route path="/register" component={Login} mode="register" />
|
|
||||||
<Route path="/search" component={Search} />
|
|
||||||
<Route path="/list" component={List} />
|
|
||||||
|
|
||||||
{/* ACP */}
|
|
||||||
<Route path="/bundles" component={Bundles} />
|
|
||||||
<Route path="/offers/acp" component={Admin} />
|
|
||||||
</Router>
|
|
||||||
</main>
|
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-4
@@ -1,8 +1,8 @@
|
|||||||
|
import { wantsState, wsState, userState } from './store'
|
||||||
|
|
||||||
const SOCKET_URL = `${window.location.protocol === 'https:' ? 'wss://' : 'ws://'}${window.location.host}/api/ws`;
|
const SOCKET_URL = `${window.location.protocol === 'https:' ? 'wss://' : 'ws://'}${window.location.host}/api/ws`;
|
||||||
|
|
||||||
import { wantsState, wsState } from './store'
|
export default function createSocket(dispatch) {
|
||||||
|
|
||||||
export default function createSocket(store) {
|
|
||||||
let ws;
|
let ws;
|
||||||
|
|
||||||
// -------------
|
// -------------
|
||||||
@@ -42,8 +42,12 @@ export default function createSocket(store) {
|
|||||||
// -------------
|
// -------------
|
||||||
// Incoming
|
// Incoming
|
||||||
// -------------
|
// -------------
|
||||||
|
function onUser(user) {
|
||||||
|
dispatch(userState.actions.set(user));
|
||||||
|
}
|
||||||
|
|
||||||
function onWants(wants) {
|
function onWants(wants) {
|
||||||
store.dispatch(wantsState.actions.set(wants));
|
dispatch(wantsState.actions.set(wants));
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------
|
// -------------
|
||||||
@@ -53,6 +57,7 @@ export default function createSocket(store) {
|
|||||||
// this object wraps the reply types to a function
|
// this object wraps the reply types to a function
|
||||||
const handlers = {
|
const handlers = {
|
||||||
Wants: onWants,
|
Wants: onWants,
|
||||||
|
User: onUser,
|
||||||
|
|
||||||
Pong: onPong,
|
Pong: onPong,
|
||||||
Error: errHandler,
|
Error: errHandler,
|
||||||
|
|||||||
Reference in new issue
Block a user