This commit is contained in:
thororen 2024-06-27 21:46:46 -04:00
commit 071d42a9a9
9 changed files with 63 additions and 55 deletions

View file

@ -1,7 +1,7 @@
{ {
"name": "vencord", "name": "vencord",
"private": "true", "private": "true",
"version": "1.9.1", "version": "1.9.2",
"description": "The other cutest Discord client mod", "description": "The other cutest Discord client mod",
"homepage": "https://github.com/Equicord/Equicord#readme", "homepage": "https://github.com/Equicord/Equicord#readme",
"bugs": { "bugs": {
@ -118,4 +118,4 @@
"node": ">=18", "node": ">=18",
"pnpm": ">=9" "pnpm": ">=9"
} }
} }

View file

@ -136,7 +136,6 @@ async function printReport() {
body: JSON.stringify({ body: JSON.stringify({
description: "Here's the latest Equicord Report!", description: "Here's the latest Equicord Report!",
username: "Equicord Reporter" + (CANARY ? " (Canary)" : ""), username: "Equicord Reporter" + (CANARY ? " (Canary)" : ""),
avatar_url: "https://avatars.githubusercontent.com/u/150590884?s=48&v=4",
embeds: [ embeds: [
{ {
title: "Bad Patches", title: "Bad Patches",

View file

@ -139,7 +139,7 @@ export const SettingsStore = new SettingsStoreClass(settings, {
if (path === "plugins" && key in plugins) if (path === "plugins" && key in plugins)
return target[key] = { return target[key] = {
enabled: IS_REPORTER ?? plugins[key].required ?? plugins[key].enabledByDefault ?? false enabled: IS_REPORTER || plugins[key].required || plugins[key].enabledByDefault || false
}; };
// Since the property is not set, check if this is a plugin's setting and if so, try to resolve // Since the property is not set, check if this is a plugin's setting and if so, try to resolve

View file

@ -343,7 +343,7 @@ export function ResetIcon(props: IconProps) {
> >
<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" /> <path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" />
<path d="M3 3v5h5" /> <path d="M3 3v5h5" />
</Icon> </Icon>
); );
} }

View file

@ -16,10 +16,12 @@ import { Margins } from "@utils/margins";
import { useForceUpdater } from "@utils/react"; import { useForceUpdater } from "@utils/react";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { findByCodeLazy, findByPropsLazy } from "@webpack"; import { findByCodeLazy, findByPropsLazy } from "@webpack";
import { Button, ChannelStore, Forms, SearchableSelect, SelectedChannelStore, TabBar, TextInput, UserStore, useState } from "@webpack/common"; import { Button, ChannelStore, Forms, Select, SelectedChannelStore, Switch, TabBar, TextInput, UserStore, useState } from "@webpack/common";
import { Message, User } from "discord-types/general/index.js"; import { Message, User } from "discord-types/general/index.js";
let keywordEntries: Array<{ regex: string, listIds: Array<string>, listType: ListType; }> = []; type KeywordEntry = { regex: string, listIds: Array<string>, listType: ListType, ignoreCase: boolean; };
let keywordEntries: Array<KeywordEntry> = [];
let currentUser: User; let currentUser: User;
let keywordLog: Array<any> = []; let keywordLog: Array<any> = [];
@ -33,7 +35,7 @@ const KEYWORD_LOG_KEY = "KeywordNotify_log";
const cl = classNameFactory("vc-keywordnotify-"); const cl = classNameFactory("vc-keywordnotify-");
async function addKeywordEntry(forceUpdate: () => void) { async function addKeywordEntry(forceUpdate: () => void) {
keywordEntries.push({ regex: "", listIds: [], listType: ListType.BlackList }); keywordEntries.push({ regex: "", listIds: [], listType: ListType.BlackList, ignoreCase: false });
await DataStore.set(KEYWORD_ENTRIES_KEY, keywordEntries); await DataStore.set(KEYWORD_ENTRIES_KEY, keywordEntries);
forceUpdate(); forceUpdate();
} }
@ -44,9 +46,9 @@ async function removeKeywordEntry(idx: number, forceUpdate: () => void) {
forceUpdate(); forceUpdate();
} }
function safeMatchesRegex(s: string, r: string) { function safeMatchesRegex(str: string, regex: string, flags: string) {
try { try {
return s.match(new RegExp(r)); return str.match(new RegExp(regex, flags));
} catch { } catch {
return false; return false;
} }
@ -57,29 +59,26 @@ enum ListType {
Whitelist = "Whitelist" Whitelist = "Whitelist"
} }
function highlightKeywords(s: string, r: Array<string>) { function highlightKeywords(str: string, entries: Array<KeywordEntry>) {
let regex: RegExp; let regexes: Array<RegExp>;
try { try {
regex = new RegExp(r.join("|"), "g"); regexes = entries.map(e => new RegExp(e.regex, "g" + (e.ignoreCase ? "i" : "")));
} catch { } catch (err) {
return [s]; return [str];
} }
const matches = s.match(regex); const matches = regexes.map(r => str.match(r)).flat().filter(e => e != null);
if (!matches) if (matches.length === 0) {
return [s]; return [str];
}
const parts = [...matches.map(e => { const idx = str.indexOf(matches[0]!);
const idx = s.indexOf(e);
const before = s.substring(0, idx);
s = s.substring(idx + e.length);
return before;
}, s), s];
return parts.map(e => [ return [
(<span>{e}</span>), <span>{str.substring(0, idx)}</span>,
matches!.length ? (<span className="highlight">{matches!.splice(0, 1)[0]}</span>) : [] <span className="highlight">{matches[0]}</span>,
]); <span>{str.substring(idx + matches[0]!.length)}</span>
];
} }
function Collapsible({ title, children }) { function Collapsible({ title, children }) {
@ -147,16 +146,17 @@ function ListedIds({ listIds, setListIds }) {
function ListTypeSelector({ listType, setListType }) { function ListTypeSelector({ listType, setListType }) {
return ( return (
<SearchableSelect <Select
options={[ options={[
{ label: "Whitelist", value: ListType.Whitelist }, { label: "Whitelist", value: ListType.Whitelist },
{ label: "Blacklist", value: ListType.BlackList } { label: "Blacklist", value: ListType.BlackList }
]} ]}
placeholder={"Select a list type"} placeholder={"Select a list type"}
maxVisibleItems={2} isSelected={v => v === listType}
closeOnSelect={true} closeOnSelect={true}
value={listType} className={`${listType}`}
onChange={setListType} select={setListType}
serialize={v => v}
/> />
); );
} }
@ -205,6 +205,16 @@ function KeywordEntries() {
<DeleteIcon /> <DeleteIcon />
</Button> </Button>
</Flex> </Flex>
<Switch
value={values[i].ignoreCase}
onChange={() => {
values[i].ignoreCase = !values[i].ignoreCase;
update();
}}
style={{ marginTop: "0.5em", marginRight: "40px" }}
>
Ignore Case
</Switch>
<Forms.FormDivider className={[Margins.top8, Margins.bottom8].join(" ")} /> <Forms.FormDivider className={[Margins.top8, Margins.bottom8].join(" ")} />
<Forms.FormTitle tag="h5">Whitelist/Blacklist</Forms.FormTitle> <Forms.FormTitle tag="h5">Whitelist/Blacklist</Forms.FormTitle>
<Flex flexDirection="row"> <Flex flexDirection="row">
@ -304,7 +314,7 @@ export default definePlugin({
applyKeywordEntries(m: Message) { applyKeywordEntries(m: Message) {
let matches = false; let matches = false;
keywordEntries.forEach(entry => { for (const entry of keywordEntries) {
if (entry.regex === "") { if (entry.regex === "") {
return; return;
} }
@ -318,6 +328,7 @@ export default definePlugin({
} }
const whitelistMode = entry.listType === ListType.Whitelist; const whitelistMode = entry.listType === ListType.Whitelist;
if (!whitelistMode && listed) { if (!whitelistMode && listed) {
return; return;
} }
@ -325,28 +336,27 @@ export default definePlugin({
return; return;
} }
if (settings.store.ignoreBots && m.author.bot) { if (settings.store.ignoreBots && m.author.bot && (!whitelistMode || !entry.listIds.includes(m.author.id))) {
if (!whitelistMode || !entry.listIds.includes(m.author.id)) { return;
return;
}
} }
if (safeMatchesRegex(m.content, entry.regex)) { const flags = entry.ignoreCase ? "i" : "";
if (safeMatchesRegex(m.content, entry.regex, flags)) {
matches = true; matches = true;
} }
for (const embed of m.embeds as any) { for (const embed of m.embeds as any) {
if (safeMatchesRegex(embed.description, entry.regex) || safeMatchesRegex(embed.title, entry.regex)) { if (safeMatchesRegex(embed.description, entry.regex, flags) || safeMatchesRegex(embed.title, entry.regex, flags)) {
matches = true; matches = true;
} else if (embed.fields != null) { } else if (embed.fields != null) {
for (const field of embed.fields as Array<{ name: string, value: string; }>) { for (const field of embed.fields as Array<{ name: string, value: string; }>) {
if (safeMatchesRegex(field.value, entry.regex) || safeMatchesRegex(field.name, entry.regex)) { if (safeMatchesRegex(field.value, entry.regex, flags) || safeMatchesRegex(field.name, entry.regex, flags)) {
matches = true; matches = true;
} }
} }
} }
} }
}); }
if (matches) { if (matches) {
// @ts-ignore // @ts-ignore
@ -358,7 +368,7 @@ export default definePlugin({
}, },
addToLog(m: Message) { addToLog(m: Message) {
if (m == null || keywordLog.some(e => e.id === m.id)) if (m === null || keywordLog.some(e => e.id === m.id))
return; return;
DataStore.get(KEYWORD_LOG_KEY).then(log => { DataStore.get(KEYWORD_LOG_KEY).then(log => {
@ -405,7 +415,7 @@ export default definePlugin({
e._keyword = true; e._keyword = true;
e.customRenderedContent = { e.customRenderedContent = {
content: highlightKeywords(e.content, keywordEntries.map(e => e.regex)) content: highlightKeywords(e.content, keywordEntries)
}; };
const msg = this.renderMsg({ const msg = this.renderMsg({

View file

@ -1,17 +1,16 @@
/* stylelint-disable no-descending-specificity */ .vc-keywordnotify-delete {
.keywordnotify-delete:hover {
color: var(--status-danger);
}
.keywordnotify-delete {
padding: 0; padding: 0;
color: var(--primary-400); color: var(--primary-400);
transition: color 0.2s ease-in-out; transition: color 0.2s ease-in-out;
} }
.keywordnotify-collapsible { .vc-keywordnotify-delete:hover {
color: var(--status-danger);
}
.vc-keywordnotify-collapsible {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 8px; padding: 8px;
cursor: pointer; cursor: pointer;
} }

View file

@ -587,4 +587,4 @@ function ThemeLibrary() {
); );
} }
export default wrapTab(ThemeLibrary, "Theme Library"); export default wrapTab(ThemeLibrary, "Theme Library");

View file

@ -109,7 +109,7 @@ interface ProfileModalProps {
} }
const ColorPicker = findComponentByCodeLazy<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)"); const ColorPicker = findComponentByCodeLazy<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
const ProfileModal = findComponentByCodeLazy("isTryItOutFlow:", "pendingThemeColors:", "avatarDecorationOverride:", ".CUSTOM_STATUS"); const ProfileModal = findComponentByCodeLazy<ProfileModalProps>("isTryItOutFlow:", "pendingThemeColors:", "pendingAvatarDecoration:", "EDIT_PROFILE_BANNER");
const requireColorPicker = extractAndLoadChunksLazy(["USER_SETTINGS_PROFILE_COLOR_DEFAULT_BUTTON.format"], /createPromise:\(\)=>\i\.\i(\("?.+?"?\)).then\(\i\.bind\(\i,"?(.+?)"?\)\)/); const requireColorPicker = extractAndLoadChunksLazy(["USER_SETTINGS_PROFILE_COLOR_DEFAULT_BUTTON.format"], /createPromise:\(\)=>\i\.\i(\("?.+?"?\)).then\(\i\.bind\(\i,"?(.+?)"?\)\)/);

View file

@ -98,8 +98,8 @@ export default definePlugin({
{ {
find: ".popularApplicationCommandIds,", find: ".popularApplicationCommandIds,",
replacement: { replacement: {
match: /applicationId:\i\.id}\),(?=.{0,50}setNote:\i)/, match: /(?<=,)(?=!\i&&!\i&&.{0,50}setNote:)/,
replace: "$&$self.patchPopout(arguments[0]),", replace: "$self.patchPopout(arguments[0]),",
} }
}, },
// below username // below username