refactor: no username roundtrips
This commit is contained in:
parent
ba5e3c71a6
commit
291847cf95
18
src/client/store/effects.js
vendored
18
src/client/store/effects.js
vendored
|
@ -14,7 +14,6 @@ import {
|
||||||
addMessage,
|
addMessage,
|
||||||
confirmMessage,
|
confirmMessage,
|
||||||
join,
|
join,
|
||||||
joined,
|
|
||||||
leave,
|
leave,
|
||||||
rejectMessage,
|
rejectMessage,
|
||||||
submitJoin,
|
submitJoin,
|
||||||
|
@ -38,7 +37,7 @@ import {
|
||||||
unblock,
|
unblock,
|
||||||
} from '../../common/state/user';
|
} from '../../common/state/user';
|
||||||
import {
|
import {
|
||||||
fetchUsernames,
|
setUsernames,
|
||||||
usernamesSelector,
|
usernamesSelector,
|
||||||
} from '~/common/state/usernames';
|
} from '~/common/state/usernames';
|
||||||
|
|
||||||
|
@ -48,9 +47,6 @@ const characterLimiter = new RateLimiterMemory({points: 2048, duration: 2});
|
||||||
const messageLimiter = new RateLimiterMemory({points: 10, duration: 15});
|
const messageLimiter = new RateLimiterMemory({points: 10, duration: 15});
|
||||||
|
|
||||||
const effects = {
|
const effects = {
|
||||||
[addFriendship]: ({dispatch}, {payload: {addeeId, adderId}}) => {
|
|
||||||
dispatch(fetchUsernames([addeeId, adderId]));
|
|
||||||
},
|
|
||||||
[confirmFriendship]: ({dispatch, getState}, {payload: {addeeId, adderId}}) => {
|
[confirmFriendship]: ({dispatch, getState}, {payload: {addeeId, adderId}}) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const id = idSelector(state);
|
const id = idSelector(state);
|
||||||
|
@ -58,15 +54,6 @@ const effects = {
|
||||||
const name = usernamesSelector(state)[otherId];
|
const name = usernamesSelector(state)[otherId];
|
||||||
dispatch(submitJoin({channel: `/u/${name}`, id}));
|
dispatch(submitJoin({channel: `/u/${name}`, id}));
|
||||||
},
|
},
|
||||||
[join]: ({dispatch}, {payload: {messages, users}}) => {
|
|
||||||
const ids = new Set();
|
|
||||||
Object.values(messages).map((message) => message.owner).forEach((id) => ids.add(id));
|
|
||||||
users.forEach((id) => ids.add(id));
|
|
||||||
dispatch(fetchUsernames(Array.from(ids.keys())));
|
|
||||||
},
|
|
||||||
[joined]: ({dispatch}, {payload: {id}}) => {
|
|
||||||
dispatch(fetchUsernames([id]));
|
|
||||||
},
|
|
||||||
[submitAddFavorite]: ({dispatch}, {payload}) => {
|
[submitAddFavorite]: ({dispatch}, {payload}) => {
|
||||||
dispatch(addToFavorites(payload));
|
dispatch(addToFavorites(payload));
|
||||||
socket.send(new AddFavorite(payload));
|
socket.send(new AddFavorite(payload));
|
||||||
|
@ -75,7 +62,7 @@ const effects = {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const userId = idSelector(state);
|
const userId = idSelector(state);
|
||||||
const hasFriendship = !!payload.addeeId;
|
const hasFriendship = !!payload.addeeId;
|
||||||
socket.send(new AddFriend({nameOrStatus: payload.nameOrStatus}), (error, id) => {
|
socket.send(new AddFriend({nameOrStatus: payload.nameOrStatus}), (error, {id, name}) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -85,6 +72,7 @@ const effects = {
|
||||||
...(hasFriendship ? payload : {}),
|
...(hasFriendship ? payload : {}),
|
||||||
status: hasFriendship ? 'active' : 'pending',
|
status: hasFriendship ? 'active' : 'pending',
|
||||||
}));
|
}));
|
||||||
|
dispatch(setUsernames({[id]: name}));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[submitBlock]: ({dispatch}, {payload: id}) => {
|
[submitBlock]: ({dispatch}, {payload: id}) => {
|
||||||
|
|
|
@ -8,6 +8,7 @@ export default class Join extends Packet {
|
||||||
data: {
|
data: {
|
||||||
id: 'uint32',
|
id: 'uint32',
|
||||||
channel: 'string',
|
channel: 'string',
|
||||||
|
name: 'string',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import {
|
import {
|
||||||
createAsyncThunk,
|
|
||||||
createSelector,
|
createSelector,
|
||||||
createSlice,
|
createSlice,
|
||||||
} from '@reduxjs/toolkit';
|
} from '@reduxjs/toolkit';
|
||||||
|
|
||||||
import Usernames from '~/common/packets/usernames.packet';
|
import {
|
||||||
|
join,
|
||||||
import {socket} from '~/client/hooks/useSocket';
|
joined,
|
||||||
|
} from '~/common/state/chat';
|
||||||
|
|
||||||
import hydration from './hydration';
|
import hydration from './hydration';
|
||||||
|
|
||||||
|
@ -17,49 +17,22 @@ export const usernameSelector = createSelector(
|
||||||
(usernames, id) => usernames[id],
|
(usernames, id) => usernames[id],
|
||||||
);
|
);
|
||||||
|
|
||||||
export const fetchUsernames = createAsyncThunk(
|
|
||||||
'usernames/fetchUsernames',
|
|
||||||
async (ids, {getState}) => {
|
|
||||||
const usernames = usernamesSelector(getState());
|
|
||||||
const hasAnonymous = -1 !== ids.indexOf(0);
|
|
||||||
const missingIds = ids.filter((id) => 0 !== id && !usernames[id]);
|
|
||||||
if (0 === missingIds.length) {
|
|
||||||
return hasAnonymous ? [[0, 'anonymous']] : [];
|
|
||||||
}
|
|
||||||
return new Promise((resolve, reject) => (
|
|
||||||
socket.send(new Usernames(missingIds), (error, usernames) => {
|
|
||||||
if (error) {
|
|
||||||
reject(error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve(
|
|
||||||
missingIds
|
|
||||||
.map((id, i) => [id, usernames[i]])
|
|
||||||
.concat(hasAnonymous ? [[0, 'anonymous']] : []),
|
|
||||||
);
|
|
||||||
})
|
|
||||||
));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
/* eslint-disable no-param-reassign */
|
/* eslint-disable no-param-reassign */
|
||||||
const slice = createSlice({
|
const slice = createSlice({
|
||||||
name: 'usernames',
|
name: 'usernames',
|
||||||
initialState: hydration('usernames') || {},
|
initialState: hydration('usernames') || {},
|
||||||
extraReducers: {
|
extraReducers: {
|
||||||
[fetchUsernames.fulfilled]: (state, {payload}) => {
|
[join]: (state, {payload: {usernames}}) => ({...state, ...usernames}),
|
||||||
payload.forEach(([id, name]) => {
|
[joined]: (state, {payload: {id, name}}) => ({...state, [id]: name}),
|
||||||
state[id] = name;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
reducers: {
|
||||||
|
setUsernames: (state, {payload}) => ({...state, ...payload}),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
/* eslint-enable no-param-reassign */
|
/* eslint-enable no-param-reassign */
|
||||||
|
|
||||||
export const {
|
export const {
|
||||||
addFriend,
|
setUsernames,
|
||||||
blockUser,
|
|
||||||
removeFriend,
|
|
||||||
} = slice.actions;
|
} = slice.actions;
|
||||||
|
|
||||||
export default slice.reducer;
|
export default slice.reducer;
|
||||||
|
|
|
@ -41,6 +41,9 @@ export default {
|
||||||
nameOrStatus: friendship.status,
|
nameOrStatus: friendship.status,
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
return addeeId;
|
return {
|
||||||
|
id: addeeId,
|
||||||
|
name: user.redditUsername,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,14 +10,16 @@ import {
|
||||||
channelState,
|
channelState,
|
||||||
channelUsers,
|
channelUsers,
|
||||||
} from '~/server/entry';
|
} from '~/server/entry';
|
||||||
|
import {allModels} from '~/server/models/registrar';
|
||||||
|
|
||||||
import ValidationError from './validation-error';
|
import ValidationError from './validation-error';
|
||||||
|
|
||||||
export const userJoin = async (channel, socket) => {
|
export const userJoin = async (channel, socket) => {
|
||||||
const userId = '/r/anonymous' === channel ? 0 : socket.handshake.userId;
|
const id = '/r/anonymous' === channel ? 0 : socket.handshake.userId;
|
||||||
|
const name = '/r/anonymous' === channel ? 'anonymous' : socket.handshake.user.redditUsername;
|
||||||
const users = await channelUsers(socket.handshake, channel);
|
const users = await channelUsers(socket.handshake, channel);
|
||||||
if (-1 === users.indexOf(userId)) {
|
if (-1 === users.indexOf(id)) {
|
||||||
ServerSocket.send(socket.to(channel), new Join({channel, id: userId}));
|
ServerSocket.send(socket.to(channel), new Join({channel, id, name}));
|
||||||
}
|
}
|
||||||
await promisify(socket.join.bind(socket))(channel);
|
await promisify(socket.join.bind(socket))(channel);
|
||||||
};
|
};
|
||||||
|
@ -31,7 +33,12 @@ export default {
|
||||||
},
|
},
|
||||||
responder: async ({data: {channel}}, socket) => {
|
responder: async ({data: {channel}}, socket) => {
|
||||||
const {req} = socket;
|
const {req} = socket;
|
||||||
|
const {User} = allModels();
|
||||||
await userJoin(channel, socket.socket);
|
await userJoin(channel, socket.socket);
|
||||||
return channelState(req, channel);
|
const state = channelState(req, channel);
|
||||||
|
const entries = await Promise.all(
|
||||||
|
state.users.map(async (id) => [id, (await User.findByPk(id)).redditUsername]),
|
||||||
|
);
|
||||||
|
return {...state, usernames: entries.reduce((r, [id, name]) => ({...r, [id]: name}))};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user