mirror of
https://github.com/Equicord/Equicord.git
synced 2025-06-17 10:27:03 -04:00
Merge branch 'dev'
This commit is contained in:
commit
b6fe44ce5b
37 changed files with 1359 additions and 1381 deletions
|
@ -18,14 +18,14 @@
|
|||
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { Channel, Message } from "discord-types/general";
|
||||
import type { MouseEventHandler } from "react";
|
||||
import type { ComponentType, MouseEventHandler, ReactElement } from "react";
|
||||
|
||||
const logger = new Logger("MessagePopover");
|
||||
|
||||
export interface ButtonItem {
|
||||
key?: string,
|
||||
label: string,
|
||||
icon: React.ComponentType<any>,
|
||||
icon: ComponentType<any>,
|
||||
message: Message,
|
||||
channel: Channel,
|
||||
onClick?: MouseEventHandler<HTMLButtonElement>,
|
||||
|
@ -49,16 +49,16 @@ export function removeButton(identifier: string) {
|
|||
|
||||
export function _buildPopoverElements(
|
||||
msg: Message,
|
||||
makeButton: (item: ButtonItem) => React.ComponentType
|
||||
PopoverButton: ComponentType<ButtonItem>,
|
||||
) {
|
||||
const items = [] as React.ComponentType[];
|
||||
const items = [] as ReactElement[];
|
||||
|
||||
for (const [identifier, getItem] of buttons.entries()) {
|
||||
try {
|
||||
const item = getItem(msg);
|
||||
if (item) {
|
||||
item.key ??= identifier;
|
||||
items.push(makeButton(item));
|
||||
items.push(<PopoverButton {...item} />);
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error(`[${identifier}]`, err);
|
|
@ -1,6 +1,6 @@
|
|||
.vc-expandableheader-center-flex {
|
||||
display: flex;
|
||||
place-content: center;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.vc-expandableheader-btn {
|
||||
|
@ -8,4 +8,4 @@
|
|||
cursor: pointer;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { classNameFactory } from "@api/Styles";
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { findComponentByCodeLazy } from "@webpack";
|
||||
import { moment, React, useMemo } from "@webpack/common";
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
/* eslint-disable arrow-parens */
|
||||
|
||||
import * as DataStore from "@api/DataStore";
|
||||
import { Flex } from "@components/Flex";
|
||||
import { DeleteIcon, PlusIcon } from "@components/Icons";
|
||||
|
@ -107,12 +105,12 @@ export default function ({
|
|||
id: "all",
|
||||
sources: [...colorwayData, ...customColorwayData]
|
||||
},
|
||||
...colorwayData.map((source) => ({
|
||||
...colorwayData.map(source => ({
|
||||
name: source.source,
|
||||
id: source.source.toLowerCase().replaceAll(" ", "-"),
|
||||
sources: [source]
|
||||
})),
|
||||
...customColorwayData.map((source) => ({
|
||||
...customColorwayData.map(source => ({
|
||||
name: source.source,
|
||||
id: source.source.toLowerCase().replaceAll(" ", "-"),
|
||||
sources: [source]
|
||||
|
@ -147,7 +145,7 @@ export default function ({
|
|||
const onlineSources: { name: string, url: string; }[] = await DataStore.get("colorwaySourceFiles") as { name: string, url: string; }[];
|
||||
|
||||
const responses: Response[] = await Promise.all(
|
||||
onlineSources.map((source) =>
|
||||
onlineSources.map(source =>
|
||||
fetch(source.url, force ? { cache: "no-store" } : {})
|
||||
)
|
||||
);
|
||||
|
@ -309,7 +307,7 @@ export default function ({
|
|||
style={{ marginLeft: "8px" }}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
onClick={() => openModal((props) => <CreatorModal
|
||||
onClick={() => openModal(props => <CreatorModal
|
||||
modalProps={props}
|
||||
loadUIProps={loadUI}
|
||||
/>)}
|
||||
|
@ -350,7 +348,7 @@ export default function ({
|
|||
id="colorway-opencolorstealer"
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
onClick={() => openModal((props) => <ColorPickerModal modalProps={props} />)}
|
||||
onClick={() => openModal(props => <ColorPickerModal modalProps={props} />)}
|
||||
>
|
||||
<PalleteIcon width={20} height={20} style={{ padding: "6px", boxSizing: "content-box" }} />
|
||||
</Button>}
|
||||
|
@ -469,7 +467,7 @@ export default function ({
|
|||
{(showLabelsInSelectorGridView || viewMode === "list") && <Text className={"colorwayLabel" + ((showLabelsInSelectorGridView && viewMode === "grid") ? " labelInGrid" : "")}>Auto</Text>}
|
||||
<div
|
||||
className="colorwayInfoIconContainer"
|
||||
onClick={async (e) => {
|
||||
onClick={async e => {
|
||||
e.stopPropagation();
|
||||
const activeAutoPreset = await DataStore.get("activeAutoPreset");
|
||||
openModal((props: ModalProps) => <AutoColorwaySelector autoColorwayId={activeAutoPreset} modalProps={props} onChange={autoPresetId => {
|
||||
|
@ -591,7 +589,7 @@ export default function ({
|
|||
{activeColorwayObject.id === color.name && activeColorwayObject.source === color.source && <circle cx="12" cy="12" r="5" className="radioIconForeground-3wH3aU" fill="currentColor" />}
|
||||
</svg>}
|
||||
<div className="discordColorwayPreviewColorContainer">
|
||||
{!color.isGradient ? colors.map((colorItm) => <div
|
||||
{!color.isGradient ? colors.map(colorItm => <div
|
||||
className="discordColorwayPreviewColor"
|
||||
style={{
|
||||
backgroundColor: color[colorItm],
|
||||
|
@ -609,9 +607,9 @@ export default function ({
|
|||
{(showLabelsInSelectorGridView || viewMode === "list") && <Text className={"colorwayLabel" + ((showLabelsInSelectorGridView && viewMode === "grid") ? " labelInGrid" : "")}>{color.name}</Text>}
|
||||
{settings.selectorType === "normal" && <div
|
||||
className="colorwayInfoIconContainer"
|
||||
onClick={(e) => {
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
openModal((props) => <ColorwayInfoModal
|
||||
openModal(props => <ColorwayInfoModal
|
||||
modalProps={props}
|
||||
colorway={color}
|
||||
loadUIProps={loadUI}
|
||||
|
@ -733,7 +731,7 @@ export default function ({
|
|||
{activeColorwayObject.id === color.name && activeColorwayObject.source === color.source && <circle cx="12" cy="12" r="5" className="radioIconForeground-3wH3aU" fill="currentColor" />}
|
||||
</svg>}
|
||||
<div className="discordColorwayPreviewColorContainer">
|
||||
{!color.isGradient ? colors.map((colorItm) => <div
|
||||
{!color.isGradient ? colors.map(colorItm => <div
|
||||
className="discordColorwayPreviewColor"
|
||||
style={{
|
||||
backgroundColor: color[colorItm],
|
||||
|
|
|
@ -26,8 +26,8 @@ const badVerbsReplacements = ["love", "eat", "deconstruct", "marry", "fart", "te
|
|||
const badNounsReplacements = ["pasta", "kebab", "cake", "potato", "woman", "computer", "java", "hamburger", "monster truck", "osu!", "Ukrainian ball in search of gas game", "Anime", "Anime girl", "good", "keyboard", "NVIDIA RTX 3090 Graphics Card", "storm", "queen", "single", "umbrella", "mosque", "physics", "bath", "virus", "bathroom", "mom", "owner", "airport", "Avast Antivirus Free"];
|
||||
|
||||
function replaceBadNouns(content) {
|
||||
// eslint-disable-next-line quotes
|
||||
const regex = new RegExp('\\b(' + badNouns.join('|') + ')\\b', 'gi');
|
||||
|
||||
const regex = new RegExp("\\b(" + badNouns.join("|") + ")\\b", "gi");
|
||||
|
||||
return content.replace(regex, function (match) {
|
||||
const randomIndex = Math.floor(Math.random() * badNounsReplacements.length);
|
||||
|
@ -36,8 +36,8 @@ function replaceBadNouns(content) {
|
|||
}
|
||||
|
||||
function replaceBadVerbs(content) {
|
||||
// eslint-disable-next-line quotes
|
||||
const regex = new RegExp('\\b(' + badVerbs.join('|') + ')\\b', 'gi');
|
||||
|
||||
const regex = new RegExp("\\b(" + badVerbs.join("|") + ")\\b", "gi");
|
||||
|
||||
return content.replace(regex, function (match) {
|
||||
const randomIndex = Math.floor(Math.random() * badVerbsReplacements.length);
|
||||
|
|
|
@ -28,7 +28,7 @@ export default new (class NoteHandler {
|
|||
},
|
||||
flags: message.flags,
|
||||
// Moment has a toString() function, this doesn't convert to '[object Object]'.
|
||||
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
||||
|
||||
timestamp: message.timestamp.toString(),
|
||||
attachments: message.attachments as Discord.Attachment[],
|
||||
embeds: message.embeds,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable simple-header/header */
|
||||
/* eslint-disable indent */
|
||||
|
||||
/*
|
||||
* Vencord, a modification for Discord's desktop app
|
||||
* Copyright (c) 2023 your mom lol
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
/* eslint-disable indent */
|
||||
import "./styles.css";
|
||||
|
||||
import { generateId } from "@api/Commands";
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { get } from "@main/utils/simpleGet";
|
||||
import { IpcEvents } from "@shared/IpcEvents";
|
||||
import { VENCORD_USER_AGENT } from "@shared/vencordUserAgent";
|
||||
import { app, dialog, ipcMain } from "electron";
|
||||
|
@ -25,7 +26,6 @@ import { join } from "path";
|
|||
import gitHash from "~git-hash";
|
||||
import gitRemote from "~git-remote";
|
||||
|
||||
import { get } from "../utils/simpleGet";
|
||||
import { ASAR_FILE, serializeErrors } from "./common";
|
||||
|
||||
const API_BASE = `https://api.github.com/repos/${gitRemote}`;
|
||||
|
|
1
src/modules.d.ts
vendored
1
src/modules.d.ts
vendored
|
@ -16,7 +16,6 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line spaced-comment
|
||||
/// <reference types="standalone-electron-types"/>
|
||||
|
||||
declare module "~plugins" {
|
||||
|
|
|
@ -26,9 +26,8 @@ export default definePlugin({
|
|||
patches: [{
|
||||
find: "Messages.MESSAGE_UTILITIES_A11Y_LABEL",
|
||||
replacement: {
|
||||
// foo && !bar ? createElement(reactionStuffs)... createElement(blah,...makeElement(reply-other))
|
||||
match: /\i&&!\i\?\(0,\i\.jsxs?\)\(.{0,200}renderEmojiPicker:.{0,500}\?(\i)\(\{key:"reply-other"(?<=message:(\i).+?)/,
|
||||
replace: (m, makeElement, msg) => `...Vencord.Api.MessagePopover._buildPopoverElements(${msg},${makeElement}),${m}`
|
||||
match: /"reply-self".+?Fragment,{children:\[(?=.+?\((\i\.\i),{label:)(?<=message:(\i).+?)/,
|
||||
replace: (m, PopoverButton, msg) => `${m}...Vencord.Api.MessagePopover._buildPopoverElements(${msg},${PopoverButton}),`
|
||||
}
|
||||
}],
|
||||
});
|
||||
|
|
|
@ -27,7 +27,7 @@ export default definePlugin({
|
|||
authors: [Devs.D3SOX, Devs.Nickyux],
|
||||
patches: [
|
||||
{
|
||||
find: ".PREMIUM_GUILD_SUBSCRIPTION_TOOLTIP",
|
||||
find: ".Messages.GUILD_OWNER,",
|
||||
replacement: {
|
||||
match: /,isOwner:(\i),/,
|
||||
replace: ",_isOwner:$1=$self.isGuildOwner(e),"
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
|
||||
.vc-st-modal-header {
|
||||
place-content: space-between center;
|
||||
place-content: center space-between;
|
||||
}
|
||||
|
||||
.vc-st-modal-header h1 {
|
||||
|
@ -43,4 +43,4 @@
|
|||
|
||||
.vc-st-button svg {
|
||||
transform: scale(1.1) translateY(1px);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -311,7 +311,7 @@ export default definePlugin({
|
|||
replacement: [
|
||||
{
|
||||
// Create a variable for the channel prop
|
||||
match: /maxUsers:\i,users:\i.+?}=(\i).*?;/,
|
||||
match: /users:\i,maxUsers:\i.+?}=(\i).*?;/,
|
||||
replace: (m, props) => `${m}let{shcChannel}=${props};`
|
||||
},
|
||||
{
|
||||
|
|
|
@ -165,7 +165,6 @@ function SeekBar() {
|
|||
|
||||
const [position, setPosition] = useState(storePosition);
|
||||
|
||||
// eslint-disable-next-line consistent-return
|
||||
useEffect(() => {
|
||||
if (isPlaying && !isSettingPosition) {
|
||||
setPosition(SpotifyStore.position);
|
||||
|
@ -358,7 +357,7 @@ export function Player() {
|
|||
const [shouldHide, setShouldHide] = useState(false);
|
||||
|
||||
// Hide player after 5 minutes of inactivity
|
||||
// eslint-disable-next-line consistent-return
|
||||
|
||||
React.useEffect(() => {
|
||||
setShouldHide(false);
|
||||
if (!isPlaying) {
|
||||
|
|
|
@ -102,9 +102,8 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0.2rem;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
align-content: flex-start;
|
||||
place-content: flex-start center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
}
|
||||
|
||||
.vc-trans-modal-header {
|
||||
place-content: space-between center;
|
||||
place-content: center space-between;
|
||||
}
|
||||
|
||||
.vc-trans-modal-header h1 {
|
||||
|
@ -37,4 +37,4 @@
|
|||
|
||||
.vc-trans-chat-button {
|
||||
scale: 1.085;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import { definePluginSettings } from "@api/Settings";
|
|||
import { makeRange } from "@components/PluginSettings/components";
|
||||
import { Devs } from "@utils/constants";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import definePlugin, { OptionType, ReporterTestable } from "@utils/types";
|
||||
import definePlugin, { OptionType, PluginNative, ReporterTestable } from "@utils/types";
|
||||
import { findByCodeLazy, findLazy } from "@webpack";
|
||||
import { Button, ChannelStore, GuildStore, UserStore } from "@webpack/common";
|
||||
import type { Channel, Embed, GuildMember, MessageAttachment, User } from "discord-types/general";
|
||||
|
@ -102,6 +102,12 @@ const settings = definePluginSettings({
|
|||
await start();
|
||||
}
|
||||
},
|
||||
preferUDP: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Enable if you use an older build of XSOverlay unable to connect through websockets. This setting is ignored on web.",
|
||||
default: false,
|
||||
disabled: () => IS_WEB
|
||||
},
|
||||
botNotifications: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Allow bot notifications",
|
||||
|
@ -178,6 +184,8 @@ async function start() {
|
|||
});
|
||||
}
|
||||
|
||||
const Native = VencordNative.pluginHelpers.XSOverlay as PluginNative<typeof import("./native")>;
|
||||
|
||||
export default definePlugin({
|
||||
name: "XSOverlay",
|
||||
description: "Forwards discord notifications to XSOverlay, for easy viewing in VR",
|
||||
|
@ -349,6 +357,10 @@ function sendOtherNotif(content: string, titleString: string) {
|
|||
}
|
||||
|
||||
async function sendToOverlay(notif: NotificationObject) {
|
||||
if (!IS_WEB && settings.store.preferUDP) {
|
||||
Native.sendToOverlay(notif);
|
||||
return;
|
||||
}
|
||||
const apiObject: ApiObject = {
|
||||
sender: "Vencord",
|
||||
target: "xsoverlay",
|
||||
|
|
16
src/plugins/xsOverlay/native.ts
Normal file
16
src/plugins/xsOverlay/native.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2023 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { createSocket, Socket } from "dgram";
|
||||
|
||||
let xsoSocket: Socket;
|
||||
|
||||
export function sendToOverlay(_, data: any) {
|
||||
data.messageType = data.type;
|
||||
const json = JSON.stringify(data);
|
||||
xsoSocket ??= createSocket("udp4");
|
||||
xsoSocket.send(json, 42069, "127.0.0.1");
|
||||
}
|
|
@ -165,11 +165,11 @@ const overrideObject = (obj, propertyName, overrideValue) => {
|
|||
}
|
||||
let overriden = false;
|
||||
for (const key in obj) {
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
|
||||
if (obj.hasOwnProperty(key) && key === propertyName) {
|
||||
obj[key] = overrideValue;
|
||||
overriden = true;
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
|
||||
} else if (obj.hasOwnProperty(key) && typeof obj[key] === "object") {
|
||||
if (overrideObject(obj[key], propertyName, overrideValue)) {
|
||||
overriden = true;
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
*/
|
||||
|
||||
import { LazyComponent } from "@utils/react";
|
||||
|
||||
import { FilterFn, filters, lazyWebpackSearchHistory, waitFor } from "../webpack";
|
||||
import { FilterFn, filters, lazyWebpackSearchHistory, waitFor } from "@webpack";
|
||||
|
||||
export function waitForComponent<T extends React.ComponentType<any> = React.ComponentType<any> & Record<string, any>>(name: string, filter: FilterFn | string | string[]): T {
|
||||
if (IS_REPORTER) lazyWebpackSearchHistory.push(["waitForComponent", Array.isArray(filter) ? filter : [filter]]);
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { filters, mapMangledModuleLazy, waitFor } from "../webpack";
|
||||
import { filters, mapMangledModuleLazy, waitFor } from "@webpack";
|
||||
|
||||
import type * as t from "./types/menu";
|
||||
|
||||
export let Menu = {} as t.Menu;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { findByPropsLazy, waitFor } from "../webpack";
|
||||
import { findByPropsLazy, waitFor } from "@webpack";
|
||||
|
||||
export let React: typeof import("react");
|
||||
export let useState: typeof React.useState;
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { findByCodeLazy, findByPropsLazy } from "@webpack";
|
||||
import type * as Stores from "discord-types/stores";
|
||||
|
||||
import { findByCodeLazy, findByPropsLazy } from "../webpack";
|
||||
import { waitForStore } from "./internal";
|
||||
import * as t from "./types/stores";
|
||||
|
||||
|
@ -66,7 +66,6 @@ export let DraftStore: t.DraftStore;
|
|||
*
|
||||
* @example const user = useStateFromStores([UserStore], () => UserStore.getCurrentUser(), null, (old, current) => old.id === current.id);
|
||||
*/
|
||||
// eslint-disable-next-line prefer-destructuring
|
||||
export const useStateFromStores: t.useStateFromStores = findByCodeLazy("useStateFromStores");
|
||||
|
||||
waitForStore("DraftStore", s => DraftStore = s);
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
*/
|
||||
|
||||
import { canonicalizeMatch } from "@utils/patches";
|
||||
import { _resolveReady, filters, findByCodeLazy, findByPropsLazy, findLazy, mapMangledModuleLazy, waitFor } from "@webpack";
|
||||
import type { Channel } from "discord-types/general";
|
||||
|
||||
import { _resolveReady, filters, findByCodeLazy, findByPropsLazy, findLazy, mapMangledModuleLazy, waitFor } from "../webpack";
|
||||
import type * as t from "./types/utils";
|
||||
|
||||
export let FluxDispatcher: t.FluxDispatcher;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { patches } from "@plugins";
|
||||
import { WEBPACK_CHUNK } from "@utils/constants";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { canonicalizeReplacement } from "@utils/patches";
|
||||
|
@ -23,7 +24,6 @@ import { PatchReplacement } from "@utils/types";
|
|||
import { WebpackInstance } from "discord-types/other";
|
||||
|
||||
import { traceFunction } from "../debug/Tracer";
|
||||
import { patches } from "../plugins";
|
||||
import { _initWebpack, beforeInitListeners, factoryListeners, moduleListeners, subscriptions, wreq } from ".";
|
||||
|
||||
const logger = new Logger("WebpackInterceptor", "#8caaee");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue