Merge branch 'dev'

This commit is contained in:
thororen1234 2025-01-22 14:56:53 -05:00
commit 4891f09e24
6 changed files with 90 additions and 74 deletions

View file

@ -5,21 +5,21 @@
*/
import { classNameFactory } from "@api/Styles";
import { makeRange } from "@components/PluginSettings/components";
import { Margins } from "@utils/margins";
import { classes } from "@utils/misc";
import { useForceUpdater } from "@utils/react";
import { findByCodeLazy, findLazy } from "@webpack";
import { Button, Card, Forms, Slider, Switch, useRef } from "@webpack/common";
import { Button, Card, Forms, Slider, Switch, Tooltip, useRef } from "@webpack/common";
import { ComponentType, Ref, SyntheticEvent } from "react";
import { SoundOverride, SoundPlayer, SoundType } from "../types";
type FileInput = ComponentType<{
ref: Ref<HTMLInputElement>;
onChange: (e: SyntheticEvent<HTMLInputElement>) => void;
onChange: (event: SyntheticEvent<HTMLInputElement>) => void;
multiple?: boolean;
filters?: { name?: string; extensions: string[]; }[];
disabled?: boolean;
}>;
const playSound: (id: string) => SoundPlayer = findByCodeLazy(".playWithListener().then");
@ -43,8 +43,72 @@ export function SoundOverrideComponent({ type, override, onChange }: { type: Sou
className={Margins.bottom16}
hideBorder={true}
>
{type.name} <span className={cl("id")}>({type.id})</span>
<Tooltip text={type.id}>
{tooltipProps => <span {...tooltipProps}>{type.name}</span>}
</Tooltip>
</Switch>
<Forms.FormTitle>Sound File</Forms.FormTitle>
<div className={classes(cl("file"), Margins.bottom16)} >
<Forms.FormText className={cl("file-name")}>{override.url.length === 0 ? "Discord Default" : (override.fileName || "Custom Sound")}</Forms.FormText>
<Button
color={Button.Colors.PRIMARY}
size={Button.Sizes.SMALL}
disabled={!override.enabled}
className={cl("file-replace")}
>
Replace
<FileInput
ref={fileInputRef}
disabled={!override.enabled}
onChange={event => {
event.stopPropagation();
event.preventDefault();
if (!event.currentTarget?.files?.length)
return;
const { files } = event.currentTarget;
const file = files[0];
// Set override URL to a data URI
const reader = new FileReader;
reader.onload = () => {
override.url = reader.result as string;
override.fileName = file.name;
onChange();
update();
};
reader.readAsDataURL(file);
}}
// Sorry .caf lovers, https://en.wikipedia.org/wiki/HTML5_audio#Supported_audio_coding_formats
filters={[{ extensions: ["mp3", "wav", "ogg", "webm", "flac"] }]}
/>
</Button>
<Button
color={Button.Colors.RED}
size={Button.Sizes.SMALL}
onClick={() => {
override.url = "";
onChange();
update();
}}
disabled={!(override.enabled && override.url.length !== 0)}
className={cl("file-reset")}
>
Reset
</Button>
</div>
<Forms.FormTitle>Volume</Forms.FormTitle>
<Slider
initialValue={override.volume}
onValueChange={value => {
override.volume = value;
onChange();
update();
}}
className={Margins.bottom16}
disabled={!override.enabled}
/>
<Button
color={Button.Colors.PRIMARY}
className={Margins.bottom16}
@ -57,63 +121,6 @@ export function SoundOverrideComponent({ type, override, onChange }: { type: Sou
>
Preview
</Button>
<Forms.FormTitle>Replacement Sound</Forms.FormTitle>
<Button
color={Button.Colors.PRIMARY}
disabled={!override.enabled}
className={classes(Margins.right8, Margins.bottom16, cl("upload"))}
>
Upload
<FileInput
ref={fileInputRef}
onChange={event => {
event.stopPropagation();
event.preventDefault();
if (!event.currentTarget?.files?.length)
return;
const { files } = event.currentTarget;
const file = files[0];
// Set override URL to a data URI
const reader = new FileReader;
reader.onload = () => {
override.url = reader.result as string;
onChange();
update();
};
reader.readAsDataURL(file);
}}
// Sorry .caf lovers, https://en.wikipedia.org/wiki/HTML5_audio#Supported_audio_coding_formats
filters={[{ extensions: ["mp3", "wav", "ogg", "webm", "flac"] }]}
/>
</Button>
<Button
color={Button.Colors.RED}
onClick={() => {
override.url = "";
onChange();
update();
}}
disabled={!(override.enabled && override.url.length !== 0)}
style={{ display: "inline" }}
className={classes(Margins.right8, Margins.bottom16)}
>
Clear
</Button>
<Forms.FormTitle>Volume</Forms.FormTitle>
<Slider
markers={makeRange(0, 100, 10)}
initialValue={override.volume}
onValueChange={value => {
override.volume = value;
onChange();
update();
}}
className={Margins.bottom16}
disabled={!override.enabled}
/>
</Card>
);
}

View file

@ -2,10 +2,17 @@
padding: 1em 1em 0;
}
.vc-custom-sounds-id {
color: var(--text-muted);
.vc-custom-sounds-file {
display: flex;
align-items: center;
gap: 0.5em;
}
.vc-custom-sounds-upload {
.vc-custom-sounds-file-name {
flex-grow: 1;
}
.vc-custom-sounds-file-replace,
.vc-custom-sounds-file-reset {
display: inline;
}

View file

@ -11,6 +11,7 @@ export interface SoundType {
export interface SoundOverride {
enabled: boolean;
fileName: string;
url: string;
volume: number;
}
@ -51,6 +52,7 @@ export const soundTypes: readonly SoundType[] = [
export function makeEmptyOverride(): SoundOverride {
return {
enabled: false,
fileName: "",
url: "",
volume: 100
};

View file

@ -76,7 +76,7 @@ export default definePlugin({
{
find: "useGenerateUserSettingsSections",
replacement: {
match: /(\.FRIEND_REQUESTS)/,
match: /(\.CLIPS)/,
replace: "$1,\"SCAN_QR_CODE\""
}
},

View file

@ -34,19 +34,19 @@ export default definePlugin({
{
find: "#{intl::STICKER_BUTTON_LABEL}",
replacement: [{
match: /(children:\(0,\w\.jsx\)\()([\w.]+?)(,{innerClassName.{10,30}\.stickerButton)/,
match: /(children:\(0,\i\.jsx\)\()([\w.]+?)(,{innerClassName.{10,30}\.stickerButton)/,
replace: (_, head, button, tail) => {
const isMoreStickers = "arguments[0]?.stickersType";
return `${head}${isMoreStickers}?$self.stickerButton:${button}${tail}`;
}
}, {
match: /(\w=)(\w\.useCallback\(\(\)=>\{\(0,\w+\.\w+\)\([\w.]*?\.STICKER,.*?);/,
match: /(\i=)(\i\.useCallback\(\(\)=>\{\(0,\w+\.\w+\)\([\w.]*?\.STICKER,.*?);/,
replace: (_, decl, cb) => {
const newCb = cb.replace(/(?<=\(\)=>\{\(.*?\)\().+?\.STICKER/, "\"stickers+\"");
return `${decl}arguments[0]?.stickersType?${newCb}:${cb};`;
}
}, {
match: /(\w)=((\w)===\w+?\.\w+?\.STICKER)/,
match: /(\i)=((\i)===\w+?\.\w+?\.STICKER)/,
replace: (_, isActive, isStickerTab, currentTab) => {
const c = "arguments[0].stickersType";
return `${isActive}=${c}?(${currentTab}===${c}):(${isStickerTab})`;
@ -56,7 +56,7 @@ export default definePlugin({
{
find: ".gifts)",
replacement: {
match: /,\(null===\(\w=\w\.stickers\)\|\|void 0.*?(\w)\.push\((\(0,\w\.jsx\))\((.+?),{disabled:\w,type:(\w)},"sticker"\)\)/,
match: /\(null===\(\i=\i\.stickers\).*?(\i)\.push\((\(0,\i\.jsx\))\((.+?),{disabled:\w,type:(\i)},"sticker"\)\)/,
replace: (m, _, jsx, compo, type) => {
const c = "arguments[0].type";
return `${m},${c}?.submit?.button&&${_}.push(${jsx}(${compo},{disabled:!${c}?.submit?.button,type:${type},stickersType:"stickers+"},"stickers+"))`;
@ -87,7 +87,7 @@ export default definePlugin({
{
find: '==="remove_text"',
replacement: {
match: /,\w\.insertText=\w=>{[\w ;]*?1===\w\.length&&.+?==="remove_text"/,
match: /,\i\.insertText=\i=>{[\w ;]*?1===\i\.length&&.+?==="remove_text"/,
replace: ",$self.textEditor=arguments[0]$&"
}
}

View file

@ -31,7 +31,7 @@ export default definePlugin({
replace: (_, rest1, rest2, args) => "" +
`${rest1}async ${rest2}` +
`if(await Vencord.Api.MessageEvents._handlePreEdit(${args}))` +
"return Promise.resolve({shouldClear:false,shouldRefocus:true});"
"return Promise.resolve({shouldClear:true,shouldRefocus:true});"
}
},
{
@ -39,12 +39,12 @@ export default definePlugin({
replacement: {
// props.chatInputType...then((function(isMessageValid)... var parsedMessage = b.c.parse(channel,... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply);
// Lookbehind: validateMessage)({openWarningPopout:..., type: i.props.chatInputType, content: t, stickers: r, ...}).then((function(isMessageValid)
match: /(\{openWarningPopout:.{0,100}type:this.props.chatInputType.+?\.then\()(\i=>\{.+?let (\i)=\i\.\i\.parse\((\i),.+?let (\i)=\i\.\i\.getSendMessageOptions\(\{.+?\}\);)(?<=\)\(({.+?})\)\.then.+?)/,
match: /(\((\{openWarningPopout:.{0,200}?\})\)\.then\()(\i=>\{.+?let (\i)=\i\.\i\.parse\((\i),.+?let (\i)=\i\.\i\.getSendMessageOptions\(\{.+?\}\);)/,
// props.chatInputType...then((async function(isMessageValid)... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply); if(await Vencord.api...) return { shoudClear:true, shouldRefocus:true };
replace: (_, rest1, rest2, parsedMessage, channel, replyOptions, extra) => "" +
replace: (_, rest1, extra, rest2, parsedMessage, channel, replyOptions) => "" +
`${rest1}async ${rest2}` +
`if(await Vencord.Api.MessageEvents._handlePreSend(${channel}.id,${parsedMessage},${extra},${replyOptions}))` +
"return{shouldClear:false,shouldRefocus:true};"
"return{shouldClear:true,shouldRefocus:true};"
}
},
{