Merge branch 'dev' into immediate-finds
This commit is contained in:
commit
97e2e2c1c8
|
@ -16,7 +16,6 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { CheckedTextInput } from "@components/CheckedTextInput";
|
|
||||||
import { CodeBlock } from "@components/CodeBlock";
|
import { CodeBlock } from "@components/CodeBlock";
|
||||||
import { debounce } from "@shared/debounce";
|
import { debounce } from "@shared/debounce";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
|
@ -47,7 +46,7 @@ const findCandidates = debounce(function ({ find, setModule, setError }) {
|
||||||
|
|
||||||
interface ReplacementComponentProps {
|
interface ReplacementComponentProps {
|
||||||
module: [id: number, factory: Function];
|
module: [id: number, factory: Function];
|
||||||
match: string | RegExp;
|
match: string;
|
||||||
replacement: string | ReplaceFn;
|
replacement: string | ReplaceFn;
|
||||||
setReplacementError(error: any): void;
|
setReplacementError(error: any): void;
|
||||||
}
|
}
|
||||||
|
@ -58,7 +57,13 @@ function ReplacementComponent({ module, match, replacement, setReplacementError
|
||||||
|
|
||||||
const [patchedCode, matchResult, diff] = React.useMemo(() => {
|
const [patchedCode, matchResult, diff] = React.useMemo(() => {
|
||||||
const src: string = fact.toString().replaceAll("\n", "");
|
const src: string = fact.toString().replaceAll("\n", "");
|
||||||
const canonicalMatch = canonicalizeMatch(match);
|
|
||||||
|
try {
|
||||||
|
new RegExp(match);
|
||||||
|
} catch (e) {
|
||||||
|
return ["", [], []];
|
||||||
|
}
|
||||||
|
const canonicalMatch = canonicalizeMatch(new RegExp(match));
|
||||||
try {
|
try {
|
||||||
const canonicalReplace = canonicalizeReplace(replacement, "YourPlugin");
|
const canonicalReplace = canonicalizeReplace(replacement, "YourPlugin");
|
||||||
var patched = src.replace(canonicalMatch, canonicalReplace as string);
|
var patched = src.replace(canonicalMatch, canonicalReplace as string);
|
||||||
|
@ -286,6 +291,7 @@ function PatchHelper() {
|
||||||
|
|
||||||
const [module, setModule] = React.useState<[number, Function]>();
|
const [module, setModule] = React.useState<[number, Function]>();
|
||||||
const [findError, setFindError] = React.useState<string>();
|
const [findError, setFindError] = React.useState<string>();
|
||||||
|
const [matchError, setMatchError] = React.useState<string>();
|
||||||
|
|
||||||
const code = React.useMemo(() => {
|
const code = React.useMemo(() => {
|
||||||
return `
|
return `
|
||||||
|
@ -322,12 +328,17 @@ function PatchHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMatchChange(v: string) {
|
function onMatchChange(v: string) {
|
||||||
try {
|
setMatchError(void 0);
|
||||||
new RegExp(v);
|
|
||||||
setFindError(void 0);
|
|
||||||
setMatch(v);
|
setMatch(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMatchBlur() {
|
||||||
|
try {
|
||||||
|
new RegExp(match);
|
||||||
|
setMatchError(void 0);
|
||||||
|
setMatch(match);
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
setFindError((e as Error).message);
|
setMatchError((e as Error).message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,16 +362,12 @@ function PatchHelper() {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Forms.FormTitle className={Margins.top8}>match</Forms.FormTitle>
|
<Forms.FormTitle className={Margins.top8}>match</Forms.FormTitle>
|
||||||
<CheckedTextInput
|
<TextInput
|
||||||
|
type="text"
|
||||||
value={match}
|
value={match}
|
||||||
onChange={onMatchChange}
|
onChange={onMatchChange}
|
||||||
validate={v => {
|
onBlur={onMatchBlur}
|
||||||
try {
|
error={matchError}
|
||||||
return (new RegExp(v), true);
|
|
||||||
} catch (e) {
|
|
||||||
return (e as Error).message;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className={Margins.top8} />
|
<div className={Margins.top8} />
|
||||||
|
@ -374,7 +381,7 @@ function PatchHelper() {
|
||||||
{module && (
|
{module && (
|
||||||
<ReplacementComponent
|
<ReplacementComponent
|
||||||
module={module}
|
module={module}
|
||||||
match={new RegExp(match)}
|
match={match}
|
||||||
replacement={replacement}
|
replacement={replacement}
|
||||||
setReplacementError={setReplacementError}
|
setReplacementError={setReplacementError}
|
||||||
/>
|
/>
|
||||||
|
|
5
src/plugins/customidle/README.md
Normal file
5
src/plugins/customidle/README.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# CustomIdle
|
||||||
|
|
||||||
|
Lets you change the time until your status gets automatically set to idle. You can also prevent idling altogether.
|
||||||
|
|
||||||
|
![Plugin Configuration](https://github.com/Vendicated/Vencord/assets/45801973/4e5259b2-18e0-42e5-b69f-efc672ce1e0b)
|
94
src/plugins/customidle/index.ts
Normal file
94
src/plugins/customidle/index.ts
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Notices } from "@api/index";
|
||||||
|
import { definePluginSettings } from "@api/Settings";
|
||||||
|
import { makeRange } from "@components/PluginSettings/components";
|
||||||
|
import { Devs } from "@utils/constants";
|
||||||
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
|
import { FluxDispatcher } from "@webpack/common";
|
||||||
|
|
||||||
|
const settings = definePluginSettings({
|
||||||
|
idleTimeout: {
|
||||||
|
description: "Minutes before Discord goes idle (0 to disable auto-idle)",
|
||||||
|
type: OptionType.SLIDER,
|
||||||
|
markers: makeRange(0, 60, 5),
|
||||||
|
default: 10,
|
||||||
|
stickToMarkers: false,
|
||||||
|
restartNeeded: true // Because of the setInterval patch
|
||||||
|
},
|
||||||
|
remainInIdle: {
|
||||||
|
description: "When you come back to Discord, remain idle until you confirm you want to go online",
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "CustomIdle",
|
||||||
|
description: "Allows you to set the time before Discord goes idle (or disable auto-idle)",
|
||||||
|
authors: [Devs.newwares],
|
||||||
|
settings,
|
||||||
|
patches: [
|
||||||
|
{
|
||||||
|
find: "IDLE_DURATION:function(){return",
|
||||||
|
replacement: {
|
||||||
|
match: /(IDLE_DURATION:function\(\){return )\i/,
|
||||||
|
replace: "$1$self.getIdleTimeout()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
find: 'type:"IDLE",idle:',
|
||||||
|
replacement: [
|
||||||
|
{
|
||||||
|
match: /Math\.min\((\i\.AfkTimeout\.getSetting\(\)\*\i\.default\.Millis\.SECOND),\i\.IDLE_DURATION\)/,
|
||||||
|
replace: "$1" // Decouple idle from afk (phone notifications will remain at user setting or 10 min maximum)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /\i\.default\.dispatch\({type:"IDLE",idle:!1}\)/,
|
||||||
|
replace: "$self.handleOnline()"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /(setInterval\(\i,\.25\*)\i\.IDLE_DURATION/,
|
||||||
|
replace: "$1$self.getIntervalDelay()" // For web installs
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
getIntervalDelay() {
|
||||||
|
return Math.min(6e5, this.getIdleTimeout());
|
||||||
|
},
|
||||||
|
|
||||||
|
handleOnline() {
|
||||||
|
if (!settings.store.remainInIdle) {
|
||||||
|
FluxDispatcher.dispatch({
|
||||||
|
type: "IDLE",
|
||||||
|
idle: false
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const backOnlineMessage = "Welcome back! Click the button to go online. Click the X to stay idle until reload.";
|
||||||
|
if (
|
||||||
|
Notices.currentNotice?.[1] === backOnlineMessage ||
|
||||||
|
Notices.noticesQueue.some(([, noticeMessage]) => noticeMessage === backOnlineMessage)
|
||||||
|
) return;
|
||||||
|
|
||||||
|
Notices.showNotice(backOnlineMessage, "Exit idle", () => {
|
||||||
|
Notices.popNotice();
|
||||||
|
FluxDispatcher.dispatch({
|
||||||
|
type: "IDLE",
|
||||||
|
idle: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getIdleTimeout() { // milliseconds, default is 6e5
|
||||||
|
const { idleTimeout } = settings.store;
|
||||||
|
return idleTimeout === 0 ? Infinity : idleTimeout * 60000;
|
||||||
|
}
|
||||||
|
});
|
|
@ -352,6 +352,15 @@ export default definePlugin({
|
||||||
if (location === "chat" && !settings.tagSettings[tag.name].showInChat) continue;
|
if (location === "chat" && !settings.tagSettings[tag.name].showInChat) continue;
|
||||||
if (location === "not-chat" && !settings.tagSettings[tag.name].showInNotChat) continue;
|
if (location === "not-chat" && !settings.tagSettings[tag.name].showInNotChat) continue;
|
||||||
|
|
||||||
|
// If the owner tag is disabled, and the user is the owner of the guild,
|
||||||
|
// avoid adding other tags because the owner will always match the condition for them
|
||||||
|
if (
|
||||||
|
tag.name !== "OWNER" &&
|
||||||
|
GuildStore.getGuild(channel?.guild_id)?.ownerId === user.id &&
|
||||||
|
(location === "chat" && !settings.tagSettings.OWNER.showInChat) ||
|
||||||
|
(location === "not-chat" && !settings.tagSettings.OWNER.showInNotChat)
|
||||||
|
) continue;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
tag.permissions?.some(perm => perms.includes(perm)) ||
|
tag.permissions?.some(perm => perms.includes(perm)) ||
|
||||||
(tag.condition?.(message!, user, channel))
|
(tag.condition?.(message!, user, channel))
|
||||||
|
|
|
@ -422,6 +422,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({
|
||||||
name: "Av32000",
|
name: "Av32000",
|
||||||
id: 593436735380127770n,
|
id: 593436735380127770n,
|
||||||
},
|
},
|
||||||
|
Noxillio: {
|
||||||
|
name: "Noxillio",
|
||||||
|
id: 138616536502894592n,
|
||||||
|
},
|
||||||
Kyuuhachi: {
|
Kyuuhachi: {
|
||||||
name: "Kyuuhachi",
|
name: "Kyuuhachi",
|
||||||
id: 236588665420251137n,
|
id: 236588665420251137n,
|
||||||
|
|
Loading…
Reference in a new issue