fix: hydrate
This commit is contained in:
parent
b7331148b6
commit
adba33448b
|
@ -1,49 +1,41 @@
|
||||||
import {promisify} from 'util';
|
import {promisify} from 'util';
|
||||||
|
|
||||||
import D from 'debug';
|
// import D from 'debug';
|
||||||
import {ModelMap} from '@latus/db';
|
import {ModelMap} from '@latus/db';
|
||||||
import {createClient, keys} from '@latus/redis';
|
import {createClient, keys} from '@latus/redis';
|
||||||
import {channelIsAnonymous, parseChannel, renderChannel} from '@reddichat/core';
|
import {channelIsAnonymous, parseChannel, renderChannel} from '@reddichat/core';
|
||||||
|
|
||||||
const debug = D('@reddichat/chat/state');
|
// const debug = D('@reddichat/chat/state');
|
||||||
|
|
||||||
export const channelUserCounts = async (req, channel) => {
|
export const channelUserCounts = async (req, channel) => {
|
||||||
const rooms = [renderChannel(channel)];
|
const rooms = [renderChannel(channel)];
|
||||||
debug('channelUserCounts: rooms(%O)', rooms);
|
|
||||||
const ids = await req.clients(rooms);
|
const ids = await req.clients(rooms);
|
||||||
debug('channelUserCounts: ids(%O)', ids);
|
|
||||||
if (0 === ids.length) {
|
if (0 === ids.length) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const replies = channelIsAnonymous(channel)
|
const replies = channelIsAnonymous(channel)
|
||||||
? [ids.reduce((r, socketKey) => ({...r, [socketKey]: 0}), {})]
|
? [ids.reduce((r, socketKey) => ({...r, [socketKey]: 0}), {})]
|
||||||
: await req.intercom('@reddichat/user/users', ids);
|
: await req.intercom('@reddichat/user/users', ids);
|
||||||
debug('channelUserCounts: replies(%O)', replies);
|
|
||||||
const uids = replies.reduce((r, m) => ({...r, ...m}), {});
|
const uids = replies.reduce((r, m) => ({...r, ...m}), {});
|
||||||
debug('channelUserCounts: uids(%O)', uids);
|
|
||||||
const reduced = Object.values(uids).reduce((r, uid) => ({...r, [uid]: 1 + (r[uid] || 0)}), {});
|
const reduced = Object.values(uids).reduce((r, uid) => ({...r, [uid]: 1 + (r[uid] || 0)}), {});
|
||||||
debug('channelUserCounts: reduced(%O)', reduced);
|
|
||||||
return reduced;
|
return reduced;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const channelUsers = async (req, channel) => {
|
export const channelUsers = async (req, channel) => {
|
||||||
const userCounts = await channelUserCounts(req, channel);
|
const userCounts = await channelUserCounts(req, channel);
|
||||||
debug('channelUsers: userCounts(%O)', userCounts);
|
|
||||||
const parsed = Object.keys(userCounts).map((id) => parseInt(id, 10));
|
const parsed = Object.keys(userCounts).map((id) => parseInt(id, 10));
|
||||||
debug('channelUsers: parsed(%O)', parsed);
|
|
||||||
return parsed;
|
return parsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const channelState = async (req, latus, channel) => {
|
export const channelState = async (req, latus, channel) => {
|
||||||
debug('channelState');
|
|
||||||
const {name, type} = channel;
|
const {name, type} = channel;
|
||||||
const redisClient = createClient(latus);
|
const redisClient = createClient(latus);
|
||||||
const mget = promisify(redisClient.mget.bind(redisClient));
|
const mget = promisify(redisClient.mget.bind(redisClient));
|
||||||
const realName = 'r' === type
|
const realName = 'r' === type
|
||||||
? name
|
? name
|
||||||
: `${[name, req.user.redditUsername].sort().join('$')}`;
|
: `${[name, req.user.redditUsername].sort().join('$')}`;
|
||||||
const messagesKey = `${renderChannel({type, name: realName})}:messages:*`;
|
const pattern = `${renderChannel({type, name: realName})}:messages:*`;
|
||||||
const messageKeys = await keys(redisClient, messagesKey);
|
const messageKeys = await keys(redisClient, pattern);
|
||||||
const messages = 0 === messageKeys.length
|
const messages = 0 === messageKeys.length
|
||||||
? []
|
? []
|
||||||
: (await mget(messageKeys))
|
: (await mget(messageKeys))
|
||||||
|
@ -53,19 +45,19 @@ export const channelState = async (req, latus, channel) => {
|
||||||
}))
|
}))
|
||||||
.filter(({message}) => !!message)
|
.filter(({message}) => !!message)
|
||||||
.sort((l, r) => l.timestamp - r.timestamp);
|
.sort((l, r) => l.timestamp - r.timestamp);
|
||||||
const users = new Set(await channelUsers(req, channel));
|
const users = channelIsAnonymous(channel)
|
||||||
users.add(channelIsAnonymous(channel) ? 0 : req.userId);
|
? [0]
|
||||||
|
: Array.from((new Set(await channelUsers(req, channel))).values());
|
||||||
return {
|
return {
|
||||||
messages,
|
messages,
|
||||||
users: Array.from(users.values()),
|
users,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const channelsToHydrate = async (req, latus) => {
|
export const channelsToHydrate = async (req, latus) => {
|
||||||
debug('channelsToHydrate');
|
|
||||||
const {channel, user} = req;
|
const {channel, user} = req;
|
||||||
if (!user) {
|
if (!user && channel) {
|
||||||
return channel ? [channel] : [];
|
return channelIsAnonymous(channel) ? [channel] : [];
|
||||||
}
|
}
|
||||||
const {User} = ModelMap(latus);
|
const {User} = ModelMap(latus);
|
||||||
const channels = await Promise.all(
|
const channels = await Promise.all(
|
||||||
|
@ -79,13 +71,15 @@ export const channelsToHydrate = async (req, latus) => {
|
||||||
}),
|
}),
|
||||||
))),
|
))),
|
||||||
);
|
);
|
||||||
return Promise.all(Array.from((new Set(channels.map(renderChannel))).values())
|
// eslint-disable-next-line max-len
|
||||||
|
return (await Promise.all(Array.from((new Set(channels.map(renderChannel))).values())
|
||||||
.map(parseChannel)
|
.map(parseChannel)
|
||||||
.filter((channel) => !user.isBannedFrom(channel)));
|
.map(async (channel) => [await user.isBannedFrom(channel), channel])))
|
||||||
|
.filter(([isBanned]) => !isBanned)
|
||||||
|
.map(([, channel]) => channel);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const chatUserIds = async (req, latus) => {
|
export const chatUserIds = async (req, latus) => {
|
||||||
debug('chatUserIds');
|
|
||||||
const toHydrate = await channelsToHydrate(req, latus);
|
const toHydrate = await channelsToHydrate(req, latus);
|
||||||
if (0 === toHydrate.length) {
|
if (0 === toHydrate.length) {
|
||||||
return [];
|
return [];
|
||||||
|
@ -103,9 +97,7 @@ export const chatUserIds = async (req, latus) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default async (req, latus) => {
|
export default async (req, latus) => {
|
||||||
debug('default state: url(%s), headers(%O)', req.url, req.headers);
|
|
||||||
const toHydrate = await channelsToHydrate(req, latus);
|
const toHydrate = await channelsToHydrate(req, latus);
|
||||||
debug('default state: toHydrate(%O)', toHydrate);
|
|
||||||
const chat = {
|
const chat = {
|
||||||
channels: {},
|
channels: {},
|
||||||
input: {},
|
input: {},
|
||||||
|
@ -117,7 +109,6 @@ export default async (req, latus) => {
|
||||||
const entries = await Promise.all(
|
const entries = await Promise.all(
|
||||||
toHydrate.map((favorite) => channelState(req, latus, favorite)),
|
toHydrate.map((favorite) => channelState(req, latus, favorite)),
|
||||||
);
|
);
|
||||||
debug('default state: entries(%O)', entries);
|
|
||||||
for (let i = 0; i < toHydrate.length; i++) {
|
for (let i = 0; i < toHydrate.length; i++) {
|
||||||
const channel = renderChannel(toHydrate[i]);
|
const channel = renderChannel(toHydrate[i]);
|
||||||
const {messages, users} = entries[i];
|
const {messages, users} = entries[i];
|
||||||
|
@ -129,6 +120,5 @@ export default async (req, latus) => {
|
||||||
chat.messages[message.uuid] = message;
|
chat.messages[message.uuid] = message;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
debug('default state(%O)', chat);
|
|
||||||
return chat;
|
return chat;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user