fix user rerender race condition

This commit is contained in:
ntr committed 2022-09-15 23:47:20 +10:00
1 parent d2ec08159d
commit 0e3c272adc
3 files changed
+48 -31

No files matched your search

+9 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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,