Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
214c101740 | ||
|
5a0e501829 | ||
|
92113da7c0 | ||
|
96f30a5359 | ||
|
ceb1f15188 | ||
|
626eb3613e | ||
|
3020fcc9bb | ||
|
bc0de3926c | ||
|
9820b79dfe | ||
|
ab811470fc | ||
|
e4162e7bd5 |
@ -39,10 +39,9 @@ Or use the [UserScript](https://raw.githubusercontent.com/Vencord/builds/main/Ve
|
|||||||
## Vencord Desktop
|
## Vencord Desktop
|
||||||
|
|
||||||
> **Warning**
|
> **Warning**
|
||||||
> This is an alternative app. It currently doesn't support screensharing or keybinds. If you just want to install to the normal Discord Desktop app, scroll up
|
> This is an alternative app. It currently doesn't support keybinds and possibly some more features. If you just want to install to the normal Discord Desktop app, scroll up
|
||||||
|
|
||||||
|
As an alternative to the Discord Desktop app, Vencord also has its own standalone Desktop app that is snappier and lighter than Discord's official Desktop app
|
||||||
As an alternative to the Discord Desktop app, Vencord also has its own standalone Desktop app that is snappier and lighter than Discord's official Desktop app. It is currently in beta and we have yet to implement some features like screensharing, but you can try the beta nonetheless
|
|
||||||
|
|
||||||
[![Download Vencord Desktop](https://img.shields.io/github/v/release/Vencord/Desktop?label=Download%20Vencord%20Desktop&style=for-the-badge)](https://github.com/Vencord/Desktop#vencord-desktop)
|
[![Download Vencord Desktop](https://img.shields.io/github/v/release/Vencord/Desktop?label=Download%20Vencord%20Desktop&style=for-the-badge)](https://github.com/Vencord/Desktop#vencord-desktop)
|
||||||
|
|
||||||
@ -50,7 +49,7 @@ As an alternative to the Discord Desktop app, Vencord also has its own standalon
|
|||||||
|
|
||||||
## Join our Support/Community Server
|
## Join our Support/Community Server
|
||||||
|
|
||||||
[![Vencord Discord Server](https://invidget.switchblade.xyz/D9uwnFnqmd?theme=dark)](https://discord.gg/D9uwnFnqmd)
|
https://discord.gg/D9uwnFnqmd
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "vencord",
|
"name": "vencord",
|
||||||
"private": "true",
|
"private": "true",
|
||||||
"version": "1.2.8",
|
"version": "1.2.9",
|
||||||
"description": "The cutest Discord client mod",
|
"description": "The cutest Discord client mod",
|
||||||
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
|
@ -254,8 +254,12 @@ export function migratePluginSettings(name: string, ...oldNames: string[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function definePluginSettings<D extends SettingsDefinition, C extends SettingsChecks<D>>(def: D, checks?: C) {
|
export function definePluginSettings<
|
||||||
const definedSettings: DefinedSettings<D> = {
|
Def extends SettingsDefinition,
|
||||||
|
Checks extends SettingsChecks<Def>,
|
||||||
|
PrivateSettings extends object = {}
|
||||||
|
>(def: Def, checks?: Checks) {
|
||||||
|
const definedSettings: DefinedSettings<Def, Checks, PrivateSettings> = {
|
||||||
get store() {
|
get store() {
|
||||||
if (!definedSettings.pluginName) throw new Error("Cannot access settings before plugin is initialized");
|
if (!definedSettings.pluginName) throw new Error("Cannot access settings before plugin is initialized");
|
||||||
return Settings.plugins[definedSettings.pluginName] as any;
|
return Settings.plugins[definedSettings.pluginName] as any;
|
||||||
@ -264,11 +268,11 @@ export function definePluginSettings<D extends SettingsDefinition, C extends Set
|
|||||||
settings?.map(name => `plugins.${definedSettings.pluginName}.${name}`) as UseSettings<Settings>[]
|
settings?.map(name => `plugins.${definedSettings.pluginName}.${name}`) as UseSettings<Settings>[]
|
||||||
).plugins[definedSettings.pluginName] as any,
|
).plugins[definedSettings.pluginName] as any,
|
||||||
def,
|
def,
|
||||||
checks: checks ?? {},
|
checks: checks ?? {} as any,
|
||||||
pluginName: "",
|
pluginName: "",
|
||||||
|
|
||||||
withPrivateSettings<T>() {
|
withPrivateSettings<T extends object>() {
|
||||||
return this as DefinedSettings<D, C> & { store: T; };
|
return this as DefinedSettings<Def, Checks, T>;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,7 +36,8 @@ function Guilds(props: {
|
|||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
const res = Vencord.Plugins.plugins.BetterFolders.Guilds(props);
|
const res = Vencord.Plugins.plugins.BetterFolders.Guilds(props);
|
||||||
|
|
||||||
const scrollerProps = res.props.children?.props?.children?.[1]?.props;
|
// TODO: Make this better
|
||||||
|
const scrollerProps = res.props.children?.props?.children?.props?.children?.[1]?.props;
|
||||||
if (scrollerProps?.children) {
|
if (scrollerProps?.children) {
|
||||||
const servers = scrollerProps.children.find(c => c?.props?.["aria-label"] === i18n.Messages.SERVERS);
|
const servers = scrollerProps.children.find(c => c?.props?.["aria-label"] === i18n.Messages.SERVERS);
|
||||||
if (servers) scrollerProps.children = servers;
|
if (servers) scrollerProps.children = servers;
|
||||||
|
@ -78,7 +78,7 @@ export default definePlugin({
|
|||||||
</Avatar>
|
</Avatar>
|
||||||
<div className={ProfileListClasses.listRowContent}>
|
<div className={ProfileListClasses.listRowContent}>
|
||||||
<div className={ProfileListClasses.listName}>{getGroupDMName(c)}</div>
|
<div className={ProfileListClasses.listName}>{getGroupDMName(c)}</div>
|
||||||
<div className={GuildLabelClasses.guildNick}>{c.recipients.length} Members</div>
|
<div className={GuildLabelClasses.guildNick}>{c.recipients.length + 1} Members</div>
|
||||||
</div>
|
</div>
|
||||||
</Clickable>
|
</Clickable>
|
||||||
));
|
));
|
||||||
|
@ -23,6 +23,7 @@ import { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, Mod
|
|||||||
import { ContextMenu, FluxDispatcher, GuildMemberStore, Menu, PermissionsBits, Text, Tooltip, useEffect, UserStore, useState, useStateFromStores } from "@webpack/common";
|
import { ContextMenu, FluxDispatcher, GuildMemberStore, Menu, PermissionsBits, Text, Tooltip, useEffect, UserStore, useState, useStateFromStores } from "@webpack/common";
|
||||||
import type { Guild } from "discord-types/general";
|
import type { Guild } from "discord-types/general";
|
||||||
|
|
||||||
|
import { settings } from "..";
|
||||||
import { cl, getPermissionDescription, getPermissionString } from "../utils";
|
import { cl, getPermissionDescription, getPermissionString } from "../utils";
|
||||||
import { PermissionAllowedIcon, PermissionDefaultIcon, PermissionDeniedIcon } from "./icons";
|
import { PermissionAllowedIcon, PermissionDefaultIcon, PermissionDeniedIcon } from "./icons";
|
||||||
|
|
||||||
@ -108,7 +109,7 @@ function RolesAndUsersPermissionsComponent({ permissions, guild, modalProps, hea
|
|||||||
<div
|
<div
|
||||||
className={cl("perms-list-item", { "perms-list-item-active": selectedItemIndex === index })}
|
className={cl("perms-list-item", { "perms-list-item-active": selectedItemIndex === index })}
|
||||||
onContextMenu={e => {
|
onContextMenu={e => {
|
||||||
if (permission.type === PermissionType.Role)
|
if ((settings.store as any).unsafeViewAsRole && permission.type === PermissionType.Role)
|
||||||
ContextMenu.open(e, () => (
|
ContextMenu.open(e, () => (
|
||||||
<RoleContextMenu
|
<RoleContextMenu
|
||||||
guild={guild}
|
guild={guild}
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
grid-area: list;
|
grid-area: list;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
gap: 2px;
|
||||||
border-right: 2px solid var(--background-modifier-active);
|
border-right: 2px solid var(--background-modifier-active);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,6 +78,15 @@
|
|||||||
padding: 8px 5px;
|
padding: 8px 5px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 230px;
|
width: 230px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-permviewer-perms-list-item:hover {
|
||||||
|
background-color: var(--background-modifier-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-permviewer-perms-list-item-active {
|
||||||
|
background-color: var(--background-modifier-selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-permviewer-perms-list-item > div {
|
.vc-permviewer-perms-list-item > div {
|
||||||
@ -85,11 +95,6 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-permviewer-perms-list-item-active {
|
|
||||||
background-color: var(--background-modifier-selected);
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vc-permviewer-perms-role-circle {
|
.vc-permviewer-perms-role-circle {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
width: 12px;
|
width: 12px;
|
||||||
|
@ -52,7 +52,7 @@ export default definePlugin({
|
|||||||
find: ".userTagNoNickname",
|
find: ".userTagNoNickname",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /=(\i)\.pronouns/,
|
match: /=(\i)\.pronouns/,
|
||||||
replace: "=$self.useProfilePronouns($1.user.id)"
|
replace: "=$self.useProfilePronouns($1.user.id,$1.pronouns)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Patch the profile modal username header to use our pronoun hook instead of Discord's pronouns
|
// Patch the profile modal username header to use our pronoun hook instead of Discord's pronouns
|
||||||
@ -60,7 +60,7 @@ export default definePlugin({
|
|||||||
find: ".USER_PROFILE_ACTIVITY",
|
find: ".USER_PROFILE_ACTIVITY",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\).showPronouns/,
|
match: /\).showPronouns/,
|
||||||
replace: ").showPronouns||true;const vcPronounce=$self.useProfilePronouns(arguments[0].user.id);if(arguments[0].displayProfile)arguments[0].displayProfile.pronouns=vcPronounce"
|
replace: ").showPronouns||true;const vcPronounce=$self.useProfilePronouns(arguments[0].user.id,arguments[0].displayProfile?.pronouns);if(arguments[0].displayProfile&&vcPronounce)arguments[0].displayProfile.pronouns=vcPronounce"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -19,17 +19,26 @@
|
|||||||
import { Settings } from "@api/Settings";
|
import { Settings } from "@api/Settings";
|
||||||
import { VENCORD_USER_AGENT } from "@utils/constants";
|
import { VENCORD_USER_AGENT } from "@utils/constants";
|
||||||
import { debounce } from "@utils/debounce";
|
import { debounce } from "@utils/debounce";
|
||||||
|
import { getCurrentChannel } from "@utils/discord";
|
||||||
import { useAwaiter } from "@utils/react";
|
import { useAwaiter } from "@utils/react";
|
||||||
|
import { findStoreLazy } from "@webpack";
|
||||||
import { UserStore } from "@webpack/common";
|
import { UserStore } from "@webpack/common";
|
||||||
|
|
||||||
import { settings } from "./settings";
|
import { settings } from "./settings";
|
||||||
import { PronounCode, PronounMapping, PronounsResponse } from "./types";
|
import { PronounCode, PronounMapping, PronounsResponse } from "./types";
|
||||||
|
|
||||||
|
const UserProfileStore = findStoreLazy("UserProfileStore");
|
||||||
|
|
||||||
export const enum PronounsFormat {
|
export const enum PronounsFormat {
|
||||||
Lowercase = "LOWERCASE",
|
Lowercase = "LOWERCASE",
|
||||||
Capitalized = "CAPITALIZED"
|
Capitalized = "CAPITALIZED"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const enum PronounSource {
|
||||||
|
PreferPDB,
|
||||||
|
PreferDiscord
|
||||||
|
}
|
||||||
|
|
||||||
// A map of cached pronouns so the same request isn't sent twice
|
// A map of cached pronouns so the same request isn't sent twice
|
||||||
const cache: Record<string, PronounCode> = {};
|
const cache: Record<string, PronounCode> = {};
|
||||||
// A map of ids and callbacks that should be triggered on fetch
|
// A map of ids and callbacks that should be triggered on fetch
|
||||||
@ -46,21 +55,29 @@ const bulkFetch = debounce(async () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export function useFormattedPronouns(id: string): string | null {
|
function getDiscordPronouns(id: string) {
|
||||||
const [result] = useAwaiter(() => fetchPronouns(id), {
|
return (
|
||||||
fallbackValue: getCachedPronouns(id),
|
UserProfileStore.getGuildMemberProfile(id, getCurrentChannel()?.guild_id)?.pronouns
|
||||||
|
|| UserProfileStore.getUserProfile(id)?.pronouns
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useFormattedPronouns(id: string, discordPronouns: string = getDiscordPronouns(id)): string | null {
|
||||||
|
const [result] = useAwaiter(() => fetchPronouns(id, discordPronouns), {
|
||||||
|
fallbackValue: getCachedPronouns(id, discordPronouns),
|
||||||
onError: e => console.error("Fetching pronouns failed: ", e)
|
onError: e => console.error("Fetching pronouns failed: ", e)
|
||||||
});
|
});
|
||||||
|
|
||||||
// If the result is present and not "unspecified", and there is a mapping for the code, then return the mappings
|
if (result && result !== "unspecified")
|
||||||
if (result && result !== "unspecified" && PronounMapping[result])
|
return Object.hasOwn(PronounMapping, result)
|
||||||
return formatPronouns(result);
|
? formatPronouns(result) // PronounDB
|
||||||
|
: result; // Discord
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useProfilePronouns(id: string) {
|
export function useProfilePronouns(id: string, discordPronouns: string) {
|
||||||
const pronouns = useFormattedPronouns(id);
|
const pronouns = useFormattedPronouns(id, discordPronouns);
|
||||||
|
|
||||||
if (!settings.store.showInProfile) return null;
|
if (!settings.store.showInProfile) return null;
|
||||||
if (!settings.store.showSelf && id === UserStore.getCurrentUser().id) return null;
|
if (!settings.store.showSelf && id === UserStore.getCurrentUser().id) return null;
|
||||||
@ -70,22 +87,28 @@ export function useProfilePronouns(id: string) {
|
|||||||
|
|
||||||
|
|
||||||
// Gets the cached pronouns, if you're too impatient for a promise!
|
// Gets the cached pronouns, if you're too impatient for a promise!
|
||||||
export function getCachedPronouns(id: string): PronounCode | null {
|
export function getCachedPronouns(id: string, discordPronouns: string): string | null {
|
||||||
return cache[id] ?? null;
|
if (settings.store.pronounSource === PronounSource.PreferDiscord && discordPronouns)
|
||||||
|
return discordPronouns;
|
||||||
|
|
||||||
|
const cached = cache[id];
|
||||||
|
if (cached && cached !== "unspecified") return cached;
|
||||||
|
|
||||||
|
return discordPronouns || cached || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetches the pronouns for one id, returning a promise that resolves if it was cached, or once the request is completed
|
// Fetches the pronouns for one id, returning a promise that resolves if it was cached, or once the request is completed
|
||||||
export function fetchPronouns(id: string): Promise<PronounCode> {
|
export function fetchPronouns(id: string, discordPronouns: string): Promise<string> {
|
||||||
return new Promise(res => {
|
return new Promise(res => {
|
||||||
// If cached, return the cached pronouns
|
const cached = getCachedPronouns(id, discordPronouns);
|
||||||
if (id in cache) res(getCachedPronouns(id)!);
|
if (cached) return res(cached);
|
||||||
|
|
||||||
// If there is already a request added, then just add this callback to it
|
// If there is already a request added, then just add this callback to it
|
||||||
else if (id in requestQueue) requestQueue[id].push(res);
|
if (id in requestQueue) return requestQueue[id].push(res);
|
||||||
|
|
||||||
// If not already added, then add it and call the debounced function to make sure the request gets executed
|
// If not already added, then add it and call the debounced function to make sure the request gets executed
|
||||||
else {
|
requestQueue[id] = [res];
|
||||||
requestQueue[id] = [res];
|
bulkFetch();
|
||||||
bulkFetch();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +139,7 @@ async function bulkFetchPronouns(ids: string[]): Promise<PronounsResponse> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatPronouns(pronouns: PronounCode): string {
|
export function formatPronouns(pronouns: string): string {
|
||||||
const { pronounsFormat } = Settings.plugins.PronounDB as { pronounsFormat: PronounsFormat, enabled: boolean; };
|
const { pronounsFormat } = Settings.plugins.PronounDB as { pronounsFormat: PronounsFormat, enabled: boolean; };
|
||||||
// For capitalized pronouns, just return the mapping (it is by default capitalized)
|
// For capitalized pronouns, just return the mapping (it is by default capitalized)
|
||||||
if (pronounsFormat === PronounsFormat.Capitalized) return PronounMapping[pronouns];
|
if (pronounsFormat === PronounsFormat.Capitalized) return PronounMapping[pronouns];
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { OptionType } from "@utils/types";
|
import { OptionType } from "@utils/types";
|
||||||
|
|
||||||
import { PronounsFormat } from "./pronoundbUtils";
|
import { PronounsFormat, PronounSource } from "./pronoundbUtils";
|
||||||
|
|
||||||
export const settings = definePluginSettings({
|
export const settings = definePluginSettings({
|
||||||
pronounsFormat: {
|
pronounsFormat: {
|
||||||
@ -37,6 +37,21 @@ export const settings = definePluginSettings({
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
pronounSource: {
|
||||||
|
type: OptionType.SELECT,
|
||||||
|
description: "Where to source pronouns from",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: "Prefer PronounDB, fall back to Discord",
|
||||||
|
value: PronounSource.PreferPDB,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Prefer Discord, fall back to PronounDB (might lead to inconsistency between pronouns in chat and profile)",
|
||||||
|
value: PronounSource.PreferDiscord
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
showSelf: {
|
showSelf: {
|
||||||
type: OptionType.BOOLEAN,
|
type: OptionType.BOOLEAN,
|
||||||
description: "Enable or disable showing pronouns for the current user",
|
description: "Enable or disable showing pronouns for the current user",
|
||||||
|
@ -419,6 +419,14 @@ export default definePlugin({
|
|||||||
match: /(?<=getChannels\(\i)(?=\))/,
|
match: /(?<=getChannels\(\i)(?=\))/,
|
||||||
replace: ",true"
|
replace: ",true"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
find: '.displayName="NowPlayingViewStore"',
|
||||||
|
replacement: {
|
||||||
|
// Make active now voice states on hiddenl channels
|
||||||
|
match: /(getVoiceStateForUser.{0,150}?)&&\i\.\i\.canWithPartialContext.{0,20}VIEW_CHANNEL.+?}\)(?=\?)/,
|
||||||
|
replace: "$1"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ const replacements = [
|
|||||||
["stupid", "baka"],
|
["stupid", "baka"],
|
||||||
["what", "nani"],
|
["what", "nani"],
|
||||||
["meow", "nya~"],
|
["meow", "nya~"],
|
||||||
|
["hello", "hewwo"],
|
||||||
];
|
];
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
|
@ -24,7 +24,7 @@ import definePlugin from "@utils/types";
|
|||||||
import { findByCodeLazy } from "@webpack";
|
import { findByCodeLazy } from "@webpack";
|
||||||
import { UserStore, useState } from "@webpack/common";
|
import { UserStore, useState } from "@webpack/common";
|
||||||
import type { User } from "discord-types/general";
|
import type { User } from "discord-types/general";
|
||||||
import type { ComponentType } from "react";
|
import type { ComponentType, ReactNode } from "react";
|
||||||
|
|
||||||
const fetching = new Set<string>();
|
const fetching = new Set<string>();
|
||||||
const queue = new Queue(5);
|
const queue = new Queue(5);
|
||||||
@ -36,7 +36,7 @@ interface MentionProps {
|
|||||||
channelId?: string;
|
channelId?: string;
|
||||||
content: any;
|
content: any;
|
||||||
};
|
};
|
||||||
parse: (content: any, props: MentionProps["props"]) => string[];
|
parse: (content: any, props: MentionProps["props"]) => ReactNode;
|
||||||
props: {
|
props: {
|
||||||
key: string;
|
key: string;
|
||||||
formatInline: boolean;
|
formatInline: boolean;
|
||||||
@ -72,7 +72,7 @@ function MentionWrapper({ data, UserMention, RoleMention, parse, props }: Mentio
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
onMouseEnter={() => {
|
onMouseEnter={() => {
|
||||||
const mention = children?.[0];
|
const mention = children?.[0]?.props?.children;
|
||||||
if (typeof mention !== "string") return;
|
if (typeof mention !== "string") return;
|
||||||
|
|
||||||
const id = mention.match(/<@(\d+)>/)?.[1];
|
const id = mention.match(/<@(\d+)>/)?.[1];
|
||||||
|
@ -44,7 +44,10 @@ const settings = definePluginSettings({
|
|||||||
],
|
],
|
||||||
description: "Choose the greet mode"
|
description: "Choose the greet mode"
|
||||||
}
|
}
|
||||||
});
|
}).withPrivateSettings<{
|
||||||
|
multiGreetChoices?: string[];
|
||||||
|
unholyMultiGreetEnabled?: boolean;
|
||||||
|
}>();
|
||||||
|
|
||||||
const MessageActions = findByPropsLazy("sendGreetMessage");
|
const MessageActions = findByPropsLazy("sendGreetMessage");
|
||||||
|
|
||||||
@ -73,7 +76,7 @@ function greet(channel: Channel, message: Message, stickers: string[]) {
|
|||||||
|
|
||||||
|
|
||||||
function GreetMenu({ stickers, channel, message }: { stickers: Sticker[], message: Message, channel: Channel; }) {
|
function GreetMenu({ stickers, channel, message }: { stickers: Sticker[], message: Message, channel: Channel; }) {
|
||||||
const s = settings.use(["greetMode", "multiGreetChoices"] as any) as { greetMode: GreetMode, multiGreetChoices: string[]; };
|
const s = settings.use(["greetMode", "multiGreetChoices"]);
|
||||||
const { greetMode, multiGreetChoices = [] } = s;
|
const { greetMode, multiGreetChoices = [] } = s;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -112,7 +115,7 @@ function GreetMenu({ stickers, channel, message }: { stickers: Sticker[], messag
|
|||||||
))}
|
))}
|
||||||
</Menu.MenuGroup>
|
</Menu.MenuGroup>
|
||||||
|
|
||||||
{!(settings.store as any).unholyMultiGreetEnabled ? null : (
|
{!settings.store.unholyMultiGreetEnabled ? null : (
|
||||||
<>
|
<>
|
||||||
<Menu.MenuSeparator />
|
<Menu.MenuSeparator />
|
||||||
|
|
||||||
|
@ -31,4 +31,5 @@ export * from "./onceDefined";
|
|||||||
export * from "./onlyOnce";
|
export * from "./onlyOnce";
|
||||||
export * from "./patches";
|
export * from "./patches";
|
||||||
export * from "./Queue";
|
export * from "./Queue";
|
||||||
|
export * from "./react";
|
||||||
export * from "./text";
|
export * from "./text";
|
||||||
|
@ -260,25 +260,29 @@ type SettingsStore<D extends SettingsDefinition> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** An instance of defined plugin settings */
|
/** An instance of defined plugin settings */
|
||||||
export interface DefinedSettings<D extends SettingsDefinition = SettingsDefinition, C extends SettingsChecks<D> = {}> {
|
export interface DefinedSettings<
|
||||||
|
Def extends SettingsDefinition = SettingsDefinition,
|
||||||
|
Checks extends SettingsChecks<Def> = {},
|
||||||
|
PrivateSettings extends object = {}
|
||||||
|
> {
|
||||||
/** Shorthand for `Vencord.Settings.plugins.PluginName`, but with typings */
|
/** Shorthand for `Vencord.Settings.plugins.PluginName`, but with typings */
|
||||||
store: SettingsStore<D>;
|
store: SettingsStore<Def> & PrivateSettings;
|
||||||
/**
|
/**
|
||||||
* React hook for getting the settings for this plugin
|
* React hook for getting the settings for this plugin
|
||||||
* @param filter optional filter to avoid rerenders for irrelavent settings
|
* @param filter optional filter to avoid rerenders for irrelavent settings
|
||||||
*/
|
*/
|
||||||
use<F extends Extract<keyof D, string>>(filter?: F[]): Pick<SettingsStore<D>, F>;
|
use<F extends Extract<keyof Def | keyof PrivateSettings, string>>(filter?: F[]): Pick<SettingsStore<Def> & PrivateSettings, F>;
|
||||||
/** Definitions of each setting */
|
/** Definitions of each setting */
|
||||||
def: D;
|
def: Def;
|
||||||
/** Setting methods with return values that could rely on other settings */
|
/** Setting methods with return values that could rely on other settings */
|
||||||
checks: C;
|
checks: Checks;
|
||||||
/**
|
/**
|
||||||
* Name of the plugin these settings belong to,
|
* Name of the plugin these settings belong to,
|
||||||
* will be an empty string until plugin is initialized
|
* will be an empty string until plugin is initialized
|
||||||
*/
|
*/
|
||||||
pluginName: string;
|
pluginName: string;
|
||||||
|
|
||||||
withPrivateSettings<T>(): this & { store: T; };
|
withPrivateSettings<T extends object>(): DefinedSettings<Def, Checks, T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PartialExcept<T, R extends keyof T> = Partial<T> & Required<Pick<T, R>>;
|
export type PartialExcept<T, R extends keyof T> = Partial<T> & Required<Pick<T, R>>;
|
||||||
|
Reference in New Issue
Block a user