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,
|
||||
confirmMessage,
|
||||
join,
|
||||
joined,
|
||||
leave,
|
||||
rejectMessage,
|
||||
submitJoin,
|
||||
|
@ -38,7 +37,7 @@ import {
|
|||
unblock,
|
||||
} from '../../common/state/user';
|
||||
import {
|
||||
fetchUsernames,
|
||||
setUsernames,
|
||||
usernamesSelector,
|
||||
} 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 effects = {
|
||||
[addFriendship]: ({dispatch}, {payload: {addeeId, adderId}}) => {
|
||||
dispatch(fetchUsernames([addeeId, adderId]));
|
||||
},
|
||||
[confirmFriendship]: ({dispatch, getState}, {payload: {addeeId, adderId}}) => {
|
||||
const state = getState();
|
||||
const id = idSelector(state);
|
||||
|
@ -58,15 +54,6 @@ const effects = {
|
|||
const name = usernamesSelector(state)[otherId];
|
||||
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}) => {
|
||||
dispatch(addToFavorites(payload));
|
||||
socket.send(new AddFavorite(payload));
|
||||
|
@ -75,7 +62,7 @@ const effects = {
|
|||
const state = getState();
|
||||
const userId = idSelector(state);
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
@ -85,6 +72,7 @@ const effects = {
|
|||
...(hasFriendship ? payload : {}),
|
||||
status: hasFriendship ? 'active' : 'pending',
|
||||
}));
|
||||
dispatch(setUsernames({[id]: name}));
|
||||
});
|
||||
},
|
||||
[submitBlock]: ({dispatch}, {payload: id}) => {
|
||||
|
|
|
@ -8,6 +8,7 @@ export default class Join extends Packet {
|
|||
data: {
|
||||
id: 'uint32',
|
||||
channel: 'string',
|
||||
name: 'string',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import {
|
||||
createAsyncThunk,
|
||||
createSelector,
|
||||
createSlice,
|
||||
} from '@reduxjs/toolkit';
|
||||
|
||||
import Usernames from '~/common/packets/usernames.packet';
|
||||
|
||||
import {socket} from '~/client/hooks/useSocket';
|
||||
import {
|
||||
join,
|
||||
joined,
|
||||
} from '~/common/state/chat';
|
||||
|
||||
import hydration from './hydration';
|
||||
|
||||
|
@ -17,49 +17,22 @@ export const usernameSelector = createSelector(
|
|||
(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 */
|
||||
const slice = createSlice({
|
||||
name: 'usernames',
|
||||
initialState: hydration('usernames') || {},
|
||||
extraReducers: {
|
||||
[fetchUsernames.fulfilled]: (state, {payload}) => {
|
||||
payload.forEach(([id, name]) => {
|
||||
state[id] = name;
|
||||
});
|
||||
},
|
||||
[join]: (state, {payload: {usernames}}) => ({...state, ...usernames}),
|
||||
[joined]: (state, {payload: {id, name}}) => ({...state, [id]: name}),
|
||||
},
|
||||
reducers: {
|
||||
setUsernames: (state, {payload}) => ({...state, ...payload}),
|
||||
},
|
||||
});
|
||||
/* eslint-enable no-param-reassign */
|
||||
|
||||
export const {
|
||||
addFriend,
|
||||
blockUser,
|
||||
removeFriend,
|
||||
setUsernames,
|
||||
} = slice.actions;
|
||||
|
||||
export default slice.reducer;
|
||||
|
|
|
@ -41,6 +41,9 @@ export default {
|
|||
nameOrStatus: friendship.status,
|
||||
}));
|
||||
});
|
||||
return addeeId;
|
||||
return {
|
||||
id: addeeId,
|
||||
name: user.redditUsername,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -10,14 +10,16 @@ import {
|
|||
channelState,
|
||||
channelUsers,
|
||||
} from '~/server/entry';
|
||||
import {allModels} from '~/server/models/registrar';
|
||||
|
||||
import ValidationError from './validation-error';
|
||||
|
||||
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);
|
||||
if (-1 === users.indexOf(userId)) {
|
||||
ServerSocket.send(socket.to(channel), new Join({channel, id: userId}));
|
||||
if (-1 === users.indexOf(id)) {
|
||||
ServerSocket.send(socket.to(channel), new Join({channel, id, name}));
|
||||
}
|
||||
await promisify(socket.join.bind(socket))(channel);
|
||||
};
|
||||
|
@ -31,7 +33,12 @@ export default {
|
|||
},
|
||||
responder: async ({data: {channel}}, socket) => {
|
||||
const {req} = socket;
|
||||
const {User} = allModels();
|
||||
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