aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorV <vendicated@riseup.net>2023-04-22 03:18:19 +0200
committerGitHub <noreply@github.com>2023-04-22 01:18:19 +0000
commit63fc354d483b86857bbee7f540c66ba614fc0f1f (patch)
tree6ebe100e5ff63254adfdb0c44cb473dcc339cf35 /src
parentc6f0c84935db37e2a18578a081404d84292fe36a (diff)
downloadVencord-63fc354d483b86857bbee7f540c66ba614fc0f1f.tar.gz
Vencord-63fc354d483b86857bbee7f540c66ba614fc0f1f.tar.bz2
Vencord-63fc354d483b86857bbee7f540c66ba614fc0f1f.zip
feat: auto-managed flux subscriptions via plugin.flux (#959)
Diffstat (limited to 'src')
-rw-r--r--src/plugins/index.ts42
-rw-r--r--src/plugins/keepCurrentChannel.ts75
-rw-r--r--src/plugins/memberCount.tsx36
-rw-r--r--src/plugins/moyai.ts66
-rw-r--r--src/plugins/relationshipNotifier/events.ts41
-rw-r--r--src/plugins/relationshipNotifier/index.ts25
-rw-r--r--src/plugins/serverListIndicators.tsx50
-rw-r--r--src/plugins/supportHelper.tsx18
-rw-r--r--src/plugins/vcNarrator.tsx95
-rw-r--r--src/utils/types.ts7
10 files changed, 206 insertions, 249 deletions
diff --git a/src/plugins/index.ts b/src/plugins/index.ts
index d0d16c2..ab69ca7 100644
--- a/src/plugins/index.ts
+++ b/src/plugins/index.ts
@@ -20,6 +20,8 @@ import { registerCommand, unregisterCommand } from "@api/Commands";
import { Settings } from "@api/settings";
import Logger from "@utils/Logger";
import { Patch, Plugin } from "@utils/types";
+import { FluxDispatcher } from "@webpack/common";
+import { FluxEvents } from "@webpack/types";
import Plugins from "~plugins";
@@ -111,56 +113,64 @@ export function startDependenciesRecursive(p: Plugin) {
}
export const startPlugin = traceFunction("startPlugin", function startPlugin(p: Plugin) {
+ const { name, commands, flux } = p;
+
if (p.start) {
- logger.info("Starting plugin", p.name);
+ logger.info("Starting plugin", name);
if (p.started) {
- logger.warn(`${p.name} already started`);
+ logger.warn(`${name} already started`);
return false;
}
try {
p.start();
p.started = true;
} catch (e) {
- logger.error(`Failed to start ${p.name}\n`, e);
+ logger.error(`Failed to start ${name}\n`, e);
return false;
}
}
- if (p.commands?.length) {
- logger.info("Registering commands of plugin", p.name);
- for (const cmd of p.commands) {
+ if (commands?.length) {
+ logger.info("Registering commands of plugin", name);
+ for (const cmd of commands) {
try {
- registerCommand(cmd, p.name);
+ registerCommand(cmd, name);
} catch (e) {
logger.error(`Failed to register command ${cmd.name}\n`, e);
return false;
}
}
+ }
+ if (flux) {
+ for (const event in flux) {
+ FluxDispatcher.subscribe(event as FluxEvents, flux[event]);
+ }
}
return true;
}, p => `startPlugin ${p.name}`);
export const stopPlugin = traceFunction("stopPlugin", function stopPlugin(p: Plugin) {
+ const { name, commands, flux } = p;
if (p.stop) {
- logger.info("Stopping plugin", p.name);
+ logger.info("Stopping plugin", name);
if (!p.started) {
- logger.warn(`${p.name} already stopped`);
+ logger.warn(`${name} already stopped`);
return false;
}
try {
p.stop();
p.started = false;
} catch (e) {
- logger.error(`Failed to stop ${p.name}\n`, e);
+ logger.error(`Failed to stop ${name}\n`, e);
return false;
}
}
- if (p.commands?.length) {
- logger.info("Unregistering commands of plugin", p.name);
- for (const cmd of p.commands) {
+ if (commands?.length) {
+ logger.info("Unregistering commands of plugin", name);
+ for (const cmd of commands) {
try {
unregisterCommand(cmd.name);
} catch (e) {
@@ -170,5 +180,11 @@ export const stopPlugin = traceFunction("stopPlugin", function stopPlugin(p: Plu
}
}
+ if (flux) {
+ for (const event in flux) {
+ FluxDispatcher.unsubscribe(event as FluxEvents, flux[event]);
+ }
+ }
+
return true;
}, p => `stopPlugin ${p.name}`);
diff --git a/src/plugins/keepCurrentChannel.ts b/src/plugins/keepCurrentChannel.ts
index e553b93..b226c34 100644
--- a/src/plugins/keepCurrentChannel.ts
+++ b/src/plugins/keepCurrentChannel.ts
@@ -19,7 +19,7 @@
import * as DataStore from "@api/DataStore";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
-import { ChannelStore, FluxDispatcher, NavigationRouter, SelectedChannelStore, SelectedGuildStore } from "@webpack/common";
+import { ChannelStore, NavigationRouter, SelectedChannelStore, SelectedGuildStore } from "@webpack/common";
export interface LogoutEvent {
type: "LOGOUT";
@@ -37,63 +37,54 @@ interface PreviousChannel {
channelId: string | null;
}
+let isSwitchingAccount = false;
+let previousCache: PreviousChannel | undefined;
+
+function attemptToNavigateToChannel(guildId: string | null, channelId: string) {
+ if (!ChannelStore.hasChannel(channelId)) return;
+ NavigationRouter.transitionTo(`/channels/${guildId ?? "@me"}/${channelId}`);
+}
export default definePlugin({
name: "KeepCurrentChannel",
description: "Attempt to navigate to the channel you were in before switching accounts or loading Discord.",
authors: [Devs.Nuckyz],
- isSwitchingAccount: false,
- previousCache: {} as PreviousChannel,
+ flux: {
+ LOGOUT(e: LogoutEvent) {
+ ({ isSwitchingAccount } = e);
+ },
- attemptToNavigateToChannel(guildId: string | null, channelId: string) {
- if (!ChannelStore.hasChannel(channelId)) return;
- NavigationRouter.transitionTo(`/channels/${guildId ?? "@me"}/${channelId}`);
- },
+ CONNECTION_OPEN() {
+ if (!isSwitchingAccount) return;
+ isSwitchingAccount = false;
- onLogout(e: LogoutEvent) {
- this.isSwitchingAccount = e.isSwitchingAccount;
- },
-
- onConnectionOpen() {
- if (!this.isSwitchingAccount) return;
- this.isSwitchingAccount = false;
-
- if (this.previousCache.channelId) this.attemptToNavigateToChannel(this.previousCache.guildId, this.previousCache.channelId);
- },
+ if (previousCache?.channelId)
+ attemptToNavigateToChannel(previousCache.guildId, previousCache.channelId);
+ },
- async onChannelSelect({ guildId, channelId }: ChannelSelectEvent) {
- if (this.isSwitchingAccount) return;
+ async CHANNEL_SELECT({ guildId, channelId }: ChannelSelectEvent) {
+ if (isSwitchingAccount) return;
- this.previousCache = {
- guildId,
- channelId
- };
- await DataStore.set("KeepCurrentChannel_previousData", this.previousCache);
+ previousCache = {
+ guildId,
+ channelId
+ };
+ await DataStore.set("KeepCurrentChannel_previousData", previousCache);
+ }
},
async start() {
- const previousData = await DataStore.get<PreviousChannel>("KeepCurrentChannel_previousData");
- if (previousData) {
- this.previousCache = previousData;
-
- if (this.previousCache.channelId) this.attemptToNavigateToChannel(this.previousCache.guildId, this.previousCache.channelId);
- } else {
- this.previousCache = {
+ previousCache = await DataStore.get<PreviousChannel>("KeepCurrentChannel_previousData");
+ if (!previousCache) {
+ previousCache = {
guildId: SelectedGuildStore.getGuildId(),
channelId: SelectedChannelStore.getChannelId() ?? null
};
- await DataStore.set("KeepCurrentChannel_previousData", this.previousCache);
- }
- FluxDispatcher.subscribe("LOGOUT", this.onLogout.bind(this));
- FluxDispatcher.subscribe("CONNECTION_OPEN", this.onConnectionOpen.bind(this));
- FluxDispatcher.subscribe("CHANNEL_SELECT", this.onChannelSelect.bind(this));
- },
-
- stop() {
- FluxDispatcher.unsubscribe("LOGOUT", this.onLogout);
- FluxDispatcher.unsubscribe("CONNECTION_OPEN", this.onConnectionOpen);
- FluxDispatcher.unsubscribe("CHANNEL_SELECT", this.onChannelSelect);
+ await DataStore.set("KeepCurrentChannel_previousData", previousCache);
+ } else if (previousCache.channelId) {
+ attemptToNavigateToChannel(previousCache.guildId, previousCache.channelId);
+ }
}
});
diff --git a/src/plugins/memberCount.tsx b/src/plugins/memberCount.tsx
index 3a68126..0b5409c 100644
--- a/src/plugins/memberCount.tsx
+++ b/src/plugins/memberCount.tsx
@@ -23,7 +23,7 @@ import { getCurrentChannel } from "@utils/discord";
import { useForceUpdater } from "@utils/misc";
import definePlugin from "@utils/types";
import { findStoreLazy } from "@webpack";
-import { FluxDispatcher, Tooltip } from "@webpack/common";
+import { Tooltip } from "@webpack/common";
const counts = {} as Record<string, [number, number]>;
let forceUpdate: () => void;
@@ -107,27 +107,21 @@ export default definePlugin({
}
}],
- onGuildMemberListUpdate({ 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;
+ flux: {
+ 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?.();
}
- counts[guildId] = [memberCount, count];
- forceUpdate?.();
- },
-
- start() {
- FluxDispatcher.subscribe("GUILD_MEMBER_LIST_UPDATE", this.onGuildMemberListUpdate);
- },
-
- stop() {
- FluxDispatcher.unsubscribe("GUILD_MEMBER_LIST_UPDATE", this.onGuildMemberListUpdate);
},
render: () => (
diff --git a/src/plugins/moyai.ts b/src/plugins/moyai.ts
index 146ac3f..b32bd99 100644
--- a/src/plugins/moyai.ts
+++ b/src/plugins/moyai.ts
@@ -21,7 +21,7 @@ import { makeRange } from "@components/PluginSettings/components/SettingSliderCo
import { Devs } from "@utils/constants";
import { sleep } from "@utils/misc";
import definePlugin, { OptionType } from "@utils/types";
-import { FluxDispatcher, SelectedChannelStore, UserStore } from "@webpack/common";
+import { SelectedChannelStore, UserStore } from "@webpack/common";
import { Message, ReactionEmoji } from "discord-types/general";
interface IMessageCreate {
@@ -80,50 +80,40 @@ export default definePlugin({
description: "🗿🗿🗿🗿🗿🗿🗿🗿",
settings,
- async onMessage(e: IMessageCreate) {
- if (e.optimistic || e.type !== "MESSAGE_CREATE") return;
- if (e.message.state === "SENDING") return;
- if (settings.store.ignoreBots && e.message.author?.bot) return;
- if (!e.message.content) return;
- if (e.channelId !== SelectedChannelStore.getChannelId()) return;
+ flux: {
+ async MESSAGE_CREATE({ optimistic, type, message, channelId }: IMessageCreate) {
+ if (optimistic || type !== "MESSAGE_CREATE") return;
+ if (message.state === "SENDING") return;
+ if (settings.store.ignoreBots && message.author?.bot) return;
+ if (!message.content) return;
+ if (channelId !== SelectedChannelStore.getChannelId()) return;
- const moyaiCount = getMoyaiCount(e.message.content);
+ const moyaiCount = getMoyaiCount(message.content);
- for (let i = 0; i < moyaiCount; i++) {
- boom();
- await sleep(300);
- }
- },
+ for (let i = 0; i < moyaiCount; i++) {
+ boom();
+ await sleep(300);
+ }
+ },
- onReaction(e: IReactionAdd) {
- if (e.optimistic || e.type !== "MESSAGE_REACTION_ADD") return;
- if (settings.store.ignoreBots && UserStore.getUser(e.userId)?.bot) return;
- if (e.channelId !== SelectedChannelStore.getChannelId()) return;
-
- const name = e.emoji.name.toLowerCase();
- if (name !== MOYAI && !name.includes("moyai") && !name.includes("moai")) return;
-
- boom();
- },
+ MESSAGE_REACTION_ADD({ optimistic, type, channelId, userId, emoji }: IReactionAdd) {
+ if (optimistic || type !== "MESSAGE_REACTION_ADD") return;
+ if (settings.store.ignoreBots && UserStore.getUser(userId)?.bot) return;
+ if (channelId !== SelectedChannelStore.getChannelId()) return;
- onVoiceChannelEffect(e: IVoiceChannelEffectSendEvent) {
- if (!e.emoji?.name) return;
- const name = e.emoji.name.toLowerCase();
- if (name !== MOYAI && !name.includes("moyai") && !name.includes("moai")) return;
+ const name = emoji.name.toLowerCase();
+ if (name !== MOYAI && !name.includes("moyai") && !name.includes("moai")) return;
- boom();
- },
+ boom();
+ },
- start() {
- FluxDispatcher.subscribe("MESSAGE_CREATE", this.onMessage);
- FluxDispatcher.subscribe("MESSAGE_REACTION_ADD", this.onReaction);
- FluxDispatcher.subscribe("VOICE_CHANNEL_EFFECT_SEND", this.onVoiceChannelEffect);
- },
+ VOICE_CHANNEL_EFFECT_SEND({ emoji }: IVoiceChannelEffectSendEvent) {
+ if (!emoji?.name) return;
+ const name = emoji.name.toLowerCase();
+ if (name !== MOYAI && !name.includes("moyai") && !name.includes("moai")) return;
- stop() {
- FluxDispatcher.unsubscribe("MESSAGE_CREATE", this.onMessage);
- FluxDispatcher.unsubscribe("MESSAGE_REACTION_ADD", this.onReaction);
- FluxDispatcher.unsubscribe("VOICE_CHANNEL_EFFECT_SEND", this.onVoiceChannelEffect);
+ boom();
+ }
}
});
diff --git a/src/plugins/relationshipNotifier/events.ts b/src/plugins/relationshipNotifier/events.ts
deleted file mode 100644
index 0c6914d..0000000
--- a/src/plugins/relationshipNotifier/events.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Vencord, a modification for Discord's desktop app
- * Copyright (c) 2023 Vendicated and contributors
- *
- * 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 <https://www.gnu.org/licenses/>.
-*/
-
-import { FluxEvents } from "@webpack/types";
-
-import { onChannelDelete, onGuildDelete, onRelationshipRemove } from "./functions";
-import { syncAndRunChecks, syncFriends, syncGroups, syncGuilds } from "./utils";
-
-export const FluxHandlers: Partial<Record<FluxEvents, Array<(data: any) => void>>> = {
- GUILD_CREATE: [syncGuilds],
- GUILD_DELETE: [onGuildDelete],
- CHANNEL_CREATE: [syncGroups],
- CHANNEL_DELETE: [onChannelDelete],
- RELATIONSHIP_ADD: [syncFriends],
- RELATIONSHIP_UPDATE: [syncFriends],
- RELATIONSHIP_REMOVE: [syncFriends, onRelationshipRemove],
- CONNECTION_OPEN: [syncAndRunChecks]
-};
-
-export function forEachEvent(fn: (event: FluxEvents, handler: (data: any) => void) => void) {
- for (const event in FluxHandlers) {
- for (const cb of FluxHandlers[event]) {
- fn(event as FluxEvents, cb);
- }
- }
-}
diff --git a/src/plugins/relationshipNotifier/index.ts b/src/plugins/relationshipNotifier/index.ts
index 6319142..7300fba 100644
--- a/src/plugins/relationshipNotifier/index.ts
+++ b/src/plugins/relationshipNotifier/index.ts
@@ -18,12 +18,10 @@
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
-import { FluxDispatcher } from "@webpack/common";
-import { forEachEvent } from "./events";
-import { removeFriend, removeGroup, removeGuild } from "./functions";
+import { onChannelDelete, onGuildDelete, onRelationshipRemove, removeFriend, removeGroup, removeGuild } from "./functions";
import settings from "./settings";
-import { syncAndRunChecks } from "./utils";
+import { syncAndRunChecks, syncFriends, syncGroups, syncGuilds } from "./utils";
export default definePlugin({
name: "RelationshipNotifier",
@@ -55,15 +53,24 @@ export default definePlugin({
}
],
+ flux: {
+ GUILD_CREATE: syncGuilds,
+ GUILD_DELETE: onGuildDelete,
+ CHANNEL_CREATE: syncGroups,
+ CHANNEL_DELETE: onChannelDelete,
+ RELATIONSHIP_ADD: syncFriends,
+ RELATIONSHIP_UPDATE: syncFriends,
+ RELATIONSHIP_REMOVE(e) {
+ onRelationshipRemove(e);
+ syncFriends();
+ },
+ CONNECTION_OPEN: syncAndRunChecks
+ },
+
async start() {
setTimeout(() => {
syncAndRunChecks();
}, 5000);
- forEachEvent((ev, cb) => FluxDispatcher.subscribe(ev, cb));
- },
-
- stop() {
- forEachEvent((ev, cb) => FluxDispatcher.unsubscribe(ev, cb));
},
removeFriend,
diff --git a/src/plugins/serverListIndicators.tsx b/src/plugins/serverListIndicators.tsx
index e1c0829..ed168b5 100644
--- a/src/plugins/serverListIndicators.tsx
+++ b/src/plugins/serverListIndicators.tsx
@@ -22,7 +22,7 @@ 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";
+import { GuildStore, PresenceStore, RelationshipStore } from "@webpack/common";
enum IndicatorType {
SERVER = 1 << 0,
@@ -71,6 +71,24 @@ function ServersIndicator() {
);
}
+function 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?.();
+}
+
+function handleGuildUpdate() {
+ guildCount = GuildStore.getGuildCount();
+ forceUpdateGuildCount?.();
+}
+
export default definePlugin({
name: "ServerListIndicators",
description: "Add online friend count or server count in the server list",
@@ -99,37 +117,21 @@ export default definePlugin({
</ErrorBoundary>;
},
- 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?.();
+ flux: {
+ PRESENCE_UPDATES: handlePresenceUpdate,
+ GUILD_CREATE: handleGuildUpdate,
+ GUILD_DELETE: handleGuildUpdate,
},
- 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);
+
+ handlePresenceUpdate();
+ 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/plugins/supportHelper.tsx b/src/plugins/supportHelper.tsx
index 21d9059..469b5ae 100644
--- a/src/plugins/supportHelper.tsx
+++ b/src/plugins/supportHelper.tsx
@@ -21,7 +21,7 @@ import { Devs, SUPPORT_CHANNEL_ID } from "@utils/constants";
import { makeCodeblock } from "@utils/misc";
import definePlugin from "@utils/types";
import { isOutdated } from "@utils/updater";
-import { Alerts, FluxDispatcher, Forms, UserStore } from "@webpack/common";
+import { Alerts, Forms, UserStore } from "@webpack/common";
import gitHash from "~git-hash";
import plugins from "~plugins";
@@ -69,18 +69,16 @@ ${makeCodeblock(Object.keys(plugins).filter(Vencord.Plugins.isPluginEnabled).joi
}
}],
- rememberDismiss() {
- DataStore.set(REMEMBER_DISMISS_KEY, gitHash);
- },
-
- start() {
- FluxDispatcher.subscribe("CHANNEL_SELECT", async ({ channelId }) => {
+ flux: {
+ async CHANNEL_SELECT({ channelId }) {
if (channelId !== SUPPORT_CHANNEL_ID) return;
const myId = BigInt(UserStore.getCurrentUser().id);
if (Object.values(Devs).some(d => d.id === myId)) return;
if (isOutdated && gitHash !== await DataStore.get(REMEMBER_DISMISS_KEY)) {
+ const rememberDismiss = () => DataStore.set(REMEMBER_DISMISS_KEY, gitHash);
+
Alerts.show({
title: "Hold on!",
body: <div>
@@ -90,10 +88,10 @@ ${makeCodeblock(Object.keys(plugins).filter(Vencord.Plugins.isPluginEnabled).joi
to do so, in case you can't access the Updater page.
</Forms.FormText>
</div>,
- onCancel: this.rememberDismiss,
- onConfirm: this.rememberDismiss
+ onCancel: rememberDismiss,
+ onConfirm: rememberDismiss
});
}
- });
+ }
}
});
diff --git a/src/plugins/vcNarrator.tsx b/src/plugins/vcNarrator.tsx
index f55f639..a318e89 100644
--- a/src/plugins/vcNarrator.tsx
+++ b/src/plugins/vcNarrator.tsx
@@ -24,7 +24,7 @@ import { Margins } from "@utils/margins";
import { wordsToTitle } from "@utils/text";
import definePlugin, { OptionType, PluginOptionsItem } from "@utils/types";
import { findByPropsLazy } from "@webpack";
-import { Button, ChannelStore, FluxDispatcher, Forms, SelectedChannelStore, useMemo, UserStore } from "@webpack/common";
+import { Button, ChannelStore, Forms, SelectedChannelStore, useMemo, UserStore } from "@webpack/common";
interface VoiceState {
userId: string;
@@ -137,59 +137,61 @@ function updateStatuses(type: string, { deaf, mute, selfDeaf, selfMute, userId,
}
*/
-function handleVoiceStates({ voiceStates }: { voiceStates: VoiceState[]; }) {
- const myChanId = SelectedChannelStore.getVoiceChannelId();
- const myId = UserStore.getCurrentUser().id;
+function playSample(tempSettings: any, type: string) {
+ const settings = Object.assign({}, Settings.plugins.VcNarrator, tempSettings);
- for (const state of voiceStates) {
- const { userId, channelId, oldChannelId } = state;
- const isMe = userId === myId;
- if (!isMe) {
- if (!myChanId) continue;
- if (channelId !== myChanId && oldChannelId !== myChanId) continue;
- }
+ speak(formatText(settings[type + "Message"], UserStore.getCurrentUser().username, "general"), settings);
+}
- const [type, id] = getTypeAndChannelId(state, isMe);
- if (!type) continue;
+export default definePlugin({
+ name: "VcNarrator",
+ description: "Announces when users join, leave, or move voice channels via narrator",
+ authors: [Devs.Ven],
- const template = Settings.plugins.VcNarrator[type + "Message"];
- const user = isMe ? "" : UserStore.getUser(userId).username;
- const channel = ChannelStore.getChannel(id).name;
+ flux: {
+ VOICE_STATE_UPDATES({ voiceStates }: { voiceStates: VoiceState[]; }) {
+ const myChanId = SelectedChannelStore.getVoiceChannelId();
+ const myId = UserStore.getCurrentUser().id;
- speak(formatText(template, user, channel));
+ for (const state of voiceStates) {
+ const { userId, channelId, oldChannelId } = state;
+ const isMe = userId === myId;
+ if (!isMe) {
+ if (!myChanId) continue;
+ if (channelId !== myChanId && oldChannelId !== myChanId) continue;
+ }
- // updateStatuses(type, state, isMe);
- }
-}
+ const [type, id] = getTypeAndChannelId(state, isMe);
+ if (!type) continue;
-function handleToggleSelfMute() {
- const chanId = SelectedChannelStore.getVoiceChannelId()!;
- const s = VoiceStateStore.getVoiceStateForChannel(chanId) as VoiceState;
- if (!s) return;
+ const template = Settings.plugins.VcNarrator[type + "Message"];
+ const user = isMe ? "" : UserStore.getUser(userId).username;
+ const channel = ChannelStore.getChannel(id).name;
- const event = s.mute || s.selfMute ? "unmute" : "mute";
- speak(formatText(Settings.plugins.VcNarrator[event + "Message"], "", ChannelStore.getChannel(chanId).name));
-}
+ speak(formatText(template, user, channel));
-function handleToggleSelfDeafen() {
- const chanId = SelectedChannelStore.getVoiceChannelId()!;
- const s = VoiceStateStore.getVoiceStateForChannel(chanId) as VoiceState;
- if (!s) return;
+ // updateStatuses(type, state, isMe);
+ }
+ },
- const event = s.deaf || s.selfDeaf ? "undeafen" : "deafen";
- speak(formatText(Settings.plugins.VcNarrator[event + "Message"], "", ChannelStore.getChannel(chanId).name));
-}
+ AUDIO_TOGGLE_SELF_MUTE() {
+ const chanId = SelectedChannelStore.getVoiceChannelId()!;
+ const s = VoiceStateStore.getVoiceStateForChannel(chanId) as VoiceState;
+ if (!s) return;
-function playSample(tempSettings: any, type: string) {
- const settings = Object.assign({}, Settings.plugins.VcNarrator, tempSettings);
+ const event = s.mute || s.selfMute ? "unmute" : "mute";
+ speak(formatText(Settings.plugins.VcNarrator[event + "Message"], "", ChannelStore.getChannel(chanId).name));
+ },
- speak(formatText(settings[type + "Message"], UserStore.getCurrentUser().username, "general"), settings);
-}
+ AUDIO_TOGGLE_SELF_DEAF() {
+ const chanId = SelectedChannelStore.getVoiceChannelId()!;
+ const s = VoiceStateStore.getVoiceStateForChannel(chanId) as VoiceState;
+ if (!s) return;
-export default definePlugin({
- name: "VcNarrator",
- description: "Announces when users join, leave, or move voice channels via narrator",
- authors: [Devs.Ven],
+ const event = s.deaf || s.selfDeaf ? "undeafen" : "deafen";
+ speak(formatText(Settings.plugins.VcNarrator[event + "Message"], "", ChannelStore.getChannel(chanId).name));
+ }
+ },
start() {
if (typeof speechSynthesis === "undefined" || speechSynthesis.getVoices().length === 0) {
@@ -199,15 +201,6 @@ export default definePlugin({
return;
}
- FluxDispatcher.subscribe("VOICE_STATE_UPDATES", handleVoiceStates);
- FluxDispatcher.subscribe("AUDIO_TOGGLE_SELF_MUTE", handleToggleSelfMute);
- FluxDispatcher.subscribe("AUDIO_TOGGLE_SELF_DEAF", handleToggleSelfDeafen);
- },
-
- stop() {
- FluxDispatcher.unsubscribe("VOICE_STATE_UPDATES", handleVoiceStates);
- FluxDispatcher.subscribe("AUDIO_TOGGLE_SELF_MUTE", handleToggleSelfMute);
- FluxDispatcher.subscribe("AUDIO_TOGGLE_SELF_DEAF", handleToggleSelfDeafen);
},
optionsCache: null as Record<string, PluginOptionsItem> | null,
diff --git a/src/utils/types.ts b/src/utils/types.ts
index 54c9674..d2b5e0e 100644
--- a/src/utils/types.ts
+++ b/src/utils/types.ts
@@ -17,6 +17,7 @@
*/
import { Command } from "@api/Commands";
+import { FluxEvents } from "@webpack/types";
import { Promisable } from "type-fest";
// exists to export default definePlugin({...})
@@ -101,6 +102,12 @@ export interface PluginDef {
settingsAboutComponent?: React.ComponentType<{
tempSettings?: Record<string, any>;
}>;
+ /**
+ * Allows you to subscribe to Flux events
+ */
+ flux?: {
+ [E in FluxEvents]?: (event: any) => void;
+ };
}
export enum OptionType {