Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
thororen1234 2025-09-25 11:01:23 -04:00
commit 0c37204b68
No known key found for this signature in database
8 changed files with 45 additions and 17 deletions

View file

@ -6,15 +6,17 @@ import type { FluxEvents } from "./fluxEvents";
export { FluxEvents };
type FluxEventsAutoComplete = LiteralUnion<FluxEvents, string>;
export interface FluxDispatcher {
_actionHandlers: any;
_interceptors: any;
_subscriptions: any;
addInterceptor(interceptor: any): void;
dispatch(event: { [key: string]: unknown; type: FluxEvents; }): Promise<void>;
dispatch(event: { [key: string]: unknown; type: FluxEventsAutoComplete; }): Promise<void>;
isDispatching(): boolean;
subscribe(event: FluxEvents, callback: (data: any) => void): void;
unsubscribe(event: FluxEvents, callback: (data: any) => void): void;
subscribe(event: FluxEventsAutoComplete, callback: (data: any) => void): void;
unsubscribe(event: FluxEventsAutoComplete, callback: (data: any) => void): void;
wait(callback: () => void): void;
}

View file

@ -71,6 +71,15 @@ export default definePlugin({
}
],
// The TRACK event takes an optional `resolve` property that is called when the tracking event was submitted to the server.
// A few spots in Discord await this callback before continuing (most notably the Voice Debug Logging toggle).
// Since we NOOP the AnalyticsActionHandlers module, there is no handler for the TRACK event, so we have to handle it ourselves
flux: {
TRACK(event) {
event?.resolve?.();
}
},
startAt: StartAt.Init,
start() {
// Sentry is initialized in its own WebpackInstance.

View file

@ -21,24 +21,39 @@ import { findComponentByCodeLazy, findStoreLazy } from "@webpack";
import { Animations, useStateFromStores } from "@webpack/common";
import type { CSSProperties } from "react";
import { ExpandedGuildFolderStore, settings } from ".";
import { ExpandedGuildFolderStore, settings, SortedGuildStore } from ".";
const ChannelRTCStore = findStoreLazy("ChannelRTCStore");
const GuildsBar = findComponentByCodeLazy('("guildsnav")');
function getExpandedFolderIds() {
const expandedFolders = ExpandedGuildFolderStore.getExpandedFolders();
const folders = SortedGuildStore.getGuildFolders();
const expandedFolderIds = new Set<string>();
for (const folder of folders) {
if (expandedFolders.has(folder.folderId) && folder.guildIds?.length) {
expandedFolderIds.add(folder.folderId);
}
}
return expandedFolderIds;
}
export default ErrorBoundary.wrap(guildsBarProps => {
const expandedFolders = useStateFromStores([ExpandedGuildFolderStore], () => ExpandedGuildFolderStore.getExpandedFolders());
const expandedFolderIds = useStateFromStores([ExpandedGuildFolderStore, SortedGuildStore], () => getExpandedFolderIds());
const isFullscreen = useStateFromStores([ChannelRTCStore], () => ChannelRTCStore.isFullscreenInContext());
const Sidebar = (
<GuildsBar
{...guildsBarProps}
isBetterFolders={true}
betterFoldersExpandedIds={expandedFolders}
betterFoldersExpandedIds={expandedFolderIds}
/>
);
const visible = !!expandedFolders.size;
const visible = !!expandedFolderIds.size;
const guilds = document.querySelector(guildsBarProps.className.split(" ").map(c => `.${c}`).join(""));
// We need to display none if we are in fullscreen. Yes this seems horrible doing with css, but it's literally how Discord does it.

View file

@ -34,7 +34,7 @@ enum FolderIconDisplay {
}
export const ExpandedGuildFolderStore = findStoreLazy("ExpandedGuildFolderStore");
const SortedGuildStore = findStoreLazy("SortedGuildStore");
export const SortedGuildStore = findStoreLazy("SortedGuildStore");
const FolderUtils = findByPropsLazy("move", "toggleGuildFolderExpand");
let lastGuildId = null as string | null;

View file

@ -60,7 +60,7 @@ function makeIcon(showCurrentGame?: boolean) {
};
}
function GameActivityToggleButton() {
function GameActivityToggleButton(props: { nameplate?: any; }) {
const showCurrentGame = ShowCurrentGame.useSetting();
return (
@ -71,6 +71,7 @@ function GameActivityToggleButton() {
role="switch"
aria-checked={!showCurrentGame}
redGlow={!showCurrentGame}
plated={props?.nameplate != null}
onClick={() => ShowCurrentGame.updateSetting(old => !old)}
/>
);
@ -98,7 +99,7 @@ export default definePlugin({
find: "#{intl::ACCOUNT_SPEAKING_WHILE_MUTED}",
replacement: {
match: /className:\i\.buttons,.{0,50}children:\[/,
replace: "$&$self.GameActivityToggleButton(),"
replace: "$&$self.GameActivityToggleButton(arguments[0]),"
}
}
],

View file

@ -233,7 +233,7 @@ export function subscribePluginFluxEvents(p: Plugin, fluxDispatcher: typeof Flux
const wrappedHandler = p.flux[event] = function () {
if (p.name === "Encryptcord" && event === "MESSAGE_CREATE") return;
try {
const res = handler.apply(p, arguments as any);
const res = handler!.apply(p, arguments as any);
return res instanceof Promise
? res.catch(e => logger.error(`${p.name}: Error while handling ${event}\n`, e))
: res;
@ -253,7 +253,7 @@ export function unsubscribePluginFluxEvents(p: Plugin, fluxDispatcher: typeof Fl
logger.debug("Unsubscribing from flux events of plugin", p.name);
for (const [event, handler] of Object.entries(p.flux)) {
fluxDispatcher.unsubscribe(event as FluxEvents, handler);
fluxDispatcher.unsubscribe(event as FluxEvents, handler!);
}
}
}

View file

@ -27,7 +27,7 @@ import { classes } from "@utils/misc";
import definePlugin, { OptionType } from "@utils/types";
import { User } from "@vencord/discord-types";
import { filters, findStoreLazy, mapMangledModuleLazy } from "@webpack";
import { PresenceStore, Tooltip, UserStore, useStateFromStores } from "@webpack/common";
import { AuthenticationStore, PresenceStore, Tooltip, UserStore, useStateFromStores } from "@webpack/common";
export interface Session {
sessionId: string;
@ -113,7 +113,7 @@ const PlatformIcon = ({ platform, status, small }: PlatformIconProps) => {
};
function useEnsureOwnStatus(user: User) {
if (user.id !== UserStore.getCurrentUser()?.id) {
if (user.id !== AuthenticationStore.getId()) {
return;
}

View file

@ -27,6 +27,7 @@ import { MessagePopoverButtonFactory } from "@api/MessagePopover";
import { NicknameIconFactory } from "@api/NicknameIcons";
import { Command, FluxEvents } from "@vencord/discord-types";
import { ReactNode } from "react";
import { LiteralUnion } from "type-fest";
// exists to export default definePlugin({...})
export default function definePlugin<P extends PluginDef>(p: P & Record<PropertyKey, any>) {
@ -151,9 +152,9 @@ export interface PluginDef {
/**
* Allows you to subscribe to Flux events
*/
flux?: {
[E in FluxEvents]?: (event: any) => void | Promise<void>;
};
flux?: Partial<{
[E in LiteralUnion<FluxEvents, string>]: (event: any) => void | Promise<void>;
}>;
/**
* Allows you to manipulate context menus
*/