diff --git a/src/plugins/serverListIndicators.tsx b/src/plugins/serverListIndicators.tsx new file mode 100644 index 00000000..e1c0829e --- /dev/null +++ b/src/plugins/serverListIndicators.tsx @@ -0,0 +1,135 @@ +/* + * Vencord, a modification for Discord's desktop app + * Copyright (c) 2022 Sofia Lima + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +import { addServerListElement, removeServerListElement, ServerListRenderPosition } from "@api/ServerList"; +import { Settings } from "@api/settings"; +import ErrorBoundary from "@components/ErrorBoundary"; +import { Devs } from "@utils/constants"; +import { useForceUpdater } from "@utils/misc"; +import definePlugin, { OptionType } from "@utils/types"; +import { FluxDispatcher, GuildStore,PresenceStore, RelationshipStore } from "@webpack/common"; + +enum IndicatorType { + SERVER = 1 << 0, + FRIEND = 1 << 1, + BOTH = SERVER | FRIEND, +} + +let onlineFriends = 0; +let guildCount = 0; +let forceUpdateFriendCount: () => void; +let forceUpdateGuildCount: () => void; + +function FriendsIndicator() { + forceUpdateFriendCount = useForceUpdater(); + + return ( + + {onlineFriends} online + + ); +} + +function ServersIndicator() { + forceUpdateGuildCount = useForceUpdater(); + + return ( + + {guildCount} servers + + ); +} + +export default definePlugin({ + name: "ServerListIndicators", + description: "Add online friend count or server count in the server list", + authors: [Devs.dzshn], + dependencies: ["ServerListAPI"], + + options: { + mode: { + description: "mode", + type: OptionType.SELECT, + options: [ + { label: "Only online friend count", value: IndicatorType.FRIEND, default: true }, + { label: "Only server count", value: IndicatorType.SERVER }, + { label: "Both server and online friend counts", value: IndicatorType.BOTH }, + ] + } + }, + + renderIndicator: () => { + const { mode } = Settings.plugins.ServerListIndicators; + return +
+ {!!(mode & IndicatorType.FRIEND) && } + {!!(mode & IndicatorType.SERVER) && } +
+
; + }, + + handlePresenceUpdate() { + onlineFriends = 0; + const relations = RelationshipStore.getRelationships(); + for (const id of Object.keys(relations)) { + const type = relations[id]; + // FRIEND relationship type + if (type === 1 && PresenceStore.getStatus(id) !== "offline") { + onlineFriends += 1; + } + } + forceUpdateFriendCount?.(); + }, + + handleGuildUpdate() { + guildCount = GuildStore.getGuildCount(); + forceUpdateGuildCount?.(); + }, + + start() { + this.handlePresenceUpdate(); + this.handleGuildUpdate(); + addServerListElement(ServerListRenderPosition.Above, this.renderIndicator); + FluxDispatcher.subscribe("PRESENCE_UPDATES", this.handlePresenceUpdate); + FluxDispatcher.subscribe("GUILD_CREATE", this.handleGuildUpdate); + FluxDispatcher.subscribe("GUILD_DELETE", this.handleGuildUpdate); + }, + + stop() { + removeServerListElement(ServerListRenderPosition.Above, this.renderIndicator); + FluxDispatcher.unsubscribe("PRESENCE_UPDATES", this.handlePresenceUpdate); + FluxDispatcher.unsubscribe("GUILD_CREATE", this.handleGuildUpdate); + FluxDispatcher.unsubscribe("GUILD_DELETE", this.handleGuildUpdate); + } +}); diff --git a/src/webpack/common.tsx b/src/webpack/common.tsx index bd6a69a4..773cc149 100644 --- a/src/webpack/common.tsx +++ b/src/webpack/common.tsx @@ -50,6 +50,7 @@ export let UserStore: Stores.UserStore; export let SelectedChannelStore: Stores.SelectedChannelStore; export let SelectedGuildStore: any; export let ChannelStore: Stores.ChannelStore; +export let RelationshipStore: Stores.RelationshipStore; export const Forms = {} as { FormTitle: Components.FormTitle; @@ -156,6 +157,7 @@ waitFor("getSortedPrivateChannels", m => ChannelStore = m); waitFor("getCurrentlySelectedChannelId", m => SelectedChannelStore = m); waitFor("getLastSelectedGuildId", m => SelectedGuildStore = m); waitFor("getGuildCount", m => GuildStore = m); +waitFor("getRelationshipType", m => RelationshipStore = m); waitFor(["Hovers", "Looks", "Sizes"], m => Button = m); waitFor(filters.byCode("helpdeskArticleId"), m => Switch = m);