diff --git a/package.json b/package.json index bfdaf9c7..9b4067d4 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "zip-local": "^0.3.5", "zustand": "^3.7.2" }, - "packageManager": "pnpm@8.10.2", + "packageManager": "pnpm@9.1.0", "pnpm": { "patchedDependencies": { "eslint@8.46.0": "patches/eslint@8.46.0.patch", diff --git a/scripts/build/common.mjs b/scripts/build/common.mjs index f50cc2ea..d4a43d68 100644 --- a/scripts/build/common.mjs +++ b/scripts/build/common.mjs @@ -25,10 +25,11 @@ import { access, readdir, readFile } from "fs/promises"; import { join, relative } from "path"; import { promisify } from "util"; -// wtf is this assert syntax -import PackageJSON from "../../package.json" assert { type: "json" }; import { getPluginTarget } from "../utils.mjs"; +/** @type {import("../../package.json")} */ +const PackageJSON = JSON.parse(readFileSync("package.json")); + export const VERSION = PackageJSON.version; // https://reproducible-builds.org/docs/source-date-epoch/ export const BUILD_TIMESTAMP = Number(process.env.SOURCE_DATE_EPOCH) || Date.now(); diff --git a/src/plugins/fakeNitro/index.tsx b/src/plugins/fakeNitro/index.tsx index 17ce9700..e40eb73f 100644 --- a/src/plugins/fakeNitro/index.tsx +++ b/src/plugins/fakeNitro/index.tsx @@ -166,10 +166,13 @@ const settings = definePluginSettings({ description: "What text the hyperlink should use. {{NAME}} will be replaced with the emoji/sticker name.", type: OptionType.STRING, default: "{{NAME}}" + }, + disableEmbedPermissionCheck: { + description: "Whether to disable the embed permission check when sending fake emojis and stickers", + type: OptionType.BOOLEAN, + default: false } -}).withPrivateSettings<{ - disableEmbedPermissionCheck: boolean; -}>(); +}); function hasPermission(channelId: string, permission: bigint) { const channel = ChannelStore.getChannel(channelId); @@ -397,6 +400,14 @@ export default definePlugin({ match: /(?<=type:"(?:SOUNDBOARD_SOUNDS_RECEIVED|GUILD_SOUNDBOARD_SOUND_CREATE|GUILD_SOUNDBOARD_SOUND_UPDATE|GUILD_SOUNDBOARD_SOUNDS_UPDATE)".+?available:)\i\.available/g, replace: "true" } + }, + // Allow using custom notification sounds + { + find: "canUseCustomNotificationSounds:function", + replacement: { + match: /canUseCustomNotificationSounds:function\(\i\){/, + replace: "$&return true;" + } } ], diff --git a/src/plugins/index.ts b/src/plugins/index.ts index 2d5e3e5a..488847d1 100644 --- a/src/plugins/index.ts +++ b/src/plugins/index.ts @@ -36,6 +36,7 @@ export const patches = [] as Patch[]; /** Whether we have subscribed to flux events of all the enabled plugins when FluxDispatcher was ready */ let enabledPluginsSubscribedFlux = false; +const subscribedFluxEventsPlugins = new Set(); const settings = Settings.plugins; @@ -123,7 +124,9 @@ export function startDependenciesRecursive(p: Plugin) { } export function subscribePluginFluxEvents(p: Plugin, fluxDispatcher: typeof FluxDispatcher) { - if (p.flux) { + if (p.flux && !subscribedFluxEventsPlugins.has(p.name)) { + subscribedFluxEventsPlugins.add(p.name); + logger.debug("Subscribing to flux events of plugin", p.name); for (const [event, handler] of Object.entries(p.flux)) { fluxDispatcher.subscribe(event as FluxEvents, handler); @@ -133,6 +136,8 @@ export function subscribePluginFluxEvents(p: Plugin, fluxDispatcher: typeof Flux export function unsubscribePluginFluxEvents(p: Plugin, fluxDispatcher: typeof FluxDispatcher) { if (p.flux) { + subscribedFluxEventsPlugins.delete(p.name); + 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); diff --git a/src/webpack/common/stores.ts b/src/webpack/common/stores.ts index 8e8be97d..06e0117f 100644 --- a/src/webpack/common/stores.ts +++ b/src/webpack/common/stores.ts @@ -64,23 +64,15 @@ export let DraftStore: t.DraftStore; /** * React hook that returns stateful data for one or more stores * You might need a custom comparator (4th argument) if your store data is an object - * * @param stores The stores to listen to * @param mapper A function that returns the data you need - * @param idk some thing, idk just pass null + * @param dependencies An array of reactive values which the hook depends on. Use this if your mapper or equality function depends on the value of another hook * @param isEqual A custom comparator for the data returned by mapper * * @example const user = useStateFromStores([UserStore], () => UserStore.getCurrentUser(), null, (old, current) => old.id === current.id); */ -export const { useStateFromStores }: { - useStateFromStores: ( - stores: t.FluxStore[], - mapper: () => T, - idk?: any, - isEqual?: (old: T, newer: T) => boolean - ) => T; -} - = findByPropsLazy("useStateFromStores"); +// eslint-disable-next-line prefer-destructuring +export const useStateFromStores: t.useStateFromStores = findByPropsLazy("useStateFromStores").useStateFromStores; waitForStore("DraftStore", s => DraftStore = s); waitForStore("UserStore", s => UserStore = s); diff --git a/src/webpack/common/types/stores.d.ts b/src/webpack/common/types/stores.d.ts index 8e89a6e2..d6bf3aaf 100644 --- a/src/webpack/common/types/stores.d.ts +++ b/src/webpack/common/types/stores.d.ts @@ -182,3 +182,10 @@ export class GuildStore extends FluxStore { getRoles(guildId: string): Record; getAllGuildRoles(): Record>; } + +export type useStateFromStores = ( + stores: t.FluxStore[], + mapper: () => T, + dependencies?: any, + isEqual?: (old: T, newer: T) => boolean +) => T; diff --git a/tsconfig.json b/tsconfig.json index 3588b8e7..4db1319e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "resolveJsonModule": true, "allowSyntheticDefaultImports": true, "esModuleInterop": true, "skipLibCheck": true,