MemberCount: Fix not properly updating on channel switch

This commit is contained in:
Vendicated 2023-05-05 18:08:12 +02:00
parent 3a54a24c70
commit 0b2c3c834a
No known key found for this signature in database
GPG Key ID: A1DC0CFB5615D905

@ -20,31 +20,34 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Flex } from "@components/Flex"; import { Flex } from "@components/Flex";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { getCurrentChannel } from "@utils/discord"; import { getCurrentChannel } from "@utils/discord";
import { useForceUpdater } from "@utils/misc";
import definePlugin from "@utils/types"; import definePlugin from "@utils/types";
import { findStoreLazy } from "@webpack"; import { findStoreLazy } from "@webpack";
import { Tooltip } from "@webpack/common"; import { SelectedChannelStore, Tooltip, useStateFromStores } from "@webpack/common";
import { FluxStore } from "@webpack/types";
const counts = {} as Record<string, [number, number]>; const GuildMemberCountStore = findStoreLazy("GuildMemberCountStore") as FluxStore & { getMemberCount(guildId: string): number | null; };
let forceUpdate: () => void; const ChannelMemberStore = findStoreLazy("ChannelMemberStore") as FluxStore & {
getProps(guildId: string, channelId: string): { groups: { count: number; id: string; }[]; };
const GuildMemberCountStore = findStoreLazy("GuildMemberCountStore"); };
function MemberCount() { function MemberCount() {
const guildId = getCurrentChannel().guild_id; const { id: channelId, guild_id: guildId } = useStateFromStores([SelectedChannelStore], () => getCurrentChannel());
const c = counts[guildId]; const { groups } = useStateFromStores(
[ChannelMemberStore],
() => ChannelMemberStore.getProps(guildId, channelId)
);
const total = useStateFromStores(
[GuildMemberCountStore],
() => GuildMemberCountStore.getMemberCount(guildId)
);
forceUpdate = useForceUpdater(); if (total == null)
return null;
if (!c) return null; const online =
(groups.length === 1 && groups[0].id === "unknown")
let total = c[0].toLocaleString(); ? 0
if (total === "0" && c[1] > 0) { : groups.reduce((count, curr) => count + curr.count, 0);
const approx = GuildMemberCountStore.getMemberCount(guildId);
total = approx ? approx.toLocaleString() : "Loading...";
}
const online = c[1].toLocaleString();
return ( return (
<Flex id="vc-membercount" style={{ <Flex id="vc-membercount" style={{
@ -55,7 +58,7 @@ function MemberCount() {
alignContent: "center", alignContent: "center",
gap: 0 gap: 0
}}> }}>
<Tooltip text={`${online} Online`} position="bottom"> <Tooltip text={`${online} Online in this Channel`} position="bottom">
{props => ( {props => (
<div {...props}> <div {...props}>
<span <span
@ -72,7 +75,7 @@ function MemberCount() {
</div> </div>
)} )}
</Tooltip> </Tooltip>
<Tooltip text={`${total} Total Members`} position="bottom"> <Tooltip text={`${total} Total Server Members`} position="bottom">
{props => ( {props => (
<div {...props}> <div {...props}>
<span <span
@ -102,31 +105,10 @@ export default definePlugin({
patches: [{ patches: [{
find: ".isSidebarVisible,", find: ".isSidebarVisible,",
replacement: { replacement: {
match: /(var (.)=.\.className.+?children):\[(.\.useMemo[^}]+"aria-multiselectable")/, match: /(var (\i)=\i\.className.+?children):\[(\i\.useMemo[^}]+"aria-multiselectable")/,
replace: "$1:[$2.startsWith('members')?$self.render():null,$3" replace: "$1:[$2.startsWith('members')?$self.render():null,$3"
} }
}], }],
flux: { render: ErrorBoundary.wrap(MemberCount, { noop: true })
GUILD_MEMBER_LIST_UPDATE({ guildId, groups, memberCount, id }) {
// eeeeeh - sometimes it has really wrong counts??? like 10 times less than actual
// but if we only listen to everyone updates, sometimes we never get the count?
// this seems to work but isn't optional
if (id !== "everyone" && counts[guildId]) return;
let count = 0;
for (const group of groups) {
if (group.id !== "offline")
count += group.count;
}
counts[guildId] = [memberCount, count];
forceUpdate?.();
}
},
render: () => (
<ErrorBoundary noop>
<MemberCount />
</ErrorBoundary>
)
}); });