Compare commits
No commits in common. "main" and "2026-10-01" have entirely different histories.
main
...
2026-10-01
138 changed files with 1339 additions and 1055 deletions
|
|
@ -73,8 +73,8 @@ window.VencordNative = {
|
|||
updater: {
|
||||
getRepo: async () => ({ ok: true, value: "https://github.com/Equicord/Equicord" }),
|
||||
getUpdates: async () => ({ ok: true, value: [] }),
|
||||
fetchUpdate: async () => ({ ok: true, value: false }),
|
||||
applyUpdate: async () => ({ ok: true, value: true }),
|
||||
update: async () => ({ ok: true, value: false }),
|
||||
rebuild: async () => ({ ok: true, value: true }),
|
||||
},
|
||||
|
||||
quickCss: {
|
||||
|
|
@ -136,4 +136,9 @@ window.VencordNative = {
|
|||
|
||||
pluginHelpers: {} as any,
|
||||
csp: {} as any,
|
||||
tray: {
|
||||
setUpdateState: NOOP,
|
||||
onCheckUpdates: NOOP,
|
||||
onRepair: NOOP,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@
|
|||
"typescript-transform-paths": "^3.5.6",
|
||||
"zip-local": "^0.3.5"
|
||||
},
|
||||
"packageManager": "pnpm@12.8.1",
|
||||
"packageManager": "pnpm@12.6.0",
|
||||
"engines": {
|
||||
"node": ">=22"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,8 +53,3 @@ export const enum PremiumType {
|
|||
TIER_2 = 2,
|
||||
TIER_0 = 3,
|
||||
}
|
||||
|
||||
export const enum ToastPosition {
|
||||
TOP = 0,
|
||||
BOTTOM = 1,
|
||||
}
|
||||
|
|
|
|||
1
packages/discord-types/src/index.d.ts
vendored
1
packages/discord-types/src/index.d.ts
vendored
|
|
@ -7,6 +7,5 @@ export * from "./fluxEvents";
|
|||
export * from "./menu";
|
||||
export * from "./modules";
|
||||
export * from "./stores";
|
||||
export * from "./toasts";
|
||||
export * from "./utils";
|
||||
export * as Webpack from "../webpack";
|
||||
|
|
|
|||
35
packages/discord-types/src/toasts.d.ts
vendored
35
packages/discord-types/src/toasts.d.ts
vendored
|
|
@ -1,35 +0,0 @@
|
|||
import type { ComponentType } from "react";
|
||||
import { ToastPosition } from "../enums";
|
||||
|
||||
export type ToastType = "message" | "success" | "failure" | "custom" | "clip" | "link" | "forward" | "bookmark" | "clock";
|
||||
|
||||
export type NewToastVariant = "default" | "success" | "critical";
|
||||
export type NewToastPosition = "top" | "bottom";
|
||||
|
||||
export interface ToastData {
|
||||
message: string;
|
||||
type?: ToastType;
|
||||
options?: {
|
||||
position?: ToastPosition;
|
||||
duration?: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface NewToastData {
|
||||
text: string;
|
||||
variant: NewToastVariant;
|
||||
position?: NewToastPosition;
|
||||
duration?: number;
|
||||
|
||||
icon?: ComponentType;
|
||||
iconColor?: any;
|
||||
}
|
||||
|
||||
export type showToast = (data: NewToastData) => void;
|
||||
export type popToast = (context?: string) => void;
|
||||
export type createToast = (data: ToastData) => NewToastData;
|
||||
|
||||
export interface Toasts {
|
||||
show: showToast;
|
||||
pop: popToast;
|
||||
}
|
||||
43
packages/discord-types/src/utils.d.ts
vendored
43
packages/discord-types/src/utils.d.ts
vendored
|
|
@ -416,46 +416,3 @@ export interface EmojiUtils {
|
|||
triggerFullscreenAnimation(emoji: any, node: HTMLElement): void;
|
||||
applyPlatformToThemedEmojiColorPalette(colors: any): any;
|
||||
}
|
||||
|
||||
export interface OpenUserSettingsOptions {
|
||||
/**
|
||||
* a *sub*section of settings to navigate to
|
||||
*
|
||||
* to navigate to a top-level section, use the navigationTarget parameter of {@link SettingsRouter.openUserSettings} instead
|
||||
*
|
||||
* discord has an enum with all the possible values (go dig in the {@link SettingsRouter.openUserSettings} source)
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* modal stacking behavior, defaults to "replaceAll"
|
||||
*/
|
||||
stackingBehavior?: "replaceAll" | "stack" | "replace";
|
||||
// ... misc analytics options
|
||||
}
|
||||
|
||||
export interface SettingsRouter {
|
||||
openUserSettings(navigationTarget?: string, opts?: OpenUserSettingsOptions, onOpen?: () => void): Promise<void>;
|
||||
}
|
||||
|
||||
export interface OpenUserProfileModalOptions {
|
||||
userId: string;
|
||||
guildId?: string | null;
|
||||
originGuildId?: string | null;
|
||||
channelId?: string | null;
|
||||
messageId?: string | null;
|
||||
roleId?: string | null;
|
||||
sessionId?: unknown | null;
|
||||
joinRequestId?: unknown;
|
||||
tabSection?: unknown;
|
||||
scrollTarget?: unknown;
|
||||
hideRestrictedProfile?: boolean;
|
||||
sourceAnalyticsLocations?: string[];
|
||||
appContext?: unknown;
|
||||
/**
|
||||
* defaults to null
|
||||
*/
|
||||
customStatusPrompt?: unknown;
|
||||
onModalOpen?: unknown;
|
||||
}
|
||||
|
||||
export type OpenUserProfileModal = (opts: OpenUserProfileModalOptions) => Promise<void>;
|
||||
|
|
|
|||
122
pnpm-lock.yaml
generated
122
pnpm-lock.yaml
generated
|
|
@ -7,153 +7,153 @@ importers:
|
|||
configDependencies: {}
|
||||
packageManagerDependencies:
|
||||
pnpm:
|
||||
specifier: 12.8.1
|
||||
version: 12.8.1
|
||||
specifier: 12.6.0
|
||||
version: 12.6.0
|
||||
|
||||
packages:
|
||||
|
||||
'@pnpm/exe.android-arm64@12.8.1':
|
||||
resolution: {integrity: sha512-siDxcidfz5eM6L2tJfik+i2bbUEw8UC7MZ3Yl2HYdRmqbdhHGAOQACtOOu6QVW4Jul4/w5wVKm+wM8ACtgh1Pg==}
|
||||
'@pnpm/exe.android-arm64@12.6.0':
|
||||
resolution: {integrity: sha512-kviIHft9h02q+7N2In7tSL9T/HRUSGwYmU74YPtsWU5ee7vgqPyC0JT6RRX6miW+NxX1CvHgQxg69qq1qTLJYQ==}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@pnpm/exe.android-x64@12.8.1':
|
||||
resolution: {integrity: sha512-0F/uqPRc3aN4vLHsa0f+6fTtmsigFQ9/yxEU43fionF//pNHEd5e97b3w/nKIgqYMCUQCJphmBRMA9Q8/wlo9Q==}
|
||||
'@pnpm/exe.android-x64@12.6.0':
|
||||
resolution: {integrity: sha512-CT8aJKLq2mtZFE71pr4E5Z2xHL8uGnRGr+NclDqsXlVF4SVcQ2QAs14mWi0C8gjT4hbmi+Q0lJRRIkMAWfjjng==}
|
||||
cpu: [x64]
|
||||
os: [android]
|
||||
|
||||
'@pnpm/exe.darwin-arm64@12.8.1':
|
||||
resolution: {integrity: sha512-/rwavvMQJsl2RIxOHBnDF+4Gk+fhQFAY4M3PQZoKskJOEnaJcygG9p1xby6wcQcbS4d9dIubv09CQhufTgfmpw==}
|
||||
'@pnpm/exe.darwin-arm64@12.6.0':
|
||||
resolution: {integrity: sha512-rafpVkjzugKBMxSvGQd5wK1x5eOTkD/+lcJIFHeQhvd+BJ8kDisOOvwhQDrpGd4vd2Fx+hhW0P2Ptt638OlhFg==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@pnpm/exe.darwin-x64@12.8.1':
|
||||
resolution: {integrity: sha512-htYt2gN7zqJKLhC99Ft6EUiO7myjZAZXfmGCTJUL1v+o7vE9hZdE1+fAkk4Oj1ZHNRti6b2woOxEkRkAusi8OQ==}
|
||||
'@pnpm/exe.darwin-x64@12.6.0':
|
||||
resolution: {integrity: sha512-72Jpuv1m24gI8zUNcaylYpBWEhBzz1VPhnDIU2GYM2eRP+KsOqVLwV78i+JrihI39zY2NNXmaN4eAKX1inpaDQ==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@pnpm/exe.freebsd-x64@12.8.1':
|
||||
resolution: {integrity: sha512-PB5BULNgytxvExoOXUUeseS/DcpPENs+cg3iA6xHHeaLT4ctEGKSGXEbuj7USeqvo8JBpAx039hivnbzGqDwnA==}
|
||||
'@pnpm/exe.freebsd-x64@12.6.0':
|
||||
resolution: {integrity: sha512-LON4QgNy1w/XF4uySZIyC/5hEB0oGdelXsY9tSKqstER+2j2X2oHz67skD11RRd/HWFRtMr64shQZ4I9ZoZ0zg==}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@pnpm/exe.linux-arm64-musl@12.8.1':
|
||||
resolution: {integrity: sha512-kKeyC/ArjrgdciQRBrOL0j9HtOI4gDRgoyP+eJ1CQKyadpKlf/DhDDyspXe07R3B9KagTVLUF2nlt6Dr5quFIg==}
|
||||
'@pnpm/exe.linux-arm64-musl@12.6.0':
|
||||
resolution: {integrity: sha512-BdDpX+DeaMUc5x6WNcE6FkmFy36NwrBbBvwsZU737Zt3u1fTY+iKFPchjEQNCM4rT6q6xvF2oN3ZwExGsJCkxQ==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@pnpm/exe.linux-arm64@12.8.1':
|
||||
resolution: {integrity: sha512-q4s9a9X2O3N9aeUFooW24orNrxvu20+jyVUFR5RanPCqOKKPBrgs2iywMkBBx1aXkkzdWT54/mfz8Be8sJlWEw==}
|
||||
'@pnpm/exe.linux-arm64@12.6.0':
|
||||
resolution: {integrity: sha512-8h2sNoIhHDpHDYqZZCh9PXr6krqW10btb0GHVGuw710muDHlFAHMtUG2ogmaHge6zJG1xgY4Y7mwX5g/LWvrYg==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@pnpm/exe.linux-ppc64@12.8.1':
|
||||
resolution: {integrity: sha512-F7XSjKJthwCh/L6abZiMpAfo2Cm61SZIT3e4dfgiIjESndlWaXCnfLKngSgZ/SEMsdmHT6dud3+kWIB3tw0/xQ==}
|
||||
'@pnpm/exe.linux-ppc64@12.6.0':
|
||||
resolution: {integrity: sha512-ld6xgcEhFCFrsVsJhbmdmR714PnsEspO/Ij8w0/D7OSiz2hYGu3fZd5tKRxOI5m6H6Gl0/RRFAPncTHbsgXVjQ==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@pnpm/exe.linux-riscv64@12.8.1':
|
||||
resolution: {integrity: sha512-z1ecpIK/ZY08Unk69KWWE9867oaKUytGUjrHnBoGFAAhsK+q+0cfvBH+f5fWobJ7FX97leMlLO+gkJolddM45Q==}
|
||||
'@pnpm/exe.linux-riscv64@12.6.0':
|
||||
resolution: {integrity: sha512-HIbImydoC3J8NFt+8MXfhTCf5rO6NjCMyinSAHac0VmV8uCHw+kbQkyAzxV84rzz9ZOzmBOnj0b1N461UIYGsw==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@pnpm/exe.linux-s390x@12.8.1':
|
||||
resolution: {integrity: sha512-KU6tnrBfu4uKXTq6N5qJwSm8FSrs9Wc8b5AUEsHK9bRXwNdsZ1/lRxG1++X29SKRW9OSNuDSjxASv5mAvGo1gA==}
|
||||
'@pnpm/exe.linux-s390x@12.6.0':
|
||||
resolution: {integrity: sha512-DjSqT7+BZ/lWcDHwNMuzsRVfyxUimh+D54Xw4tSWbdVVQhtWtNMUyI93LVnwCmsoEpar2gC3SFeAgywx37svKQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@pnpm/exe.linux-x64-musl@12.8.1':
|
||||
resolution: {integrity: sha512-eUE8BWJkDr2tJb/yrk0yVnszlmNqFarVxUlqiZ9BAkct28Nq/5g2H0tvMDmPA7fAQW3STNj+omJPPRVT+4s5sQ==}
|
||||
'@pnpm/exe.linux-x64-musl@12.6.0':
|
||||
resolution: {integrity: sha512-31lKeGPmRE6xfV6I3VjaEGVFRei14pl/zgoFDK4w+UkbJqOuNl2Ht3O1GuqNIg3Gl14qTEb4kZRAYFHXifDx9A==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@pnpm/exe.linux-x64@12.8.1':
|
||||
resolution: {integrity: sha512-8bDZ0lZlCdi2rvnFul7EYgcC7zKeWSe76y8JV2oXobaS8p9i9d6PSf6LgLtTM0fI7R9Oh4eLCbveXyNDMmvZ+g==}
|
||||
'@pnpm/exe.linux-x64@12.6.0':
|
||||
resolution: {integrity: sha512-qFWBneHJAJ73W4whtbaFOL1M/7DBC6ILHXuxc7ZPtEhfPuT1zeZiGrmKHoMAfJA+mcm6xhOFljqVTUS+00Jabw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@pnpm/exe.win32-arm64@12.8.1':
|
||||
resolution: {integrity: sha512-MsT0dlrRxnCRCHCaosNbhWpEiAFnFuMEu3KuDJDU41BXgTwiINxU8goloUSUDejWZUqKaUqNC/qUTihl9nFtqg==}
|
||||
'@pnpm/exe.win32-arm64@12.6.0':
|
||||
resolution: {integrity: sha512-OhfefXEEykZlslSUhR8PPRe6MVPV3Oink/dVfIecE5velpc7j80cZYsHlaDrtRDcm3TPwQHkaRW1SJ1efX9oFg==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@pnpm/exe.win32-x64@12.8.1':
|
||||
resolution: {integrity: sha512-SWtPe0PsbTTk//gJND10tMdOfCYjrkq5+qV49hzVhY7xz2iJ339Rc+xwASlcvbwTfrvH39YNqpKYibD+CRGLwA==}
|
||||
'@pnpm/exe.win32-x64@12.6.0':
|
||||
resolution: {integrity: sha512-L2tuyrD2+Imgxs3VK/ST/2L3xD6vDP0ktJQxM0TaGw7TbAQEMq+RMc8iK6Ew7Id579uzjJe8jSfJID2ZGsOHCA==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
pnpm@12.8.1:
|
||||
resolution: {integrity: sha512-9kupB1B/XOr+BsjTjmBS0BeURFgOwSed3Vv8EctIqoomRLZlmOB+dh2oSHKp/FfV+QK4f6SdAkGY1VhhKqu+RQ==}
|
||||
pnpm@12.6.0:
|
||||
resolution: {integrity: sha512-PvaPlRyxEawgS0paFvCy3fDaVqluBBPoHYVdnwtV75JnFHCQKOHNAMQFwsX7e56OxNxGd3yAXQNzwvL/AP0g7A==}
|
||||
engines: {node: '>=18.*'}
|
||||
hasBin: true
|
||||
|
||||
snapshots:
|
||||
|
||||
'@pnpm/exe.android-arm64@12.8.1':
|
||||
'@pnpm/exe.android-arm64@12.6.0':
|
||||
optional: true
|
||||
|
||||
'@pnpm/exe.android-x64@12.8.1':
|
||||
'@pnpm/exe.android-x64@12.6.0':
|
||||
optional: true
|
||||
|
||||
'@pnpm/exe.darwin-arm64@12.8.1':
|
||||
'@pnpm/exe.darwin-arm64@12.6.0':
|
||||
optional: true
|
||||
|
||||
'@pnpm/exe.darwin-x64@12.8.1':
|
||||
'@pnpm/exe.darwin-x64@12.6.0':
|
||||
optional: true
|
||||
|
||||
'@pnpm/exe.freebsd-x64@12.8.1':
|
||||
'@pnpm/exe.freebsd-x64@12.6.0':
|
||||
optional: true
|
||||
|
||||
'@pnpm/exe.linux-arm64-musl@12.8.1':
|
||||
'@pnpm/exe.linux-arm64-musl@12.6.0':
|
||||
optional: true
|
||||
|
||||
'@pnpm/exe.linux-arm64@12.8.1':
|
||||
'@pnpm/exe.linux-arm64@12.6.0':
|
||||
optional: true
|
||||
|
||||
'@pnpm/exe.linux-ppc64@12.8.1':
|
||||
'@pnpm/exe.linux-ppc64@12.6.0':
|
||||
optional: true
|
||||
|
||||
'@pnpm/exe.linux-riscv64@12.8.1':
|
||||
'@pnpm/exe.linux-riscv64@12.6.0':
|
||||
optional: true
|
||||
|
||||
'@pnpm/exe.linux-s390x@12.8.1':
|
||||
'@pnpm/exe.linux-s390x@12.6.0':
|
||||
optional: true
|
||||
|
||||
'@pnpm/exe.linux-x64-musl@12.8.1':
|
||||
'@pnpm/exe.linux-x64-musl@12.6.0':
|
||||
optional: true
|
||||
|
||||
'@pnpm/exe.linux-x64@12.8.1':
|
||||
'@pnpm/exe.linux-x64@12.6.0':
|
||||
optional: true
|
||||
|
||||
'@pnpm/exe.win32-arm64@12.8.1':
|
||||
'@pnpm/exe.win32-arm64@12.6.0':
|
||||
optional: true
|
||||
|
||||
'@pnpm/exe.win32-x64@12.8.1':
|
||||
'@pnpm/exe.win32-x64@12.6.0':
|
||||
optional: true
|
||||
|
||||
pnpm@12.8.1:
|
||||
pnpm@12.6.0:
|
||||
optionalDependencies:
|
||||
'@pnpm/exe.android-arm64': 12.8.1
|
||||
'@pnpm/exe.android-x64': 12.8.1
|
||||
'@pnpm/exe.darwin-arm64': 12.8.1
|
||||
'@pnpm/exe.darwin-x64': 12.8.1
|
||||
'@pnpm/exe.freebsd-x64': 12.8.1
|
||||
'@pnpm/exe.linux-arm64': 12.8.1
|
||||
'@pnpm/exe.linux-arm64-musl': 12.8.1
|
||||
'@pnpm/exe.linux-ppc64': 12.8.1
|
||||
'@pnpm/exe.linux-riscv64': 12.8.1
|
||||
'@pnpm/exe.linux-s390x': 12.8.1
|
||||
'@pnpm/exe.linux-x64': 12.8.1
|
||||
'@pnpm/exe.linux-x64-musl': 12.8.1
|
||||
'@pnpm/exe.win32-arm64': 12.8.1
|
||||
'@pnpm/exe.win32-x64': 12.8.1
|
||||
'@pnpm/exe.android-arm64': 12.6.0
|
||||
'@pnpm/exe.android-x64': 12.6.0
|
||||
'@pnpm/exe.darwin-arm64': 12.6.0
|
||||
'@pnpm/exe.darwin-x64': 12.6.0
|
||||
'@pnpm/exe.freebsd-x64': 12.6.0
|
||||
'@pnpm/exe.linux-arm64': 12.6.0
|
||||
'@pnpm/exe.linux-arm64-musl': 12.6.0
|
||||
'@pnpm/exe.linux-ppc64': 12.6.0
|
||||
'@pnpm/exe.linux-riscv64': 12.6.0
|
||||
'@pnpm/exe.linux-s390x': 12.6.0
|
||||
'@pnpm/exe.linux-x64': 12.6.0
|
||||
'@pnpm/exe.linux-x64-musl': 12.6.0
|
||||
'@pnpm/exe.win32-arm64': 12.6.0
|
||||
'@pnpm/exe.win32-x64': 12.6.0
|
||||
|
||||
---
|
||||
lockfileVersion: '9.0'
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
import "~plugins";
|
||||
import "./fixWeirdAppRegionBug.css";
|
||||
|
||||
import nativeTitleBarStyles from "./nativeTitleBar.css?managed";
|
||||
|
||||
export * as Api from "./api";
|
||||
export * as Plugins from "./api/PluginManager";
|
||||
export * as Components from "./components";
|
||||
|
|
@ -31,20 +29,22 @@ export * as Webpack from "./webpack";
|
|||
export * as WebpackPatcher from "./webpack/patchWebpack";
|
||||
export { PlainSettings, Settings };
|
||||
|
||||
import { enableStyle, initStyles } from "@api/Styles";
|
||||
import { coreStyleRootNode, initStyles } from "@api/Styles";
|
||||
import { openSettingsTabModal, UpdaterTab } from "@components/settings";
|
||||
import { debounce } from "@shared/debounce";
|
||||
import { IS_WINDOWS } from "@utils/constants";
|
||||
import { createAndAppendStyle } from "@utils/css";
|
||||
import { StartAt } from "@utils/types";
|
||||
import { SettingsRouter } from "@webpack/common";
|
||||
|
||||
import { get as dsGet } from "./api/DataStore";
|
||||
import { showNotice } from "./api/Notices";
|
||||
import { popNotice, showNotice } from "./api/Notices";
|
||||
import { NotificationData, showNotification } from "./api/Notifications";
|
||||
import { initPluginManager, PMLogger, startAllPlugins } from "./api/PluginManager";
|
||||
import { PlainSettings, Settings, SettingsStore } from "./api/Settings";
|
||||
import { areLocalSettingsDirty, getCloudSettings, getCloudSyncDirection, markLocalSettingsDirty, putCloudSettings, shouldCloudSync } from "./api/SettingsSync/cloudSync";
|
||||
import { relaunch } from "./utils/native";
|
||||
import { checkForUpdates, update, UpdateLogger } from "./utils/updater";
|
||||
import { checkForUpdates, isOutdated as getIsOutdated, update, UpdateLogger } from "./utils/updater";
|
||||
import { onceReady } from "./webpack";
|
||||
import { patches } from "./webpack/patchWebpack";
|
||||
|
||||
|
|
@ -137,6 +137,7 @@ async function runUpdateCheck() {
|
|||
|
||||
try {
|
||||
const isOutdated = await checkForUpdates();
|
||||
if (IS_DISCORD_DESKTOP) VencordNative.tray.setUpdateState(isOutdated);
|
||||
if (!isOutdated) return;
|
||||
|
||||
if (Settings.autoUpdate) {
|
||||
|
|
@ -167,11 +168,43 @@ async function runUpdateCheck() {
|
|||
}
|
||||
}
|
||||
|
||||
function initTrayIpc() {
|
||||
if (IS_WEB || IS_UPDATER_DISABLED) return;
|
||||
|
||||
VencordNative.tray.onCheckUpdates(async () => {
|
||||
try {
|
||||
const isOutdated = await checkForUpdates();
|
||||
VencordNative.tray.setUpdateState(isOutdated);
|
||||
|
||||
if (isOutdated) {
|
||||
showNotice("An Equicord update is available!", "View Update", () => openSettingsTabModal(UpdaterTab!));
|
||||
} else {
|
||||
showNotice("No updates available, you're on the latest version!", "OK", popNotice);
|
||||
}
|
||||
} catch (err) {
|
||||
UpdateLogger.error("Failed to check for updates from tray", err);
|
||||
showNotice("Failed to check for updates, check the console for more info", "OK", popNotice);
|
||||
}
|
||||
});
|
||||
|
||||
VencordNative.tray.onRepair(async () => {
|
||||
try {
|
||||
await update();
|
||||
relaunch();
|
||||
} catch (err) {
|
||||
UpdateLogger.error("Failed to repair Equicord", err);
|
||||
}
|
||||
});
|
||||
|
||||
VencordNative.tray.setUpdateState(getIsOutdated);
|
||||
}
|
||||
|
||||
async function init() {
|
||||
await onceReady;
|
||||
startAllPlugins(StartAt.WebpackReady);
|
||||
|
||||
syncSettings();
|
||||
initTrayIpc();
|
||||
|
||||
if (!IS_DEV && !IS_WEB && !IS_UPDATER_DISABLED) {
|
||||
runUpdateCheck();
|
||||
|
|
@ -204,7 +237,8 @@ init();
|
|||
document.addEventListener("DOMContentLoaded", () => {
|
||||
startAllPlugins(StartAt.DOMContentLoaded);
|
||||
|
||||
if (IS_DISCORD_DESKTOP && Settings.nativeTitleBar) {
|
||||
enableStyle(nativeTitleBarStyles);
|
||||
// FIXME
|
||||
if (IS_DISCORD_DESKTOP && Settings.winNativeTitleBar && IS_WINDOWS) {
|
||||
createAndAppendStyle("vencord-native-titlebar-style", coreStyleRootNode).textContent = "[class*=titleBar]{display: none!important}";
|
||||
}
|
||||
}, { once: true });
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import type { Settings } from "@api/Settings";
|
|||
import type { CspRequestResult } from "@main/csp/manager";
|
||||
import type { PluginIpcMappings } from "@main/ipcPlugins";
|
||||
import { UserThemeHeader } from "@main/themes";
|
||||
import { UpdateData } from "@main/updater";
|
||||
import { IpcEvents } from "@shared/IpcEvents";
|
||||
import type { IpcRes } from "@utils/types";
|
||||
import { ipcRenderer } from "electron/renderer";
|
||||
|
|
@ -47,10 +46,10 @@ export default {
|
|||
},
|
||||
|
||||
updater: {
|
||||
getRepo: () => invoke<IpcRes<string>>(IpcEvents.UPDATER_GET_REPO),
|
||||
getUpdates: () => invoke<IpcRes<UpdateData[]>>(IpcEvents.UPDATER_LIST_UPDATES),
|
||||
fetchUpdate: () => invoke<IpcRes<boolean>>(IpcEvents.UPDATER_FETCH_UPDATE),
|
||||
applyUpdate: () => invoke<IpcRes<boolean>>(IpcEvents.UPDATER_APPLY_UPDATE),
|
||||
getUpdates: () => invoke<IpcRes<Record<"hash" | "author" | "message", string>[]>>(IpcEvents.GET_UPDATES),
|
||||
update: () => invoke<IpcRes<boolean>>(IpcEvents.UPDATE),
|
||||
rebuild: () => invoke<IpcRes<boolean>>(IpcEvents.BUILD),
|
||||
getRepo: () => invoke<IpcRes<string>>(IpcEvents.GET_REPO),
|
||||
},
|
||||
|
||||
settings: {
|
||||
|
|
@ -102,5 +101,11 @@ export default {
|
|||
invoke<CspRequestResult>(IpcEvents.CSP_REQUEST_ADD_OVERRIDE, url, directives, callerName),
|
||||
},
|
||||
|
||||
tray: {
|
||||
setUpdateState: (available: boolean) => ipcRenderer.send(IpcEvents.SET_TRAY_UPDATE_STATE, available),
|
||||
onCheckUpdates: (cb: () => void) => { ipcRenderer.on(IpcEvents.TRAY_CHECK_UPDATES, cb); },
|
||||
onRepair: (cb: () => void) => { ipcRenderer.on(IpcEvents.TRAY_REPAIR, cb); },
|
||||
},
|
||||
|
||||
pluginHelpers: PluginHelpers
|
||||
};
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ export interface Settings {
|
|||
| undefined;
|
||||
windowsMaterial: "none" | "mica" | "tabbed" | "acrylic";
|
||||
disableMinSize: boolean;
|
||||
nativeTitleBar: boolean;
|
||||
winNativeTitleBar: boolean;
|
||||
plugins: {
|
||||
[plugin: string]: {
|
||||
enabled: boolean;
|
||||
|
|
@ -124,7 +124,7 @@ const DefaultSettings: Settings = {
|
|||
macosVibrancyStyle: undefined,
|
||||
windowsMaterial: "none",
|
||||
disableMinSize: false,
|
||||
nativeTitleBar: false,
|
||||
winNativeTitleBar: false,
|
||||
plugins: {},
|
||||
|
||||
uiElements: {
|
||||
|
|
|
|||
|
|
@ -7,17 +7,24 @@
|
|||
import { PlainSettings } from "@api/Settings";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { chooseFile, saveFile } from "@utils/web";
|
||||
import { moment, showToast } from "@webpack/common";
|
||||
import { moment, Toasts } from "@webpack/common";
|
||||
|
||||
import { DataStore } from "..";
|
||||
|
||||
type BackupType = "all" | "plugins" | "css" | "datastore";
|
||||
|
||||
const toast = (type: string, message: string) =>
|
||||
Toasts.show({
|
||||
type,
|
||||
message,
|
||||
id: Toasts.genId()
|
||||
});
|
||||
|
||||
const toastSuccess = () =>
|
||||
showToast("Settings successfully imported. Restart to apply changes!", "success");
|
||||
toast(Toasts.Type.SUCCESS, "Settings successfully imported. Restart to apply changes!");
|
||||
|
||||
const toastFailure = (err: any) =>
|
||||
showToast(`Failed to import settings: ${String(err)}`, "failure");
|
||||
toast(Toasts.Type.FAILURE, `Failed to import settings: ${String(err)}`);
|
||||
|
||||
const logger = new Logger("SettingsSync:Offline", "#39b7e0");
|
||||
|
||||
|
|
@ -111,7 +118,7 @@ export async function exportSettings({ syncDataStore = true, type = "all", minif
|
|||
|
||||
if (type === "all") {
|
||||
logger.warn("Skipping DataStore in backup due to size. Export DataStore separately if needed.");
|
||||
showToast("DataStore too large - exported without it. Use 'Export DataStore' separately if needed.", "message");
|
||||
toast(Toasts.Type.MESSAGE, "DataStore too large - exported without it. Use 'Export DataStore' separately if needed.");
|
||||
dataStore = undefined;
|
||||
} else if (type === "datastore") {
|
||||
throw new Error("DataStore is too large to export. Please clear some plugin data and try again.");
|
||||
|
|
@ -149,7 +156,7 @@ export async function downloadSettingsBackup(type: BackupType = "all", { minify
|
|||
}
|
||||
} catch (err) {
|
||||
logger.error("Failed to export settings:", err);
|
||||
showToast("Failed to export settings, check console", "failure");
|
||||
toast(Toasts.Type.FAILURE, "Failed to export settings, check console");
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ import { HashLink } from "@components/settings/tabs/updater/Components";
|
|||
import { Margins } from "@utils/margins";
|
||||
import { useAwaiter } from "@utils/react";
|
||||
import { getRepo, UpdateLogger } from "@utils/updater";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { Alerts, React, showToast } from "@webpack/common";
|
||||
import { Alerts, React, Toasts } from "@webpack/common";
|
||||
|
||||
import gitHash from "~git-hash";
|
||||
|
||||
|
|
@ -353,8 +352,13 @@ function ChangelogContent() {
|
|||
const logged = await ensureLocalUpdateLogged();
|
||||
if (!logged) {
|
||||
setChangelog([]);
|
||||
showToast("Already up to date with repository", "message", {
|
||||
position: ToastPosition.BOTTOM,
|
||||
Toasts.show({
|
||||
message: "Already up to date with repository",
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.MESSAGE,
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM,
|
||||
},
|
||||
});
|
||||
}
|
||||
return;
|
||||
|
|
@ -380,16 +384,26 @@ function ChangelogContent() {
|
|||
await loadChangelogHistory();
|
||||
setRecentlyChecked(true);
|
||||
|
||||
showToast(`Found ${updates.value.length} commit${updates.value.length === 1 ? "" : "s"} from repository`, "success", {
|
||||
position: ToastPosition.BOTTOM,
|
||||
Toasts.show({
|
||||
message: `Found ${updates.value.length} commit${updates.value.length === 1 ? "" : "s"} from repository`,
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.SUCCESS,
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const logged = await ensureLocalUpdateLogged();
|
||||
setRecentlyChecked(true);
|
||||
showToast(logged
|
||||
? "Logged commits from your latest update"
|
||||
: "Repository is up to date with your local copy", logged ? "success" : "message", {
|
||||
position: ToastPosition.BOTTOM,
|
||||
Toasts.show({
|
||||
message: logged
|
||||
? "Logged commits from your latest update"
|
||||
: "Repository is up to date with your local copy",
|
||||
id: Toasts.genId(),
|
||||
type: logged ? Toasts.Type.SUCCESS : Toasts.Type.MESSAGE,
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM,
|
||||
},
|
||||
});
|
||||
if (!logged) {
|
||||
setChangelog([]);
|
||||
|
|
@ -408,8 +422,13 @@ function ChangelogContent() {
|
|||
setError(errorMessage);
|
||||
|
||||
// funny little error toast hopefully doesn't happen!
|
||||
showToast("Could not fetch commits from repository", "failure", {
|
||||
position: ToastPosition.BOTTOM,
|
||||
Toasts.show({
|
||||
message: "Could not fetch commits from repository",
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.FAILURE,
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM,
|
||||
},
|
||||
});
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
|
|
@ -501,8 +520,13 @@ function ChangelogContent() {
|
|||
await clearChangelogHistory();
|
||||
await loadChangelogHistory();
|
||||
setShowHistory(false);
|
||||
showToast("All logs have been cleared", "success", {
|
||||
position: ToastPosition.BOTTOM,
|
||||
Toasts.show({
|
||||
message: "All logs have been cleared",
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.SUCCESS,
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
@ -635,8 +659,13 @@ function ChangelogContent() {
|
|||
Array.from(expandedLogs).filter(id => id !== logId),
|
||||
),
|
||||
);
|
||||
showToast("Log has been cleared", "success", {
|
||||
position: ToastPosition.BOTTOM,
|
||||
Toasts.show({
|
||||
message: "Log has been cleared",
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.SUCCESS,
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ import { AddonCard } from "@components/settings/AddonCard";
|
|||
import { classNameFactory } from "@utils/css";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { Plugin } from "@utils/types";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { React, showToast } from "@webpack/common";
|
||||
import { React, showToast, Toasts } from "@webpack/common";
|
||||
|
||||
import { PluginMeta } from "~plugins";
|
||||
|
||||
|
|
@ -80,7 +79,9 @@ export function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, on
|
|||
settings.enabled = false;
|
||||
|
||||
const msg = `Error while ${wasEnabled ? "stopping" : "starting"} plugin ${plugin.name}`;
|
||||
showToast(msg, "failure", { position: ToastPosition.BOTTOM });
|
||||
showToast(msg, Toasts.Type.FAILURE, {
|
||||
position: Toasts.Position.BOTTOM,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,9 +34,8 @@ import { Margins } from "@utils/margins";
|
|||
import { classes, isObjectEmpty } from "@utils/misc";
|
||||
import { OptionType, Plugin, PluginTag } from "@utils/types";
|
||||
import { RenderModalProps, User } from "@vencord/discord-types";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { findComponentByCodeLazy, findCssClassesLazy } from "@webpack";
|
||||
import { Clickable, FluxDispatcher, Modal, openModal, React, showToast,Text, Tooltip, useEffect, useMemo, UserStore, UserSummaryItem, UserUtils, useState } from "@webpack/common";
|
||||
import { Clickable, FluxDispatcher, Modal, openModal, React, Text, Toasts, Tooltip, useEffect, useMemo, UserStore, UserSummaryItem, UserUtils, useState } from "@webpack/common";
|
||||
import { Constructor } from "type-fest";
|
||||
|
||||
import { PluginMeta } from "~plugins";
|
||||
|
|
@ -325,9 +324,14 @@ function resetSettings(plugin: Plugin, onRestartNeeded?: (pluginName: string) =>
|
|||
onRestartNeeded?.(plugin.name);
|
||||
}
|
||||
|
||||
showToast(`Settings for ${pluginName} have been reset.`, "success", {
|
||||
position: ToastPosition.TOP
|
||||
});
|
||||
Toasts.show({
|
||||
message: `Settings for ${pluginName} have been reset.`,
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.SUCCESS,
|
||||
options: {
|
||||
position: Toasts.Position.TOP
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function openWarningModal(plugin?: Plugin | null, onRestartNeeded?: (pluginName: string) => void, isPlugin = true, enabledPlugins?: number | null, reset?: () => void) {
|
||||
|
|
|
|||
|
|
@ -38,8 +38,7 @@ import { classes } from "@utils/misc";
|
|||
import { PluginTarget } from "@utils/pluginTargets";
|
||||
import { useAwaiter, useCleanupEffect, useIntersection } from "@utils/react";
|
||||
import { PluginTag, PluginTags } from "@utils/types";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { Alerts, ConfirmModal, lodash, openModal, Parser, React, SearchableSelect, Select, showToast,TextInput, Tooltip, useCallback, useMemo, useRef, useState } from "@webpack/common";
|
||||
import { Alerts, ConfirmModal, lodash, openModal, Parser, React, SearchableSelect, Select, TextInput, Toasts, Tooltip, useCallback, useMemo, useRef, useState } from "@webpack/common";
|
||||
import { JSX } from "react";
|
||||
|
||||
import Plugins, { ExcludedPlugins, PluginMeta } from "~plugins";
|
||||
|
|
@ -53,9 +52,14 @@ export const cl = classNameFactory("vc-plugins-");
|
|||
export const logger = new Logger("PluginSettings", "#a6d189");
|
||||
|
||||
function showErrorToast(message: string) {
|
||||
showToast(message, "failure", {
|
||||
position: ToastPosition.BOTTOM
|
||||
});
|
||||
Toasts.show({
|
||||
message,
|
||||
type: Toasts.Type.FAILURE,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function ReloadRequiredCard({ required, enabledPlugins, openWarningModal, resetCheckAndDo }) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import { copyWithToast } from "@utils/discord";
|
|||
import { Margins } from "@utils/margins";
|
||||
import { classes } from "@utils/misc";
|
||||
import { getStylusWebStoreUrl } from "@utils/web";
|
||||
import { React, Select, showToast, TextInput, useEffect, useMemo, useRef, useState } from "@webpack/common";
|
||||
import { React, Select, showToast, TextInput, Toasts, useEffect, useMemo, useRef, useState } from "@webpack/common";
|
||||
import { SyntheticEvent } from "react";
|
||||
|
||||
import { OnlineThemesSection } from "./OnlineThemes";
|
||||
|
|
@ -263,9 +263,9 @@ function ThemesTab() {
|
|||
setOnlineThemes(prev =>
|
||||
prev?.map(t => t.link === link ? updatedTheme : t) ?? null
|
||||
);
|
||||
showToast("Theme refreshed!", "success");
|
||||
showToast("Theme refreshed!", Toasts.Type.SUCCESS);
|
||||
} catch {
|
||||
showToast("Failed to refresh theme", "failure");
|
||||
showToast("Failed to refresh theme", Toasts.Type.FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -288,7 +288,7 @@ function ThemesTab() {
|
|||
URL.revokeObjectURL(url);
|
||||
}
|
||||
} catch {
|
||||
showToast("Failed to download theme", "failure");
|
||||
showToast("Failed to download theme", Toasts.Type.FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,7 @@ import { Span } from "@components/Span";
|
|||
import { Margins } from "@utils/margins";
|
||||
import { relaunch } from "@utils/native";
|
||||
import { changes, checkForUpdates, update, updateError } from "@utils/updater";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { ConfirmModal, openModal, React, showToast, useState } from "@webpack/common";
|
||||
import { ConfirmModal, openModal, React, Toasts, useState } from "@webpack/common";
|
||||
|
||||
import { runWithDispatch } from "./runWithDispatch";
|
||||
|
||||
|
|
@ -91,8 +90,13 @@ export function Updatable(props: CommonProps) {
|
|||
} else {
|
||||
setUpdates([]);
|
||||
|
||||
showToast("No updates found!", "message", {
|
||||
position: ToastPosition.BOTTOM
|
||||
Toasts.show({
|
||||
message: "No updates found!",
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.MESSAGE,
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
});
|
||||
}
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ type KeysOfType<Object, Type> = {
|
|||
}[keyof Object];
|
||||
|
||||
function Switches() {
|
||||
const settings = useSettings(["useQuickCss", "enableReactDevtools", "mainWindowFrameless", "frameless", "nativeTitleBar", "transparent", "winCtrlQ", "disableMinSize"]);
|
||||
const settings = useSettings(["useQuickCss", "enableReactDevtools", "mainWindowFrameless", "frameless", "winNativeTitleBar", "transparent", "winCtrlQ", "disableMinSize"]);
|
||||
|
||||
const Switches = [
|
||||
{
|
||||
|
|
@ -71,7 +71,7 @@ function Switches() {
|
|||
restartRequired: true,
|
||||
}
|
||||
: {
|
||||
key: "nativeTitleBar",
|
||||
key: "winNativeTitleBar",
|
||||
title: "Use Windows' native title bar instead of Discord's custom one",
|
||||
description: "Replace Discord's custom title bar with the standard Windows title bar. This may improve compatibility with some window management tools.",
|
||||
restartRequired: true,
|
||||
|
|
|
|||
|
|
@ -10,11 +10,9 @@ import { definePluginSettings } from "@api/Settings";
|
|||
import { EquicordDevs } from "@utils/constants";
|
||||
import { classNameFactory } from "@utils/css";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { ColorUtils, React, showToast } from "@webpack/common";
|
||||
import { ColorUtils, React, showToast, Toasts } from "@webpack/common";
|
||||
|
||||
const cl = classNameFactory("vc-better-audio-player-");
|
||||
const CORS_PROXY = "https://cors.keiran0.workers.dev?url=";
|
||||
const MAX_FILE_SIZE = 12e6;
|
||||
|
||||
interface PlayerInstance {
|
||||
mediaRef: React.RefObject<HTMLAudioElement | null>;
|
||||
|
|
@ -22,12 +20,6 @@ interface PlayerInstance {
|
|||
state: { playing: boolean; };
|
||||
}
|
||||
|
||||
interface AudioGraph {
|
||||
ctx: AudioContext;
|
||||
analyser: AnalyserNode;
|
||||
blobUrl: string;
|
||||
}
|
||||
|
||||
function validateColor(value: string, key: string, fallback: string) {
|
||||
if (/^\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}$/.test(value)) return;
|
||||
|
||||
|
|
@ -39,7 +31,7 @@ function validateColor(value: string, key: string, fallback: string) {
|
|||
}
|
||||
} catch { /* invalid hex */ }
|
||||
|
||||
showToast(`Invalid color format for ${key}, use "R, G, B" or "#RRGGBB"`, "failure");
|
||||
showToast(`Invalid color format for ${key}, use "R, G, B" or "#RRGGBB"`, Toasts.Type.FAILURE);
|
||||
settings.store[key] = fallback;
|
||||
}
|
||||
|
||||
|
|
@ -106,101 +98,62 @@ function drawSpectrograph(ctx: CanvasRenderingContext2D, w: number, h: number, f
|
|||
}
|
||||
}
|
||||
|
||||
async function fetchAudioBlob(src: string): Promise<string | null> {
|
||||
const url = new URL(src);
|
||||
url.searchParams.set("t", Date.now().toString());
|
||||
|
||||
const response = await fetch(CORS_PROXY + encodeURIComponent(url.href));
|
||||
const contentLength = response.headers.get("content-length");
|
||||
if (contentLength && Number(contentLength) > MAX_FILE_SIZE) return null;
|
||||
|
||||
const blob = await response.blob();
|
||||
return URL.createObjectURL(blob);
|
||||
}
|
||||
|
||||
async function createAudioGraph(audio: HTMLAudioElement): Promise<AudioGraph | null> {
|
||||
const blobUrl = await fetchAudioBlob(audio.currentSrc || audio.src).catch(() => null);
|
||||
if (!blobUrl) return null;
|
||||
|
||||
const wasPlaying = !audio.paused;
|
||||
const { currentTime } = audio;
|
||||
audio.src = blobUrl;
|
||||
audio.currentTime = currentTime;
|
||||
if (wasPlaying) audio.play().catch(() => { });
|
||||
|
||||
const ctx = new AudioContext();
|
||||
const analyser = ctx.createAnalyser();
|
||||
analyser.fftSize = 2048;
|
||||
ctx.createMediaElementSource(audio).connect(analyser);
|
||||
analyser.connect(ctx.destination);
|
||||
|
||||
return { ctx, analyser, blobUrl };
|
||||
}
|
||||
|
||||
function Visualizer({ mediaRef, playing }: { mediaRef: PlayerInstance["mediaRef"]; playing: boolean; }) {
|
||||
const canvasRef = React.useRef<HTMLCanvasElement>(null);
|
||||
const graphRef = React.useRef<Promise<AudioGraph | null> | null>(null);
|
||||
const graphRef = React.useRef<{ ctx: AudioContext; analyser: AnalyserNode; } | null>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
const audio = mediaRef.current;
|
||||
const canvasCtx = canvasRef.current?.getContext("2d");
|
||||
if (!playing || !audio || !canvasCtx) return;
|
||||
|
||||
graphRef.current ??= createAudioGraph(audio);
|
||||
if (!graphRef.current) {
|
||||
const ctx = new AudioContext();
|
||||
const analyser = ctx.createAnalyser();
|
||||
analyser.fftSize = 2048;
|
||||
ctx.createMediaElementSource(audio).connect(analyser);
|
||||
analyser.connect(ctx.destination);
|
||||
graphRef.current = { ctx, analyser };
|
||||
}
|
||||
|
||||
const { ctx, analyser } = graphRef.current;
|
||||
ctx.resume();
|
||||
|
||||
const dataArray = new Uint8Array(analyser.frequencyBinCount);
|
||||
const frequencyData = new Uint8Array(analyser.frequencyBinCount);
|
||||
let frame = 0;
|
||||
let stopped = false;
|
||||
let graphCtx: AudioContext | null = null;
|
||||
|
||||
graphRef.current.then(graph => {
|
||||
if (stopped || !graph) return;
|
||||
const draw = () => {
|
||||
frame = requestAnimationFrame(draw);
|
||||
|
||||
const { ctx, analyser } = graph;
|
||||
graphCtx = ctx;
|
||||
ctx.resume();
|
||||
analyser.getByteTimeDomainData(dataArray);
|
||||
analyser.getByteFrequencyData(frequencyData);
|
||||
|
||||
const dataArray = new Uint8Array(analyser.frequencyBinCount);
|
||||
const frequencyData = new Uint8Array(analyser.frequencyBinCount);
|
||||
const { canvas } = canvasCtx;
|
||||
const width = canvas.clientWidth;
|
||||
const height = canvas.clientHeight;
|
||||
const dpr = window.devicePixelRatio;
|
||||
const pixelWidth = Math.round(width * dpr);
|
||||
const pixelHeight = Math.round(height * dpr);
|
||||
if (canvas.width !== pixelWidth || canvas.height !== pixelHeight) {
|
||||
canvas.width = pixelWidth;
|
||||
canvas.height = pixelHeight;
|
||||
canvasCtx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
||||
}
|
||||
|
||||
const draw = () => {
|
||||
frame = requestAnimationFrame(draw);
|
||||
|
||||
analyser.getByteTimeDomainData(dataArray);
|
||||
analyser.getByteFrequencyData(frequencyData);
|
||||
|
||||
const { canvas } = canvasCtx;
|
||||
const width = canvas.clientWidth;
|
||||
const height = canvas.clientHeight;
|
||||
const dpr = window.devicePixelRatio;
|
||||
const pixelWidth = Math.round(width * dpr);
|
||||
const pixelHeight = Math.round(height * dpr);
|
||||
if (canvas.width !== pixelWidth || canvas.height !== pixelHeight) {
|
||||
canvas.width = pixelWidth;
|
||||
canvas.height = pixelHeight;
|
||||
canvasCtx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
||||
}
|
||||
|
||||
canvasCtx.clearRect(0, 0, width, height);
|
||||
if (settings.store.oscilloscope) drawOscilloscope(canvasCtx, width, height, dataArray, dataArray.length);
|
||||
if (settings.store.spectrograph) drawSpectrograph(canvasCtx, width, height, frequencyData, frequencyData.length);
|
||||
};
|
||||
draw();
|
||||
});
|
||||
canvasCtx.clearRect(0, 0, width, height);
|
||||
if (settings.store.oscilloscope) drawOscilloscope(canvasCtx, width, height, dataArray, dataArray.length);
|
||||
if (settings.store.spectrograph) drawSpectrograph(canvasCtx, width, height, frequencyData, frequencyData.length);
|
||||
};
|
||||
draw();
|
||||
|
||||
return () => {
|
||||
stopped = true;
|
||||
cancelAnimationFrame(frame);
|
||||
graphCtx?.suspend();
|
||||
ctx.suspend();
|
||||
};
|
||||
}, [playing]);
|
||||
|
||||
React.useEffect(() => () => {
|
||||
graphRef.current?.then(graph => {
|
||||
if (!graph) return;
|
||||
graph.ctx.close();
|
||||
URL.revokeObjectURL(graph.blobUrl);
|
||||
});
|
||||
}, []);
|
||||
React.useEffect(() => () => void graphRef.current?.ctx.close(), []);
|
||||
|
||||
return (
|
||||
<canvas
|
||||
|
|
@ -256,6 +209,10 @@ export default definePlugin({
|
|||
{
|
||||
find: "}renderPlayIcon(){",
|
||||
replacement: [
|
||||
{
|
||||
match: /"audio",\{(?=className:)/,
|
||||
replace: '$&crossOrigin:"anonymous",',
|
||||
},
|
||||
{
|
||||
match: /this\.renderAudio\(\):this\.renderVideo\(\)/,
|
||||
replace: "$&,$self.renderVisualizer(this)",
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { Logger } from "@utils/Logger";
|
|||
import { classes, pluralise } from "@utils/misc";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { chooseFile, saveFile } from "@utils/web";
|
||||
import { Alerts, Button, React, showToast, useCallback, useEffect, useRef, useState } from "@webpack/common";
|
||||
import { Alerts, Button, React, showToast, Toasts, useCallback, useEffect, useRef, useState } from "@webpack/common";
|
||||
|
||||
import { cl, croppedLabel, Shelf } from "./components/Shelf";
|
||||
import { add, clear, CropState, currentApplied, Entry, exportAll, forget, forgetCrops, getFile, getThumbs, Group, importAll, Kind, previousApplied, readIndex, recordApplied, saveCrop, toDataUrl, togglePin, touch } from "./library";
|
||||
|
|
@ -86,7 +86,7 @@ const settings = definePluginSettings({
|
|||
onConfirm: () => forgetCrops()
|
||||
.then(count => showToast(
|
||||
count ? `Forgot the framing on ${pluralise(count, "picture")}` : "Nothing was framed",
|
||||
"success"
|
||||
Toasts.Type.SUCCESS
|
||||
))
|
||||
.catch(err => logger.error("could not forget the remembered crops", err))
|
||||
})}
|
||||
|
|
@ -165,7 +165,7 @@ async function exportLibrary() {
|
|||
else saveFile(new File([data], FILENAME, { type: "application/json" }));
|
||||
} catch (err) {
|
||||
logger.error("could not export the library", err);
|
||||
showToast("Could not export your pictures", "failure");
|
||||
showToast("Could not export your pictures", Toasts.Type.FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -186,11 +186,11 @@ async function importLibrary() {
|
|||
const added = await importAll(json, settings.store.librarySize);
|
||||
showToast(
|
||||
added ? `Added ${pluralise(added, "picture")}` : "Nothing new in that file",
|
||||
"success"
|
||||
Toasts.Type.SUCCESS
|
||||
);
|
||||
} catch (err) {
|
||||
logger.error("could not import the library", err);
|
||||
showToast("Could not read that file", "failure");
|
||||
showToast("Could not read that file", Toasts.Type.FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -324,7 +324,7 @@ function PickerShelf({ kind, open, complete, maxSize }: {
|
|||
|
||||
const onPick = useCallback(async (entry: Entry) => {
|
||||
const blob = await getFile(entry.id);
|
||||
if (!blob) return showToast("That picture is missing", "failure");
|
||||
if (!blob) return showToast("That picture is missing", Toasts.Type.FAILURE);
|
||||
|
||||
const file = new File([blob], entry.name, { type: blob.type });
|
||||
await touch(entry.id);
|
||||
|
|
@ -344,7 +344,7 @@ function PickerShelf({ kind, open, complete, maxSize }: {
|
|||
}, [bump]);
|
||||
|
||||
const accept = useCallback(async (file: File) => {
|
||||
if (maxSize && file.size > maxSize) return showToast("That picture is too big for Discord", "failure");
|
||||
if (maxSize && file.size > maxSize) return showToast("That picture is too big for Discord", Toasts.Type.FAILURE);
|
||||
|
||||
try {
|
||||
const entry = await add(file, kind, "original", settings.store.librarySize);
|
||||
|
|
@ -352,7 +352,7 @@ function PickerShelf({ kind, open, complete, maxSize }: {
|
|||
await hand(entry.id, file, settings.store.rememberCrop ? entry.crop ?? null : null);
|
||||
} catch (err) {
|
||||
logger.error("could not take that picture", err);
|
||||
showToast("Could not use that picture", "failure");
|
||||
showToast("Could not use that picture", Toasts.Type.FAILURE);
|
||||
}
|
||||
}, [kind, hand, bump, maxSize]);
|
||||
|
||||
|
|
@ -432,7 +432,7 @@ function EditorShelf({ Original, ownProps }: { Original: React.ComponentType<Edi
|
|||
await show(entry.id, file, settings.store.rememberCrop ? entry.crop ?? null : null);
|
||||
} catch (err) {
|
||||
logger.error("could not take that picture", err);
|
||||
showToast("Could not use that picture", "failure");
|
||||
showToast("Could not use that picture", Toasts.Type.FAILURE);
|
||||
}
|
||||
}, [kind, show, bump, setGroup]);
|
||||
|
||||
|
|
@ -440,7 +440,7 @@ function EditorShelf({ Original, ownProps }: { Original: React.ComponentType<Edi
|
|||
|
||||
const onPick = useCallback(async (entry: Entry) => {
|
||||
const blob = await getFile(entry.id);
|
||||
if (!blob) return showToast("That picture is missing", "failure");
|
||||
if (!blob) return showToast("That picture is missing", Toasts.Type.FAILURE);
|
||||
|
||||
await touch(entry.id);
|
||||
bump();
|
||||
|
|
@ -464,7 +464,7 @@ function EditorShelf({ Original, ownProps }: { Original: React.ComponentType<Edi
|
|||
};
|
||||
const run = () => save().catch(err => {
|
||||
logger.error("could not keep the cropped copy", err);
|
||||
showToast("Could not keep the cropped copy", "failure");
|
||||
showToast("Could not keep the cropped copy", Toasts.Type.FAILURE);
|
||||
});
|
||||
|
||||
if (!settings.store.askBeforeSavingCropped) return void run();
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { Flex } from "@components/Flex";
|
|||
import { Heading } from "@components/Heading";
|
||||
import { Paragraph } from "@components/Paragraph";
|
||||
import { BasicChannelTabsProps, ChannelTabsProps, clearStaleNavigationContext, closeTab, createTab, handleChannelSwitch, isNavigationFromSource, isTabSelected, moveToTab, openedTabs, openStartupTabs, saveTabs, settings, setUpdaterFunction, useGhostTabs } from "@equicordplugins/channelTabs/util";
|
||||
import { IS_MAC } from "@utils/constants";
|
||||
import { classNameFactory } from "@utils/css";
|
||||
import { classes } from "@utils/misc";
|
||||
import { useForceUpdater } from "@utils/react";
|
||||
|
|
@ -288,6 +289,7 @@ export default function ChannelsTabsContainer(props: BasicChannelTabsProps) {
|
|||
className={classes(
|
||||
cl("container"),
|
||||
tabBarPosition === "top" && cl("container-top"),
|
||||
IS_MAC && !IS_WEB && tabBarPosition === "top" && cl("container-top-macos"),
|
||||
!animationHover && cl("no-hover-animation"),
|
||||
!animationSelection && cl("no-selection-animation"),
|
||||
!animationDragDrop && cl("no-drag-animation"),
|
||||
|
|
|
|||
|
|
@ -76,6 +76,10 @@
|
|||
z-index: 102;
|
||||
}
|
||||
|
||||
.vc-channeltabs-container-top-macos {
|
||||
padding-left: 80px;
|
||||
}
|
||||
|
||||
/* as its in the same region as notices, it needs to hide itself when a notice is shown
|
||||
there's no permanent notices, right? */
|
||||
[class*="notice"] + .vc-channeltabs-container-top {
|
||||
|
|
@ -1345,4 +1349,4 @@
|
|||
/* disable transitions when compact expand animation is disabled */
|
||||
.vc-channeltabs-no-compact-animation .vc-channeltabs-tab-number-badge {
|
||||
transition: none !important;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
import { DataStore } from "@api/index";
|
||||
import { isPluginEnabled } from "@api/PluginManager";
|
||||
import { classNameFactory } from "@utils/css";
|
||||
import { NavigationRouter, SelectedChannelStore, SelectedGuildStore, showToast, useEffect, useRef, useState } from "@webpack/common";
|
||||
import { NavigationRouter, SelectedChannelStore, SelectedGuildStore, showToast, Toasts, useEffect, useRef, useState } from "@webpack/common";
|
||||
import { JSX } from "react";
|
||||
|
||||
import { logger, settings } from "./constants";
|
||||
|
|
@ -418,7 +418,7 @@ export async function openStartupTabs(props: BasicChannelTabsProps & { userId: s
|
|||
savedTabs = persistedTabs?.[userId];
|
||||
} catch (error) {
|
||||
logger.error("Failed to load persisted tabs from DataStore", error);
|
||||
showToast("Failed to load saved tabs", "failure");
|
||||
showToast("Failed to load saved tabs", Toasts.Type.FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -430,14 +430,14 @@ export async function openStartupTabs(props: BasicChannelTabsProps & { userId: s
|
|||
|
||||
if (keepCurrentChannel) {
|
||||
hydratedUserId = undefined;
|
||||
showToast("Not restoring tabs as KeepCurrentChannel is enabled", "failure");
|
||||
showToast("Not restoring tabs as KeepCurrentChannel is enabled", Toasts.Type.FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (settings.store.onStartup) {
|
||||
case "remember": {
|
||||
if (!savedTabs?.openTabs.length) {
|
||||
showToast("Failed to restore tabs", "failure");
|
||||
showToast("Failed to restore tabs", Toasts.Type.FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -160,8 +160,8 @@ export default definePlugin({
|
|||
{
|
||||
find: 'tutorialId:"whos-online"',
|
||||
replacement: {
|
||||
match: /\((function\(\i\)\{let\{id:.*?#{intl::CHANNEL_MEMBERS_A11Y_LABEL}.*?\}\))\}\)/,
|
||||
replace: "($self.wrapRoleGroup($1}))",
|
||||
match: /\((function\(\i\)\{let\{id:.*?#{intl::CHANNEL_MEMBERS_A11Y_LABEL}.*?\}\))\}\);/,
|
||||
replace: "($self.wrapRoleGroup($1}));",
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { Flex } from "@components/Flex";
|
|||
import { Heading } from "@components/Heading";
|
||||
import { Paragraph } from "@components/Paragraph";
|
||||
import type { RenderModalProps } from "@vencord/discord-types";
|
||||
import { Checkbox, FluxDispatcher, MessageActions, Modal, openModal, PendingReplyStore, showToast, useEffect, useState } from "@webpack/common";
|
||||
import { Checkbox, FluxDispatcher, MessageActions, Modal, openModal, PendingReplyStore, showToast, Toasts, useEffect, useState } from "@webpack/common";
|
||||
|
||||
import { ApplicationField, BooleanField, DateTimeField, getDateTimeLocalValue, ParticipantField, TextField } from "./fields";
|
||||
import { abortActiveClipUploads, type ClipMetadata, getClipCreatedAt, getClipTitleFromName, getDefaultClipTitle, getDefaultFileName, getErrorMessage, getParticipantIds, getString, isValidDate, pickClipFile, uploadClipFile } from "./upload";
|
||||
|
|
@ -52,7 +52,7 @@ function UploadClipFileModal({ modalProps, channelId, clip }: { modalProps: Rend
|
|||
result = await pickClipFile(parseMetadata);
|
||||
if (!result) return;
|
||||
} catch (error) {
|
||||
showToast(getErrorMessage(error), "failure");
|
||||
showToast(getErrorMessage(error), Toasts.Type.FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { Logger } from "@utils/Logger";
|
|||
import { isObject } from "@utils/misc";
|
||||
import type { PluginNative } from "@utils/types";
|
||||
import type { User } from "@vencord/discord-types";
|
||||
import { Constants, MediaEngineStore, RestAPI, showToast, SnowflakeUtils } from "@webpack/common";
|
||||
import { Constants, MediaEngineStore, RestAPI, showToast, SnowflakeUtils, Toasts } from "@webpack/common";
|
||||
|
||||
import { convertClipToMp4 } from "./ffmpeg";
|
||||
const logger = new Logger("ClipUpload");
|
||||
|
|
@ -329,7 +329,7 @@ function shouldRetryWithFFmpeg(error: unknown) {
|
|||
|
||||
export async function uploadClipFile(file: File, options: ClipUploadOptions) {
|
||||
try {
|
||||
showToast("Checking clip file.", "message");
|
||||
showToast("Checking clip file.", Toasts.Type.MESSAGE);
|
||||
|
||||
const uploadFile = await prepareClipFile(file, options.fileName);
|
||||
|
||||
|
|
@ -338,15 +338,15 @@ export async function uploadClipFile(file: File, options: ClipUploadOptions) {
|
|||
} catch (error) {
|
||||
if (!shouldRetryWithFFmpeg(error)) throw error;
|
||||
|
||||
showToast("Converting clip file.", "message");
|
||||
showToast("Converting clip file.", Toasts.Type.MESSAGE);
|
||||
await sendClipUpload(await stampVideoFile(await convertClipToMp4(file, options.fileName), options.fileName), options);
|
||||
}
|
||||
|
||||
showToast("Clip uploaded.", "success");
|
||||
showToast("Clip uploaded.", Toasts.Type.SUCCESS);
|
||||
return true;
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
showToast(getErrorMessage(error), "failure");
|
||||
showToast(getErrorMessage(error), Toasts.Type.FAILURE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { insertTextIntoChatInputBox } from "@utils/discord";
|
||||
import { parseUrl } from "@utils/misc";
|
||||
import { showToast } from "@webpack/common";
|
||||
import { showToast, Toasts } from "@webpack/common";
|
||||
|
||||
import { registerCommands } from "../api/registry";
|
||||
import type { FormPageSpec, PageEntry, PaletteAction, PaletteCommand } from "../api/types";
|
||||
|
|
@ -109,7 +109,7 @@ function commandForm(existing: CustomCommandData | null): PageEntry {
|
|||
: [...store.get(), next]);
|
||||
registerCustomCommands();
|
||||
|
||||
showToast(existing ? "Command saved." : "Command created.", "success");
|
||||
showToast(existing ? "Command saved." : "Command created.", Toasts.Type.SUCCESS);
|
||||
ctx.pop();
|
||||
}
|
||||
};
|
||||
|
|
@ -138,7 +138,7 @@ function toCommand(data: CustomCommandData): PaletteCommand {
|
|||
run() {
|
||||
store.set(store.get().filter(entry => entry.id !== data.id));
|
||||
registerCustomCommands();
|
||||
showToast("Command deleted.", "success");
|
||||
showToast("Command deleted.", Toasts.Type.SUCCESS);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
import { getUserSettingLazy } from "@api/UserSettings";
|
||||
import type { Theme } from "@vencord/discord-types";
|
||||
import { findByCodeLazy } from "@webpack";
|
||||
import { showToast, ThemeStore, VoiceActions } from "@webpack/common";
|
||||
import { showToast, ThemeStore, Toasts, VoiceActions } from "@webpack/common";
|
||||
|
||||
import type { PaletteCommand } from "../api/types";
|
||||
import { CircleIcon, HeadphonesIcon, MicIcon, MoonIcon } from "../ui/icons";
|
||||
|
|
@ -78,7 +78,7 @@ export const discordCommands: PaletteCommand[] = [
|
|||
label: `Set ${status.label}`,
|
||||
run() {
|
||||
StatusSetting?.updateSetting(status.value);
|
||||
showToast(`Status set to ${status.label}.`, "success");
|
||||
showToast(`Status set to ${status.label}.`, Toasts.Type.SUCCESS);
|
||||
}
|
||||
}]
|
||||
}))
|
||||
|
|
@ -98,7 +98,7 @@ export const discordCommands: PaletteCommand[] = [
|
|||
const currentIdx = THEMES.findIndex(theme => theme.value === ThemeStore.theme);
|
||||
const next = THEMES[(currentIdx + 1) % THEMES.length];
|
||||
updateDiscordTheme({ theme: next.value });
|
||||
showToast(`Theme set to ${next.label}.`, "success");
|
||||
showToast(`Theme set to ${next.label}.`, Toasts.Type.SUCCESS);
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { SettingsRouter, showToast } from "@webpack/common";
|
||||
import { SettingsRouter, showToast, Toasts } from "@webpack/common";
|
||||
|
||||
export interface SettingsRoute {
|
||||
route: string;
|
||||
|
|
@ -110,7 +110,7 @@ const logger = new Logger("CommandPalette");
|
|||
export async function openSettingsPage(route: string, label?: string) {
|
||||
const candidates = resolveRouteCandidates(route);
|
||||
if (candidates.length === 0) {
|
||||
showToast("No settings page was provided.", "failure");
|
||||
showToast("No settings page was provided.", Toasts.Type.FAILURE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -124,6 +124,6 @@ export async function openSettingsPage(route: string, label?: string) {
|
|||
}
|
||||
}
|
||||
|
||||
showToast(`Unable to open ${label ?? "that settings page"}.`, "failure");
|
||||
showToast(`Unable to open ${label ?? "that settings page"}.`, Toasts.Type.FAILURE);
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { isPluginEnabled, pluginRequiresRestart, plugins, startDependenciesRecur
|
|||
import { Settings } from "@api/Settings";
|
||||
import { openPluginModal } from "@components/settings/tabs/plugins/PluginModal";
|
||||
import type { Plugin } from "@utils/types";
|
||||
import { showToast } from "@webpack/common";
|
||||
import { showToast, Toasts } from "@webpack/common";
|
||||
|
||||
import type { PaletteCommand, PaletteListItem } from "../api/types";
|
||||
import { GearIcon, PlugIcon } from "../ui/icons";
|
||||
|
|
@ -20,37 +20,37 @@ function togglePlugin(plugin: Plugin) {
|
|||
if (!wasEnabled) {
|
||||
const { restartNeeded, failures } = startDependenciesRecursive(plugin);
|
||||
if (failures.length) {
|
||||
showToast(`Failed to start dependencies: ${failures.join(", ")}`, "failure");
|
||||
showToast(`Failed to start dependencies: ${failures.join(", ")}`, Toasts.Type.FAILURE);
|
||||
return;
|
||||
}
|
||||
if (restartNeeded) {
|
||||
pluginSettings.enabled = true;
|
||||
showToast(`${plugin.name} enabled. Restart to apply.`, "message");
|
||||
showToast(`${plugin.name} enabled. Restart to apply.`, Toasts.Type.MESSAGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pluginRequiresRestart(plugin)) {
|
||||
pluginSettings.enabled = !wasEnabled;
|
||||
showToast(`${plugin.name} ${wasEnabled ? "disabled" : "enabled"}. Restart to apply.`, "message");
|
||||
showToast(`${plugin.name} ${wasEnabled ? "disabled" : "enabled"}. Restart to apply.`, Toasts.Type.MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wasEnabled && !plugin.started) {
|
||||
pluginSettings.enabled = false;
|
||||
showToast(`${plugin.name} disabled.`, "success");
|
||||
showToast(`${plugin.name} disabled.`, Toasts.Type.SUCCESS);
|
||||
return;
|
||||
}
|
||||
|
||||
const result = wasEnabled ? stopPlugin(plugin) : startPlugin(plugin);
|
||||
if (!result) {
|
||||
pluginSettings.enabled = false;
|
||||
showToast(`Error while ${wasEnabled ? "stopping" : "starting"} ${plugin.name}.`, "failure");
|
||||
showToast(`Error while ${wasEnabled ? "stopping" : "starting"} ${plugin.name}.`, Toasts.Type.FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
pluginSettings.enabled = !wasEnabled;
|
||||
showToast(`${plugin.name} ${wasEnabled ? "disabled" : "enabled"}.`, "success");
|
||||
showToast(`${plugin.name} ${wasEnabled ? "disabled" : "enabled"}.`, Toasts.Type.SUCCESS);
|
||||
}
|
||||
|
||||
function pluginItems(): PaletteListItem[] {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
import { openPrivateChannel, sendMessage } from "@utils/discord";
|
||||
import { sleep } from "@utils/misc";
|
||||
import { CloudUploadPlatform } from "@vencord/discord-types/enums";
|
||||
import { ChannelStore, CloudUploader, IconUtils, RelationshipStore, showToast, UserStore } from "@webpack/common";
|
||||
import { ChannelStore, CloudUploader, IconUtils, RelationshipStore, showToast, Toasts, UserStore } from "@webpack/common";
|
||||
|
||||
import type { FormFieldOption, FormSubmitExtras, PaletteCommand } from "../api/types";
|
||||
import { fuzzyScore } from "../search/ranker";
|
||||
|
|
@ -82,7 +82,7 @@ export const sendDmCommand: PaletteCommand = {
|
|||
});
|
||||
|
||||
const user = UserStore.getUser(values.recipient);
|
||||
showToast(`Message sent to ${user.globalName || user.username}.`, "success");
|
||||
showToast(`Message sent to ${user.globalName || user.username}.`, Toasts.Type.SUCCESS);
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { EquicordDevs } from "@utils/constants";
|
|||
import { Logger } from "@utils/Logger";
|
||||
import definePlugin from "@utils/types";
|
||||
import { User } from "@vencord/discord-types";
|
||||
import { Menu, SelectedGuildStore, showToast,UserProfileStore } from "@webpack/common";
|
||||
import { Menu, SelectedGuildStore, Toasts, UserProfileStore } from "@webpack/common";
|
||||
|
||||
const logger = new Logger("CopyProfileColors");
|
||||
|
||||
|
|
@ -38,7 +38,11 @@ function copyProfileColors(userId: string, guildId?: string) {
|
|||
const colors = getProfileColors(userId, guildId);
|
||||
|
||||
if (!colors) {
|
||||
showToast("No profile colors found!", "failure");
|
||||
Toasts.show({
|
||||
type: Toasts.Type.FAILURE,
|
||||
message: "No profile colors found!",
|
||||
id: Toasts.genId()
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -49,10 +53,18 @@ function copyProfileColors(userId: string, guildId?: string) {
|
|||
|
||||
try {
|
||||
copyToClipboard(formattedColors);
|
||||
showToast("Profile colors copied to clipboard!", "success");
|
||||
Toasts.show({
|
||||
type: Toasts.Type.SUCCESS,
|
||||
message: "Profile colors copied to clipboard!",
|
||||
id: Toasts.genId()
|
||||
});
|
||||
} catch (e) {
|
||||
logger.error("Failed to copy to clipboard:", e);
|
||||
showToast("Error copying profile colors!", "failure");
|
||||
Toasts.show({
|
||||
type: Toasts.Type.FAILURE,
|
||||
message: "Error copying profile colors!",
|
||||
id: Toasts.genId()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,8 @@ import { copyToClipboard } from "@utils/clipboard";
|
|||
import { Devs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
import { User } from "@vencord/discord-types";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { findByCodeLazy } from "@webpack";
|
||||
import { showToast } from "@webpack/common";
|
||||
import { Toasts } from "@webpack/common";
|
||||
|
||||
interface MakeContextMenuProps {
|
||||
user: User,
|
||||
|
|
@ -45,14 +44,24 @@ export default definePlugin({
|
|||
throw new Error("button_urls does not contain index");
|
||||
}
|
||||
copyToClipboard(button_urls[index]);
|
||||
showToast("Copied URL", "success", {
|
||||
position: ToastPosition.TOP
|
||||
});
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
message: "Copied URL",
|
||||
type: Toasts.Type.SUCCESS,
|
||||
options: {
|
||||
position: Toasts.Position.TOP
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
showToast("Error copying URL, check console for more info", "failure", {
|
||||
position: ToastPosition.TOP
|
||||
});
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
message: "Error copying URL, check console for more info",
|
||||
type: Toasts.Type.FAILURE,
|
||||
options: {
|
||||
position: Toasts.Position.TOP
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { Logger } from "@utils/Logger";
|
|||
import { pluralize } from "@utils/misc";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { Message, MessageAttachment } from "@vencord/discord-types";
|
||||
import { ChannelStore, showToast } from "@webpack/common";
|
||||
import { ChannelStore, showToast, Toasts } from "@webpack/common";
|
||||
|
||||
const logger = new Logger("DownloadAllAttachments");
|
||||
|
||||
|
|
@ -71,9 +71,9 @@ async function downloadAll(attachments: MessageAttachment[]) {
|
|||
const succeeded = attachments.length - failed;
|
||||
|
||||
if (failed === 0)
|
||||
showToast(`Downloaded ${pluralize(succeeded, "attachment")}.`, "success");
|
||||
showToast(`Downloaded ${pluralize(succeeded, "attachment")}.`, Toasts.Type.SUCCESS);
|
||||
else
|
||||
showToast(`Downloaded ${succeeded} of ${attachments.length} attachments. ${failed} failed.`, "failure");
|
||||
showToast(`Downloaded ${succeeded} of ${attachments.length} attachments. ${failed} failed.`, Toasts.Type.FAILURE);
|
||||
}
|
||||
|
||||
export default definePlugin({
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { Logger } from "@utils/Logger";
|
|||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import type { Channel } from "@vencord/discord-types";
|
||||
import { ChannelType } from "@vencord/discord-types/enums";
|
||||
import { ChannelStore, GuildStore, IconUtils, RelationshipStore, SelectedChannelStore, showToast, UserStore } from "@webpack/common";
|
||||
import { ChannelStore, GuildStore, IconUtils, RelationshipStore, SelectedChannelStore, showToast, Toasts, UserStore } from "@webpack/common";
|
||||
|
||||
import { beginDrag as beginSessionDrag, clearDragState, getLastDropAt, hasActiveDrag, isGuildDragActive, isInputDragSource, isUserDragActive, markDrop, markInputDragSource, scheduleGuildCleanup, shouldIgnoreDrop, startDragWatchdog, stopDragState, touchDrag } from "./dragState";
|
||||
import { type GhostState, hideGhost as hideDragGhost, isGhostVisible, mountGhost as mountDragGhost, scheduleGhostPosition as scheduleDragGhostPosition, showGhost as showDragGhost, unmountGhost as unmountDragGhost } from "./ghost";
|
||||
|
|
@ -293,7 +293,7 @@ export default definePlugin({
|
|||
} catch (error) {
|
||||
clearDragState();
|
||||
logger.error("Failed handling drop", error);
|
||||
showToast("Dragify failed to handle drop.", "failure");
|
||||
showToast("Dragify failed to handle drop.", Toasts.Type.FAILURE);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
import { Logger } from "@utils/Logger";
|
||||
import type { Channel } from "@vencord/discord-types";
|
||||
import { ChannelType } from "@vencord/discord-types/enums";
|
||||
import { ChannelStore, GuildChannelStore, GuildStore, PermissionsBits, PermissionStore, RestAPI, showToast } from "@webpack/common";
|
||||
import { ChannelStore, GuildChannelStore, GuildStore, PermissionsBits, PermissionStore, RestAPI, showToast, Toasts } from "@webpack/common";
|
||||
|
||||
const logger = new Logger("Dragify");
|
||||
|
||||
|
|
@ -135,7 +135,7 @@ function getInviteUrl(code: string) {
|
|||
export async function createInvite(guildId: string, currentChannel: Channel, settings: InviteSettings): Promise<string | null> {
|
||||
const inviteChannel = resolveInviteChannel(guildId, currentChannel);
|
||||
if (!inviteChannel) {
|
||||
showToast("No channel available for invites.", "failure");
|
||||
showToast("No channel available for invites.", Toasts.Type.FAILURE);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ export async function createInvite(guildId: string, currentChannel: Channel, set
|
|||
reused.reason === "missing"
|
||||
? "No reusable invite available."
|
||||
: "Unable to reuse invite.",
|
||||
"failure",
|
||||
Toasts.Type.FAILURE,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
|
@ -174,11 +174,11 @@ export async function createInvite(guildId: string, currentChannel: Channel, set
|
|||
maxUses: maxUses === 0 ? null : maxUses,
|
||||
uses: 0,
|
||||
});
|
||||
showToast("Invite created.", "success");
|
||||
showToast("Invite created.", Toasts.Type.SUCCESS);
|
||||
return getInviteUrl(code);
|
||||
} catch (error) {
|
||||
logger.error("Failed to create invite", error);
|
||||
showToast("Unable to create invite.", "failure");
|
||||
showToast("Unable to create invite.", Toasts.Type.FAILURE);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ export default definePlugin({
|
|||
match: /case \i\.\i\.WINDOWS:/,
|
||||
replace: 'case "WEB":'
|
||||
},
|
||||
predicate: () => Settings.nativeTitleBar,
|
||||
predicate: () => Settings.winNativeTitleBar,
|
||||
},
|
||||
{
|
||||
find: '"refresh-title-bar-small"',
|
||||
|
|
@ -328,7 +328,7 @@ export default definePlugin({
|
|||
replace: "true"
|
||||
}
|
||||
],
|
||||
predicate: () => Settings.nativeTitleBar,
|
||||
predicate: () => Settings.winNativeTitleBar,
|
||||
},
|
||||
{
|
||||
find: "DirectMessage: getSpringConfigs()",
|
||||
|
|
@ -350,7 +350,7 @@ export default definePlugin({
|
|||
replace: "$&&&!$self.isChannelMuted($1?.guildId,$1?.channelId)"
|
||||
},
|
||||
{
|
||||
match: /\.getEmbeddedActivitiesForGuild\((\i)\)(?=.{0,100}\.flatMap\(\i=>)/,
|
||||
match: /\.getEmbeddedActivitiesForGuild\((\i)\)(?=.flatMap\(\i=>)/,
|
||||
replace: "$&.filter(e=>!$self.isChannelMuted($1?.guildId,e?.channelId))"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import ErrorBoundary from "@components/ErrorBoundary";
|
|||
import { Logger } from "@utils/Logger";
|
||||
import { isEquicordGuild, isEquicordSupport } from "@utils/misc";
|
||||
import { Message } from "@vencord/discord-types";
|
||||
import { Button, showToast } from "@webpack/common";
|
||||
import { Button, showToast, Toasts } from "@webpack/common";
|
||||
import { JSX } from "react";
|
||||
|
||||
import { toggleEnabled } from "./utils";
|
||||
|
|
@ -50,10 +50,10 @@ export const PluginButtons = ErrorBoundary.wrap(function PluginCards({ message }
|
|||
onClick={async () => {
|
||||
try {
|
||||
const success = await toggleEnabled(matchedPlugin);
|
||||
if (success) showToast(`${label}`, "success");
|
||||
if (success) showToast(`${label}`, Toasts.Type.SUCCESS);
|
||||
} catch (e) {
|
||||
new Logger("EquicordHelper").error("Error while toggling:", e);
|
||||
showToast(`Failed to ${label.toLowerCase()}`, "failure");
|
||||
showToast(`Failed to ${label.toLowerCase()}`, Toasts.Type.FAILURE);
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -7,13 +7,17 @@
|
|||
import { showNotice } from "@api/Notices";
|
||||
import { plugins, startDependenciesRecursive, startPlugin, stopPlugin } from "@api/PluginManager";
|
||||
import { Settings } from "@api/Settings";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { Alerts, showToast } from "@webpack/common";
|
||||
import { Alerts, Toasts } from "@webpack/common";
|
||||
|
||||
function showErrorToast(message: string) {
|
||||
showToast(message, "failure", {
|
||||
position: ToastPosition.BOTTOM
|
||||
});
|
||||
Toasts.show({
|
||||
message,
|
||||
type: Toasts.Type.FAILURE,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function restartPrompt(): Promise<boolean> {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { Devs } from "@utils/constants";
|
|||
import { classNameFactory } from "@utils/css";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { findComponentByCodeLazy } from "@webpack";
|
||||
import { Constants, GuildStore, IconUtils, MediaEngineStore, Menu, RestAPI, SearchableSelect, SelectedChannelStore, showToast,TextInput } from "@webpack/common";
|
||||
import { Constants, GuildStore, IconUtils, MediaEngineStore, Menu, RestAPI, SearchableSelect, SelectedChannelStore, TextInput, Toasts } from "@webpack/common";
|
||||
|
||||
const cl = classNameFactory("vc-exitsounds-");
|
||||
|
||||
|
|
@ -134,7 +134,11 @@ export default definePlugin({
|
|||
}
|
||||
});
|
||||
} catch {
|
||||
showToast("Oops! Something went wrong.", "failure");
|
||||
Toasts.show({
|
||||
message: "Oops! Something went wrong.",
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.FAILURE
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,8 +15,7 @@ import { showItemInFolder } from "@utils/native";
|
|||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { saveFile } from "@utils/web";
|
||||
import { Message } from "@vencord/discord-types";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { Menu, showToast } from "@webpack/common";
|
||||
import { Menu, Toasts } from "@webpack/common";
|
||||
|
||||
import { ContactsList } from "./types";
|
||||
|
||||
|
|
@ -176,18 +175,28 @@ export default definePlugin({
|
|||
copyContactToClipboard() {
|
||||
if (this.contactList) {
|
||||
copyToClipboard(JSON.stringify(this.contactList));
|
||||
showToast("Contacts copied to clipboard successfully.", "success", {
|
||||
Toasts.show({
|
||||
message: "Contacts copied to clipboard successfully.",
|
||||
type: Toasts.Type.SUCCESS,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
duration: 3000,
|
||||
position: ToastPosition.BOTTOM
|
||||
});
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
// reason why you need to click the all tab is because the data is extracted during
|
||||
// the request itself when you fetch all your friends. this is done to avoid sending a
|
||||
// manual request to discord, which may raise suspicion and might even get you terminated.
|
||||
showToast("Contact list is undefined. Click on the \"All\" tab before exporting.", "failure", {
|
||||
Toasts.show({
|
||||
message: "Contact list is undefined. Click on the \"All\" tab before exporting.",
|
||||
type: Toasts.Type.FAILURE,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
duration: 3000,
|
||||
position: ToastPosition.BOTTOM
|
||||
});
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { useForceUpdater } from "@utils/react";
|
|||
import { PluginNative } from "@utils/types";
|
||||
import { Channel, MessageAttachment } from "@vencord/discord-types";
|
||||
import { findByCodeLazy, findByPropsLazy } from "@webpack";
|
||||
import { Constants, createRoot, DraftType, FluxDispatcher, Humanize, MessageActions, PendingReplyStore, PermissionStore, ReactDOM, RestAPI, showToast,UploadAttachmentStore, UploadHandler, UploadManager, useCallback, useEffect, useRef, UserSettingsActionCreators, UserSettingsProtoStore, useStateFromStores } from "@webpack/common";
|
||||
import { Constants, createRoot, DraftType, FluxDispatcher, Humanize, MessageActions, PendingReplyStore, PermissionStore, ReactDOM, RestAPI, Toasts, UploadAttachmentStore, UploadHandler, UploadManager, useCallback, useEffect, useRef, UserSettingsActionCreators, UserSettingsProtoStore, useStateFromStores } from "@webpack/common";
|
||||
import { deflateSync, inflateSync } from "fflate";
|
||||
import { Key, ReactNode } from "react";
|
||||
import { JsonValue } from "type-fest";
|
||||
|
|
@ -189,13 +189,13 @@ async function fetchAttachment(attachment: MessageAttachment): Promise<File> {
|
|||
export async function sendAttachment(attachment: MessageAttachment, channel: Channel) {
|
||||
const { filename, title, description } = attachment;
|
||||
const file = await fetchAttachment(attachment).catch(() =>
|
||||
showToast(`Couldn't fetch ${filename}`, "failure")
|
||||
Toasts.show({ message: `Couldn't fetch ${filename}`, id: Toasts.genId(), type: Toasts.Type.FAILURE })
|
||||
);
|
||||
if (!file) return;
|
||||
|
||||
// Using promptToUpload instead of addFiles directly since it has file size checks with error popups
|
||||
await UploadHandler.promptToUpload([file], channel, DraftType.ChannelMessage).catch(() =>
|
||||
showToast(`Couldn't upload ${filename}`, "failure")
|
||||
Toasts.show({ message: `Couldn't upload ${filename}`, id: Toasts.genId(), type: Toasts.Type.FAILURE })
|
||||
);
|
||||
|
||||
const uploads = [...UploadAttachmentStore.getUploads(channel.id, DraftType.ChannelMessage)];
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { classNameFactory } from "@utils/css";
|
|||
import definePlugin from "@utils/types";
|
||||
import { CloudUpload } from "@vencord/discord-types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { DraftType, FluxDispatcher, Menu, PermissionsBits, PermissionStore, React, showToast, UploadAttachmentStore, useEffect, UserStore, useState } from "@webpack/common";
|
||||
import { DraftType, FluxDispatcher, Menu, PermissionsBits, PermissionStore, React, showToast, Toasts, UploadAttachmentStore, useEffect, UserStore, useState } from "@webpack/common";
|
||||
|
||||
import { settings } from "./settings";
|
||||
import { serviceLabels, ServiceType } from "./types";
|
||||
|
|
@ -233,12 +233,12 @@ async function handleUploadFileFromDraft(upload: CloudUpload) {
|
|||
if (!file) return;
|
||||
|
||||
if (!isFileTypeAllowed(file)) {
|
||||
showToast("File type not allowed by current filter", "failure");
|
||||
showToast("File type not allowed by current filter", Toasts.Type.FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isConfigured()) {
|
||||
showToast("Please configure FileUpload settings first", "failure");
|
||||
showToast("Please configure FileUpload settings first", Toasts.Type.FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { Switch } from "@components/Switch";
|
|||
import { classNameFactory } from "@utils/css";
|
||||
import { useForceUpdater } from "@utils/react";
|
||||
import { OptionType } from "@utils/types";
|
||||
import { React, Select, showToast, TextArea, TextInput } from "@webpack/common";
|
||||
import { React, Select, showToast, TextArea, TextInput, Toasts } from "@webpack/common";
|
||||
|
||||
import { CORS_PROXY } from "./constants";
|
||||
import { fallbackServiceOrder, serviceLabels, ServiceType } from "./types";
|
||||
|
|
@ -520,10 +520,10 @@ export function SettingsComponent() {
|
|||
const validateShareXConfig = () => {
|
||||
try {
|
||||
parseShareXConfig(settings.store.sharexConfig || "");
|
||||
showToast("ShareX config is valid", "success");
|
||||
showToast("ShareX config is valid", Toasts.Type.SUCCESS);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : "Invalid ShareX config";
|
||||
showToast(message, "failure");
|
||||
showToast(message, Toasts.Type.FAILURE);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -542,10 +542,10 @@ export function SettingsComponent() {
|
|||
const parsed = parseShareXConfig(content);
|
||||
settings.store.sharexConfig = JSON.stringify(parsed, null, 2);
|
||||
update();
|
||||
showToast("Imported ShareX config", "success");
|
||||
showToast("Imported ShareX config", Toasts.Type.SUCCESS);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : "Failed to import ShareX config";
|
||||
showToast(message, "failure");
|
||||
showToast(message, Toasts.Type.FAILURE);
|
||||
}
|
||||
};
|
||||
reader.readAsText(file);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { insertTextIntoChatInputBox } from "@utils/discord";
|
|||
import { Logger } from "@utils/Logger";
|
||||
import { PluginNative } from "@utils/types";
|
||||
import { chooseFile } from "@utils/web";
|
||||
import { showToast } from "@webpack/common";
|
||||
import { showToast, Toasts } from "@webpack/common";
|
||||
|
||||
import { convertApngToGif } from "./apngToGif";
|
||||
import { getExtensionFromBytes, getExtensionFromMime, getMimeFromExtension, getUrlExtension } from "./getMediaUrl";
|
||||
|
|
@ -1304,19 +1304,19 @@ function getFilenameExtension(filename: string): string | undefined {
|
|||
async function notifyUploadSuccess(finalUrl: string, forceSend?: boolean): Promise<void> {
|
||||
if (settings.store.autoCopy) {
|
||||
if (!finalUrl || !finalUrl.trim()) {
|
||||
showToast("Upload successful, but no URL was available to copy", "message");
|
||||
showToast("Upload successful, but no URL was available to copy", Toasts.Type.MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await copyToClipboard(finalUrl);
|
||||
showToast("Upload successful, URL copied to clipboard", "success");
|
||||
showToast("Upload successful, URL copied to clipboard", Toasts.Type.SUCCESS);
|
||||
} catch (error) {
|
||||
logger.warn("Upload succeeded but clipboard copy failed", error);
|
||||
showToast("Upload successful, but failed to copy URL", "message");
|
||||
showToast("Upload successful, but failed to copy URL", Toasts.Type.MESSAGE);
|
||||
}
|
||||
} else {
|
||||
showToast("Upload successful", "success");
|
||||
showToast("Upload successful", Toasts.Type.SUCCESS);
|
||||
}
|
||||
|
||||
const autoSend = forceSend || Boolean((settings.store as { autoSend?: boolean; }).autoSend);
|
||||
|
|
@ -1366,7 +1366,7 @@ async function uploadWithFallbacks(fileBlob: Blob, filename: string, primary: Se
|
|||
try {
|
||||
const uploadedUrl = await uploadToService(service, fileBlob, filename);
|
||||
if (attempted.length) {
|
||||
showToast(`Upload succeeded with ${serviceLabels[service]} after fallback`, "success");
|
||||
showToast(`Upload succeeded with ${serviceLabels[service]} after fallback`, Toasts.Type.SUCCESS);
|
||||
}
|
||||
|
||||
setUploadState({
|
||||
|
|
@ -1433,7 +1433,7 @@ async function normalizeUploadBlob(blob: Blob, sourceUrl?: string): Promise<{ bl
|
|||
blob = gifBlob;
|
||||
ext = "gif";
|
||||
} else {
|
||||
showToast("APNG to GIF conversion failed, uploading as APNG", "failure");
|
||||
showToast("APNG to GIF conversion failed, uploading as APNG", Toasts.Type.FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1463,12 +1463,12 @@ async function uploadPreparedBlob(blob: Blob, sourceUrl?: string, forceSend?: bo
|
|||
|
||||
export async function uploadFile(url: string): Promise<void> {
|
||||
if (isUploading) {
|
||||
showToast("Upload already in progress", "message");
|
||||
showToast("Upload already in progress", Toasts.Type.MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isConfigured()) {
|
||||
showToast("Please configure FileUpload settings first", "failure");
|
||||
showToast("Please configure FileUpload settings first", Toasts.Type.FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1527,10 +1527,10 @@ export async function uploadFile(url: string): Promise<void> {
|
|||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : "Unknown error";
|
||||
if (isUploadCancelledError(error)) {
|
||||
showToast("Upload cancelled", "message");
|
||||
showToast("Upload cancelled", Toasts.Type.MESSAGE);
|
||||
setUploadState({ phase: "cancelled", status: "Upload cancelled.", canCancel: false, percent: 0 });
|
||||
} else {
|
||||
showToast(`Upload failed: ${message}`, "failure");
|
||||
showToast(`Upload failed: ${message}`, Toasts.Type.FAILURE);
|
||||
logger.error("Upload error", error);
|
||||
setUploadState({ phase: "failed", status: `Upload failed: ${message}`, canCancel: false, percent: 0 });
|
||||
}
|
||||
|
|
@ -1547,7 +1547,7 @@ export async function uploadPickedFile(): Promise<void> {
|
|||
if (!file) return;
|
||||
|
||||
if (!isFileTypeAllowed(file)) {
|
||||
showToast("File type not allowed by current filter", "failure");
|
||||
showToast("File type not allowed by current filter", Toasts.Type.FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1556,12 +1556,12 @@ export async function uploadPickedFile(): Promise<void> {
|
|||
|
||||
export async function uploadProvidedFiles(files: readonly File[], forceSend?: boolean): Promise<void> {
|
||||
if (isUploading) {
|
||||
showToast("Upload already in progress", "message");
|
||||
showToast("Upload already in progress", Toasts.Type.MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isConfigured()) {
|
||||
showToast("Please configure FileUpload settings first", "failure");
|
||||
showToast("Please configure FileUpload settings first", Toasts.Type.FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1596,10 +1596,10 @@ export async function uploadProvidedFiles(files: readonly File[], forceSend?: bo
|
|||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : "Unknown error";
|
||||
if (isUploadCancelledError(error)) {
|
||||
showToast("Upload cancelled", "message");
|
||||
showToast("Upload cancelled", Toasts.Type.MESSAGE);
|
||||
setUploadState({ phase: "cancelled", status: "Upload cancelled.", canCancel: false, percent: 0 });
|
||||
} else {
|
||||
showToast(`Upload failed: ${message}`, "failure");
|
||||
showToast(`Upload failed: ${message}`, Toasts.Type.FAILURE);
|
||||
logger.error("Manual upload error", error);
|
||||
setUploadState({ phase: "failed", status: `Upload failed: ${message}`, canCancel: false, percent: 0 });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import { Devs } from "@utils/constants";
|
|||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { Message } from "@vencord/discord-types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { ChannelStore, createRoot, MessageStore, showToast } from "@webpack/common";
|
||||
import { ChannelStore, createRoot, MessageStore, Toasts } from "@webpack/common";
|
||||
import { Root } from "react-dom/client";
|
||||
|
||||
import ReplyNavigator from "./ReplyNavigator";
|
||||
|
|
@ -115,10 +115,18 @@ export default definePlugin({
|
|||
jumpType: "INSTANT"
|
||||
});
|
||||
if (replies.length > 1) {
|
||||
showToast("Use the bottom panel to navigate between replies.", "message");
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
message: "Use the bottom panel to navigate between replies.",
|
||||
type: Toasts.Type.MESSAGE
|
||||
});
|
||||
const container = document.querySelector("[class*=channelBottomBarArea_]");
|
||||
if (!container) {
|
||||
showToast("Couldn't find the container element.", "failure");
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
message: "Couldn't find the container element.",
|
||||
type: Toasts.Type.FAILURE
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +139,11 @@ export default definePlugin({
|
|||
root!.render(<ReplyNavigator replies={replies} />);
|
||||
}
|
||||
} else {
|
||||
showToast("Couldn't find a reply.", "failure");
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
message: "Couldn't find a reply.",
|
||||
type: Toasts.Type.FAILURE
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||
import { FolderIcon, InfoIcon, LinkIcon, PencilIcon, PlusIcon, RemixIcon, TrashIcon } from "@components/Icons";
|
||||
import { copyToClipboard } from "@utils/clipboard";
|
||||
import { Alerts, Button, FluxDispatcher, Menu, showToast } from "@webpack/common";
|
||||
import { Alerts, Button, FluxDispatcher, Menu, showToast, Toasts } from "@webpack/common";
|
||||
|
||||
import { settings } from "../settings";
|
||||
import { Gif } from "../types";
|
||||
|
|
@ -71,7 +71,7 @@ export const addCollectionContextMenuPatch: NavContextMenuPatchCallback = (child
|
|||
leadingAccessory={{ type: "icon", icon: LinkIcon }}
|
||||
action={() => {
|
||||
copyToClipboard(gif.url);
|
||||
showToast("Image link copied to clipboard", "success");
|
||||
showToast("Image link copied to clipboard", Toasts.Type.SUCCESS);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
|
@ -131,7 +131,7 @@ export function RemoveItemContextMenuItems({ type, nameOrId }: { type: "collecti
|
|||
const gif = getGifById(nameOrId);
|
||||
if (!gif) return;
|
||||
copyToClipboard(gif.url);
|
||||
showToast("URL copied to clipboard", "success");
|
||||
showToast("URL copied to clipboard", Toasts.Type.SUCCESS);
|
||||
}}
|
||||
/>
|
||||
<Menu.MenuItem
|
||||
|
|
@ -198,7 +198,7 @@ export function GifPickerContextMenu({ gif }: { gif: Gif; }) {
|
|||
leadingAccessory={{ type: "icon", icon: LinkIcon }}
|
||||
action={() => {
|
||||
copyToClipboard(gif.url);
|
||||
showToast("Image link copied to clipboard", "success");
|
||||
showToast("Image link copied to clipboard", Toasts.Type.SUCCESS);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
|
@ -220,7 +220,7 @@ export function getGifPickerContextMenuItems(src: string, url: string, height: n
|
|||
leadingAccessory={{ type: "icon", icon: LinkIcon }}
|
||||
action={() => {
|
||||
copyToClipboard(url);
|
||||
showToast("Image link copied to clipboard", "success");
|
||||
showToast("Image link copied to clipboard", Toasts.Type.SUCCESS);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@
|
|||
*/
|
||||
|
||||
import { DataStore } from "@api/index";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { showToast } from "@webpack/common";
|
||||
import { Toasts } from "@webpack/common";
|
||||
|
||||
import { settings } from "../settings";
|
||||
import { Collection, Gif } from "../types";
|
||||
|
|
@ -33,7 +32,7 @@ export async function createCollection(name: string, gifs: Gif[]): Promise<void>
|
|||
const fullName = `${settings.store.collectionPrefix}${name}`;
|
||||
|
||||
if (collections.some(c => c.name === fullName)) {
|
||||
showToast("That collection already exists", "failure", { duration: 3000, position: ToastPosition.BOTTOM });
|
||||
Toasts.show({ message: "That collection already exists", type: Toasts.Type.FAILURE, id: Toasts.genId(), options: { duration: 3000, position: Toasts.Position.BOTTOM } });
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +56,7 @@ export async function addToCollection(name: string, gif: Gif): Promise<void> {
|
|||
if (!collection) return void logger.warn("Collection not found");
|
||||
|
||||
if (settings.store.preventDuplicates && collection.gifs.some(g => g.url === gif.url)) {
|
||||
showToast("This GIF is already in the collection", "failure", { duration: 3000, position: ToastPosition.BOTTOM });
|
||||
Toasts.show({ message: "This GIF is already in the collection", type: Toasts.Type.FAILURE, id: Toasts.genId(), options: { duration: 3000, position: Toasts.Position.BOTTOM } });
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { DataStore } from "@api/index";
|
||||
import { chooseFile, saveFile } from "@utils/web";
|
||||
import { showToast } from "@webpack/common";
|
||||
import { Toasts } from "@webpack/common";
|
||||
|
||||
import { DATA_COLLECTION_NAME, getCollections, refreshCacheCollection } from "./collectionManager";
|
||||
import { logger } from "./misc";
|
||||
|
|
@ -70,6 +70,14 @@ export async function uploadGifCollections(showToast = true): Promise<void> {
|
|||
}
|
||||
}
|
||||
|
||||
const toastSuccess = () => showToast("Collections imported successfully.", "success");
|
||||
const toastSuccess = () => Toasts.show({
|
||||
type: Toasts.Type.SUCCESS,
|
||||
message: "Collections imported successfully.",
|
||||
id: Toasts.genId(),
|
||||
});
|
||||
|
||||
const toastFailure = (err: unknown) => showToast(`Failed to import collections: ${String(err)}`, "failure");
|
||||
const toastFailure = (err: unknown) => Toasts.show({
|
||||
type: Toasts.Type.FAILURE,
|
||||
message: `Failed to import collections: ${String(err)}`,
|
||||
id: Toasts.genId(),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { BadgeContextMenu } from "@plugins/_api/badges";
|
|||
import { Devs, EquicordDevs } from "@utils/constants";
|
||||
import { openInviteModal } from "@utils/discord";
|
||||
import definePlugin from "@utils/types";
|
||||
import { ContextMenuApi, React, showToast } from "@webpack/common";
|
||||
import { ContextMenuApi, React, Toasts } from "@webpack/common";
|
||||
|
||||
import { settings } from "./settings";
|
||||
import { cl, GlobalBadges, INVITE_LINK, loadBadges } from "./utils";
|
||||
|
|
@ -47,7 +47,11 @@ export default definePlugin({
|
|||
toolboxActions: {
|
||||
async "Refetch Global Badges"() {
|
||||
await loadBadges();
|
||||
showToast("Successfully refetched global badges!", "success");
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
message: "Successfully refetched global badges!",
|
||||
type: Toasts.Type.SUCCESS
|
||||
});
|
||||
}
|
||||
},
|
||||
get GlobalBadges() {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { Devs, EquicordDevs } from "@utils/constants";
|
|||
import definePlugin from "@utils/types";
|
||||
import { VoiceState } from "@vencord/discord-types";
|
||||
import { findByCodeLazy } from "@webpack";
|
||||
import { ApplicationStreamingSettingsStore, ChannelStore, MediaEngineStore, PermissionsBits, PermissionStore, SelectedChannelStore, showToast, UserStore, VoiceActions, WindowStore } from "@webpack/common";
|
||||
import { ApplicationStreamingSettingsStore, ChannelStore, MediaEngineStore, PermissionsBits, PermissionStore, SelectedChannelStore, showToast, Toasts, UserStore, VoiceActions, WindowStore } from "@webpack/common";
|
||||
|
||||
import { getCurrentMedia, settings } from "./utils";
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ export default definePlugin({
|
|||
toolboxActions: {
|
||||
"Instant Screenshare"() {
|
||||
settings.store.toolboxManagement = !settings.store.toolboxManagement;
|
||||
showToast(`Instant Screenshare ${settings.store.toolboxManagement ? "Enabled" : "Disabled"}`, "success");
|
||||
showToast(`Instant Screenshare ${settings.store.toolboxManagement ? "Enabled" : "Disabled"}`, Toasts.Type.SUCCESS);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { NavContextMenuPatchCallback } from "@api/ContextMenu";
|
|||
import { Devs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
import { Channel, Message, User } from "@vencord/discord-types";
|
||||
import { ChannelStore, Constants, Menu, NavigationRouter, RestAPI, SelectedChannelStore, SelectedGuildStore, showToast } from "@webpack/common";
|
||||
import { ChannelStore, Constants, Menu, NavigationRouter, RestAPI, SelectedChannelStore, SelectedGuildStore, Toasts } from "@webpack/common";
|
||||
|
||||
function jumpToFirstMessage(channelId: string, guildId?: string | null) {
|
||||
NavigationRouter.transitionTo(`/channels/${guildId ?? "@me"}/${channelId}/0`);
|
||||
|
|
@ -38,13 +38,21 @@ async function jumpToUserMessage(channelId: string, guildId: string, userId: str
|
|||
|
||||
const messageId = res.body?.messages?.[0]?.[0]?.id;
|
||||
if (!messageId) {
|
||||
showToast("No messages found from this user in this channel.", "failure");
|
||||
Toasts.show({
|
||||
type: Toasts.Type.FAILURE,
|
||||
message: "No messages found from this user in this channel.",
|
||||
id: Toasts.genId()
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
NavigationRouter.transitionTo(`/channels/${guildId}/${channelId}/${messageId}`);
|
||||
} catch (e) {
|
||||
showToast("Failed to search for messages.", "failure");
|
||||
Toasts.show({
|
||||
type: Toasts.Type.FAILURE,
|
||||
message: "Failed to search for messages.",
|
||||
id: Toasts.genId()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ import { gitHashShort } from "@shared/vencordUserAgent";
|
|||
import { copyToClipboard } from "@utils/clipboard";
|
||||
import { relaunch, showItemInFolder } from "@utils/native";
|
||||
import { checkForUpdates, getRepo } from "@utils/updater";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { GuildStore, NavigationRouter, SettingsRouter, showToast } from "@webpack/common";
|
||||
import { GuildStore, NavigationRouter, SettingsRouter, Toasts } from "@webpack/common";
|
||||
|
||||
import gitRemote from "~git-remote";
|
||||
import Plugins from "~plugins";
|
||||
|
|
@ -47,9 +46,14 @@ export const actions: ButtonAction[] = [
|
|||
new URL(newUrl); // Throws if invalid
|
||||
VencordNative.native.openExternal(newUrl);
|
||||
} catch {
|
||||
showToast("Invalid URL", "failure", {
|
||||
position: ToastPosition.BOTTOM
|
||||
});
|
||||
Toasts.show({
|
||||
message: "Invalid URL",
|
||||
type: Toasts.Type.FAILURE,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
});
|
||||
}
|
||||
}, registrar: "Equicord"
|
||||
},
|
||||
|
|
@ -88,14 +92,24 @@ export const actions: ButtonAction[] = [
|
|||
const text = await res.text();
|
||||
copyToClipboard(text);
|
||||
|
||||
showToast("Copied response to clipboard!", "success", {
|
||||
position: ToastPosition.BOTTOM
|
||||
});
|
||||
Toasts.show({
|
||||
message: "Copied response to clipboard!",
|
||||
type: Toasts.Type.SUCCESS,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
showToast("Issue fetching URL", "failure", {
|
||||
position: ToastPosition.BOTTOM
|
||||
});
|
||||
Toasts.show({
|
||||
message: "Issue fetching URL",
|
||||
type: Toasts.Type.FAILURE,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
});
|
||||
}
|
||||
}, registrar: "Equicord"
|
||||
},
|
||||
|
|
@ -104,9 +118,14 @@ export const actions: ButtonAction[] = [
|
|||
id: "copyGitInfo", label: "Copy Git Info", callback: async () => {
|
||||
copyToClipboard(`gitHash: ${gitHashShort}\ngitRemote: ${gitRemote}`);
|
||||
|
||||
showToast("Copied git info to clipboard!", "success", {
|
||||
position: ToastPosition.BOTTOM
|
||||
});
|
||||
Toasts.show({
|
||||
message: "Copied git info to clipboard!",
|
||||
type: Toasts.Type.SUCCESS,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
});
|
||||
}, registrar: "Equicord"
|
||||
},
|
||||
|
||||
|
|
@ -125,9 +144,14 @@ export const actions: ButtonAction[] = [
|
|||
}
|
||||
}), 10_000);
|
||||
} else {
|
||||
showToast("No updates available", "message", {
|
||||
position: ToastPosition.BOTTOM
|
||||
});
|
||||
Toasts.show({
|
||||
message: "No updates available",
|
||||
type: Toasts.Type.MESSAGE,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
});
|
||||
}
|
||||
}, registrar: "Equicord"
|
||||
},
|
||||
|
|
@ -157,9 +181,14 @@ function togglePlugin(plugin: ButtonAction, enabled: boolean) {
|
|||
|
||||
Settings.plugins[plugin.id].enabled = enabled;
|
||||
|
||||
showToast(`Successfully ${enabled ? "enabled" : "disabled"} ${plugin.id}`, "success", {
|
||||
position: ToastPosition.BOTTOM
|
||||
});
|
||||
Toasts.show({
|
||||
message: `Successfully ${enabled ? "enabled" : "disabled"} ${plugin.id}`,
|
||||
type: Toasts.Type.SUCCESS,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function registerAction(action: ButtonAction) {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { NavContextMenuPatchCallback } from "@api/ContextMenu";
|
|||
import { EquicordDevs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
import { Channel } from "@vencord/discord-types";
|
||||
import { Menu, NavigationRouter, RestAPI, showToast,UserStore } from "@webpack/common";
|
||||
import { Menu, NavigationRouter, RestAPI, Toasts, UserStore } from "@webpack/common";
|
||||
|
||||
async function findLastMessageFromUser(guildId: string, channelId: string, userId: string) {
|
||||
try {
|
||||
|
|
@ -33,17 +33,29 @@ async function findLastMessageFromUser(guildId: string, channelId: string, userI
|
|||
if (messageId) return messageId;
|
||||
} catch (error) {
|
||||
console.error("Error finding last message:", error);
|
||||
showToast("Failed to find messages. Check console for details.", "failure");
|
||||
Toasts.show({
|
||||
type: Toasts.Type.FAILURE,
|
||||
message: "Failed to find messages. Check console for details.",
|
||||
id: Toasts.genId()
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
showToast("Couldn't find any recent messages from this user.", "failure");
|
||||
Toasts.show({
|
||||
type: Toasts.Type.FAILURE,
|
||||
message: "Couldn't find any recent messages from this user.",
|
||||
id: Toasts.genId()
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
async function jumpToLastActive(channel: Channel, targetUserId?: string) {
|
||||
if (!channel) {
|
||||
showToast("Channel information not available.", "failure");
|
||||
Toasts.show({
|
||||
type: Toasts.Type.FAILURE,
|
||||
message: "Channel information not available.",
|
||||
id: Toasts.genId()
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +69,11 @@ async function jumpToLastActive(channel: Channel, targetUserId?: string) {
|
|||
}
|
||||
} catch (error) {
|
||||
console.error("Error in jumpToLastActive:", error);
|
||||
showToast("Failed to jump to message. Check console for details.", "failure");
|
||||
Toasts.show({
|
||||
type: Toasts.Type.FAILURE,
|
||||
message: "Failed to jump to message. Check console for details.",
|
||||
id: Toasts.genId()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,19 +97,17 @@ export default definePlugin({
|
|||
],
|
||||
|
||||
MentionTooltip({ Component, vcProps, ...props }) {
|
||||
return withTooltip(Component, props, vcProps?.messageId, vcProps?.channelId);
|
||||
return withTooltip(Component, props, vcProps.messageId, vcProps.channelId);
|
||||
},
|
||||
|
||||
ReplyTooltip({ Component, vcProps, ...props }) {
|
||||
const messageReference = vcProps?.baseMessage?.messageReference;
|
||||
if (!messageReference) return <Component {...props} />;
|
||||
return withTooltip(Component, props, messageReference?.message_id, messageReference?.channel_id);
|
||||
const mess = vcProps.baseMessage.messageReference;
|
||||
return withTooltip(Component, props, mess?.message_id, mess?.channel_id);
|
||||
},
|
||||
|
||||
ForwardTooltip({ Component, vcProps, ...props }) {
|
||||
const messageReference = vcProps?.message?.messageReference;
|
||||
if (!messageReference) return <Component {...props} />;
|
||||
return withTooltip(Component, props, messageReference?.message_id, messageReference?.channel_id);
|
||||
const mess = vcProps.message.messageReference;
|
||||
return withTooltip(Component, props, mess?.message_id, mess?.channel_id);
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { Button } from "@components/Button";
|
||||
import { Alerts, showToast,useState } from "@webpack/common";
|
||||
import { Alerts, Toasts, useState } from "@webpack/common";
|
||||
|
||||
import { clearMessagesIDB } from "../db";
|
||||
import { Flogger } from "../index";
|
||||
|
|
@ -33,10 +33,18 @@ export function ClearLogsButton({ label = "Clear Logs", onCleared }: ClearLogsBu
|
|||
try {
|
||||
await clearMessagesIDB();
|
||||
onCleared?.();
|
||||
showToast("Cleared Logs", "success");
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
message: "Cleared Logs",
|
||||
type: Toasts.Type.SUCCESS
|
||||
});
|
||||
} catch (err) {
|
||||
Flogger.error("Failed to clear logs", err);
|
||||
showToast("Failed to clear logs", "failure");
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
message: "Failed to clear logs",
|
||||
type: Toasts.Type.FAILURE
|
||||
});
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import { DEFAULT_IMAGE_CACHE_DIR } from "@equicordplugins/messageLoggerEnhanced/
|
|||
import { copyWithToast } from "@utils/discord";
|
||||
import { classes } from "@utils/misc";
|
||||
import { findCssClassesLazy } from "@webpack";
|
||||
import { showToast } from "@webpack/common";
|
||||
import { Toasts } from "@webpack/common";
|
||||
|
||||
const inputClasses = findCssClassesLazy("input", "inputWrapper", "editable") as Record<string, string>;
|
||||
|
||||
|
|
@ -65,9 +65,17 @@ export function SelectFolderInput({ settingsKey, successMessage }: Props) {
|
|||
const res = await Native.chooseDir(settingsKey);
|
||||
settings.store[settingsKey] = res;
|
||||
|
||||
return showToast(successMessage, "success");
|
||||
return Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.SUCCESS,
|
||||
message: successMessage
|
||||
});
|
||||
} catch (err) {
|
||||
showToast("Failed to update directory", "failure");
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.FAILURE,
|
||||
message: "Failed to update directory"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { ChannelStore, showToast } from "@webpack/common";
|
||||
import { ChannelStore, Toasts } from "@webpack/common";
|
||||
import { DBSchema, IDBPDatabase, openDB } from "idb";
|
||||
|
||||
import { LoggedMessageJSON } from "./types";
|
||||
|
|
@ -256,7 +256,7 @@ export async function deleteMessagesBulkIDB(message_ids: string[]) {
|
|||
message_ids.forEach(id => cachedMessages.delete(id));
|
||||
}
|
||||
|
||||
export async function clearMessagesIDB(toast = true) {
|
||||
export async function clearMessagesIDB(showToast = true) {
|
||||
cachedMessages.clear();
|
||||
|
||||
const deleted = await new Promise<boolean>(resolve => {
|
||||
|
|
@ -271,9 +271,13 @@ export async function clearMessagesIDB(toast = true) {
|
|||
|
||||
cachedMessages.clear();
|
||||
|
||||
if (!toast) return;
|
||||
if (!showToast) return;
|
||||
|
||||
showToast("Cleared message log database and cache.", "message");
|
||||
Toasts.show({
|
||||
type: Toasts.Type.MESSAGE,
|
||||
message: "Cleared message log database and cache.",
|
||||
id: Toasts.genId()
|
||||
});
|
||||
}
|
||||
|
||||
// faster than db.clear on large dbs
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ let didClearLogsOnStartup = false;
|
|||
|
||||
const cacheThing = findByPropsLazy("commit", "getOrCreate");
|
||||
|
||||
export async function clearLogs(toast = true) {
|
||||
await idb.clearMessagesIDB(toast);
|
||||
export async function clearLogs(showToast = true) {
|
||||
await idb.clearMessagesIDB(showToast);
|
||||
cacheSentMessages.clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
|
||||
import { updateMessage } from "@api/MessageUpdater";
|
||||
import { FluxDispatcher, Menu, MessageActions, React, showToast,SortedGuildStore, UserStore } from "@webpack/common";
|
||||
import { FluxDispatcher, Menu, MessageActions, React, SortedGuildStore, Toasts, UserStore } from "@webpack/common";
|
||||
|
||||
import { openLogModal } from "../components/LogsModal";
|
||||
import { deleteMessageIDB } from "../db";
|
||||
|
|
@ -80,7 +80,11 @@ const removeMessageAction = async (props: any) => {
|
|||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to remove message", e);
|
||||
showToast("Failed to remove message. Check console for details.", "failure");
|
||||
Toasts.show({
|
||||
type: Toasts.Type.FAILURE,
|
||||
message: "Failed to remove message. Check console for details.",
|
||||
id: Toasts.genId()
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
import JSONParser from "@streamparser/json/jsonparser.js";
|
||||
import { chooseFile as chooseFileWeb } from "@utils/web";
|
||||
import { showToast } from "@webpack/common";
|
||||
import { Toasts } from "@webpack/common";
|
||||
import { showSaveFilePicker } from "native-file-system-adapter";
|
||||
|
||||
import { clearLogs,Native } from "..";
|
||||
|
|
@ -60,15 +60,27 @@ export async function importLogs() {
|
|||
}
|
||||
|
||||
if (count === 0) {
|
||||
showToast("No messages found in log file", "failure");
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
message: "No messages found in log file",
|
||||
type: Toasts.Type.FAILURE
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
showToast(`Successfully imported ${count} logs`, "success");
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
message: `Successfully imported ${count} logs`,
|
||||
type: Toasts.Type.SUCCESS
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
||||
showToast("Error importing logs. Check the console for more information", "failure");
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
message: "Error importing logs. Check the console for more information",
|
||||
type: Toasts.Type.FAILURE
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +106,11 @@ export async function exportLogs() {
|
|||
await Native.writeNativeLogChunk(streamId, "\n ]\n}");
|
||||
await Native.finishNativeLogExport(streamId);
|
||||
|
||||
showToast("Successfully exported logs", "success");
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
message: "Successfully exported logs",
|
||||
type: Toasts.Type.SUCCESS
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -127,12 +143,20 @@ export async function exportLogs() {
|
|||
await writer.write(encoder.encode("\n ]\n}"));
|
||||
await writer.close();
|
||||
|
||||
showToast(`Successfully exported ${count} logs`, "success");
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
message: `Successfully exported ${count} logs`,
|
||||
type: Toasts.Type.SUCCESS
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
||||
showToast("Error exporting logs. Check the console for more information", "failure");
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
message: "Error exporting logs. Check the console for more information",
|
||||
type: Toasts.Type.FAILURE
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import { isV1, migrate } from "@equicordplugins/moreStickers/migrate-v1";
|
|||
import { deleteStickerPack, getStickerPack, getStickerPackMetas, saveStickerPack } from "@equicordplugins/moreStickers/stickers";
|
||||
import { SettingsTabsKey, Sticker, StickerPack, StickerPackMeta } from "@equicordplugins/moreStickers/types";
|
||||
import { cl, clPicker, Mutex } from "@equicordplugins/moreStickers/utils";
|
||||
import { Button, React, showToast,TabBar, TextArea } from "@webpack/common";
|
||||
import { Button, React, TabBar, TextArea, Toasts } from "@webpack/common";
|
||||
import { JSX } from "react";
|
||||
|
||||
const mutex = new Mutex();
|
||||
|
|
@ -58,14 +58,24 @@ const StickerPackMetadata = ({ meta, hoveredStickerPackId, setHoveredStickerPack
|
|||
onClick={async () => {
|
||||
try {
|
||||
await deleteStickerPack(meta.id);
|
||||
showToast("Sticker Pack deleted", "success", {
|
||||
Toasts.show({
|
||||
message: "Sticker Pack deleted",
|
||||
type: Toasts.Type.SUCCESS,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
});
|
||||
await refreshStickerPackMetas();
|
||||
} catch (e: any) {
|
||||
showToast(e.message, "failure", {
|
||||
Toasts.show({
|
||||
message: e.message,
|
||||
type: Toasts.Type.FAILURE,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
|
@ -200,13 +210,23 @@ export const Packs = () => {
|
|||
refreshStickerPackMetas();
|
||||
|
||||
if (errorMessage) {
|
||||
showToast(errorMessage, "failure", {
|
||||
Toasts.show({
|
||||
message: errorMessage,
|
||||
type: Toasts.Type.FAILURE,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
showToast("Sticker Pack added", "success", {
|
||||
Toasts.show({
|
||||
message: "Sticker Pack added",
|
||||
type: Toasts.Type.SUCCESS,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}}
|
||||
|
|
@ -268,13 +288,23 @@ export const Packs = () => {
|
|||
refreshStickerPackMetas();
|
||||
|
||||
if (errorMessage) {
|
||||
showToast(errorMessage, "failure", {
|
||||
Toasts.show({
|
||||
message: errorMessage,
|
||||
type: Toasts.Type.FAILURE,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
showToast("Sticker Pack added", "success", {
|
||||
Toasts.show({
|
||||
message: "Sticker Pack added",
|
||||
type: Toasts.Type.SUCCESS,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}}
|
||||
>Insert from HTML</Button>
|
||||
|
|
@ -310,14 +340,24 @@ export const Packs = () => {
|
|||
await saveStickerPack(stickerPack);
|
||||
}
|
||||
|
||||
showToast("Sticker Packs added", "success", {
|
||||
Toasts.show({
|
||||
message: "Sticker Packs added",
|
||||
type: Toasts.Type.SUCCESS,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (e: any) {
|
||||
console.error(e);
|
||||
showToast(e.message, "failure", {
|
||||
Toasts.show({
|
||||
message: e.message,
|
||||
type: Toasts.Type.FAILURE,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
input.click();
|
||||
|
|
@ -355,9 +395,14 @@ export const Packs = () => {
|
|||
a.click();
|
||||
setTimeout(() => URL.revokeObjectURL(objectUrl), 1000);
|
||||
|
||||
showToast("Sticker Packs exported", "success", {
|
||||
Toasts.show({
|
||||
message: "Sticker Packs exported",
|
||||
type: Toasts.Type.SUCCESS,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
});
|
||||
}}
|
||||
>Export Sticker Packs</Button>
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { DataStore } from "@api/index";
|
||||
import { showToast } from "@webpack/common";
|
||||
import { Toasts } from "@webpack/common";
|
||||
|
||||
import { getRecentStickers, setRecentStickers } from "./components/misc";
|
||||
import { deleteStickerPack, getStickerPack, getStickerPackMetas, saveStickerPack } from "./stickers";
|
||||
|
|
@ -74,17 +74,27 @@ export async function isV1() {
|
|||
export async function migrate() {
|
||||
const newPackMetas = await getStickerPackMetas(PACKS_KEY);
|
||||
if (newPackMetas.length > 0) {
|
||||
showToast("New sticker packs already exist, migration not needed", "failure", {
|
||||
Toasts.show({
|
||||
message: "New sticker packs already exist, migration not needed",
|
||||
type: Toasts.Type.FAILURE,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let oldPackMetas = await getStickerPackMetas(PACKS_KEY_OLD);
|
||||
if (oldPackMetas.length === 0) {
|
||||
showToast("Old sticker packs not found, nothing to migrate", "failure", {
|
||||
Toasts.show({
|
||||
message: "Old sticker packs not found, nothing to migrate",
|
||||
type: Toasts.Type.FAILURE,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -102,9 +112,14 @@ export async function migrate() {
|
|||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
showToast(`Migration failed: ${oldStickerPackMeta.title} (${oldStickerPackMeta.id})`, "failure", {
|
||||
Toasts.show({
|
||||
message: `Migration failed: ${oldStickerPackMeta.title} (${oldStickerPackMeta.id})`,
|
||||
type: Toasts.Type.FAILURE,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -121,7 +136,12 @@ export async function migrate() {
|
|||
}
|
||||
|
||||
console.log("Migration complete");
|
||||
showToast("Sticker Pack Migration Complete", "success", {
|
||||
Toasts.show({
|
||||
message: "Sticker Pack Migration Complete",
|
||||
type: Toasts.Type.SUCCESS,
|
||||
id: Toasts.genId(),
|
||||
options: {
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { getMimeFromExtension } from "@equicordplugins/fileUpload/utils/getMedia
|
|||
import { FFmpeg } from "@ffmpeg/ffmpeg";
|
||||
import { insertTextIntoChatInputBox, MessageOptions } from "@utils/discord";
|
||||
import { CloudUploadPlatform } from "@vencord/discord-types/enums";
|
||||
import { ChannelStore, CloudUploader, Constants, DraftStore, FluxDispatcher, MessageActions, PendingReplyStore, RestAPI, showToast, SnowflakeUtils, UploadHandler } from "@webpack/common";
|
||||
import { ChannelStore, CloudUploader, Constants, DraftStore, FluxDispatcher, MessageActions, PendingReplyStore, RestAPI, showToast, SnowflakeUtils, Toasts, UploadHandler } from "@webpack/common";
|
||||
|
||||
import { settings } from ".";
|
||||
import { FFmpegState, Sticker } from "./types";
|
||||
|
|
@ -169,7 +169,7 @@ export async function sendSticker({ channelId, sticker, ctrlKey, shiftKey, ffmpe
|
|||
});
|
||||
});
|
||||
|
||||
upload.on("error", () => showToast("Failed to upload sticker", "failure"));
|
||||
upload.on("error", () => showToast("Failed to upload sticker", Toasts.Type.FAILURE));
|
||||
|
||||
upload.upload();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { HeadingSecondary } from "@components/Heading";
|
|||
import { Paragraph } from "@components/Paragraph";
|
||||
import { SettingsSection } from "@components/settings/tabs/plugins/components/Common";
|
||||
import { makeRange, OptionType } from "@utils/types";
|
||||
import { MaskedLink, Select, showToast, TextInput } from "@webpack/common";
|
||||
import { MaskedLink, Select, showToast, TextInput, Toasts } from "@webpack/common";
|
||||
|
||||
import hoverOnlyStyle from "./hoverOnly.css?managed";
|
||||
import { clearLyricsCache, removeTranslations } from "./spotify/lyrics/api";
|
||||
|
|
@ -66,7 +66,7 @@ function LyricsProviderSettings() {
|
|||
onChange={v => {
|
||||
settings.store.spotifyLyricsApiUrl = v;
|
||||
void clearLyricsCache();
|
||||
showToast("Lyrics cache purged", "success");
|
||||
showToast("Lyrics cache purged", Toasts.Type.SUCCESS);
|
||||
}}
|
||||
placeholder="https://spotify-lyrics-api-pi.vercel.app"
|
||||
maxLength={null}
|
||||
|
|
@ -113,7 +113,7 @@ export const settings = definePluginSettings({
|
|||
default: "https://spotify-lyrics-api-pi.vercel.app",
|
||||
onChange: async () => {
|
||||
await clearLyricsCache();
|
||||
showToast("Lyrics cache purged", "success");
|
||||
showToast("Lyrics cache purged", Toasts.Type.SUCCESS);
|
||||
}
|
||||
},
|
||||
lyricsProviderSettings: {
|
||||
|
|
@ -126,7 +126,7 @@ export const settings = definePluginSettings({
|
|||
options: languages,
|
||||
onChange: async () => {
|
||||
await removeTranslations();
|
||||
showToast("Translations cleared", "success");
|
||||
showToast("Translations cleared", Toasts.Type.SUCCESS);
|
||||
}
|
||||
},
|
||||
lyricsConversion: {
|
||||
|
|
@ -162,7 +162,7 @@ export const settings = definePluginSettings({
|
|||
color={ButtonCompat.Colors.RED}
|
||||
onClick={() => {
|
||||
clearLyricsCache();
|
||||
showToast("Lyrics cache purged", "success");
|
||||
showToast("Lyrics cache purged", Toasts.Type.SUCCESS);
|
||||
}}
|
||||
>
|
||||
Purge Cache
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
import { definePluginSettings } from "@api/Settings";
|
||||
import { EquicordDevs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { ChannelStore, FluxDispatcher, GuildMemberStore, showToast,StreamerModeStore, UserStore, VoiceStateStore } from "@webpack/common";
|
||||
import { ChannelStore, FluxDispatcher, GuildMemberStore, StreamerModeStore, Toasts, UserStore, VoiceStateStore } from "@webpack/common";
|
||||
|
||||
interface ChannelState {
|
||||
userId: string;
|
||||
|
|
@ -211,7 +211,11 @@ const createWebsocket = () => {
|
|||
|
||||
setTimeout(() => {
|
||||
if (ws?.readyState !== WebSocket.OPEN) {
|
||||
showToast("Orbolay websocket could not connect. Is it running?", "failure");
|
||||
Toasts.show({
|
||||
message: "Orbolay websocket could not connect. Is it running?",
|
||||
type: Toasts.Type.FAILURE,
|
||||
id: Toasts.genId(),
|
||||
});
|
||||
ws = null;
|
||||
return;
|
||||
}
|
||||
|
|
@ -231,7 +235,11 @@ const createWebsocket = () => {
|
|||
ws = null;
|
||||
};
|
||||
ws.onopen = async () => {
|
||||
showToast("Connected to Orbolay server", "success");
|
||||
Toasts.show({
|
||||
message: "Connected to Orbolay server",
|
||||
type: Toasts.Type.SUCCESS,
|
||||
id: Toasts.genId(),
|
||||
});
|
||||
|
||||
const userId = await waitForPopulate(() => UserStore.getCurrentUser().id);
|
||||
if (!userId) return;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { isNonNullish } from "@utils/guards";
|
||||
import { ProfilePreset } from "@vencord/discord-types";
|
||||
import { showToast, UserProfileSettingsStore } from "@webpack/common";
|
||||
import { showToast, Toasts, UserProfileSettingsStore } from "@webpack/common";
|
||||
|
||||
import { getCurrentProfile } from "./profile";
|
||||
import { addPreset, movePresetInArray, presets, PresetSection, type ProfilePresetEx, removePreset, replaceAllPresets, savePresetsData, updatePreset } from "./storage";
|
||||
|
|
@ -133,7 +133,7 @@ export async function importPresets(
|
|||
await savePresetsData(section);
|
||||
forceUpdate();
|
||||
} catch {
|
||||
showToast("Failed to import presets. The file might be invalid.", "failure");
|
||||
showToast("Failed to import presets. The file might be invalid.", Toasts.Type.FAILURE);
|
||||
}
|
||||
};
|
||||
input.click();
|
||||
|
|
|
|||
|
|
@ -239,8 +239,8 @@ export default definePlugin({
|
|||
find: "collapsed-with-rewards\":\"collapsed-without-rewards",
|
||||
predicate: () => getQuestifySettings().disableAccountPanelPromo || !getQuestifySettings().disableAccountPanelQuestProgress,
|
||||
replacement: {
|
||||
match: /(?<=function\(\)\{)(let (\i)=\(0,\i\.\i\)\(\),\i=\(0,\i\.\i\)\(.{0,55}?\);)(?=switch\(\2\.type\)\{case (\i\.\i\.QUEST):)/,
|
||||
replace: "void $self.useQuestRerender();$1$2=$self.getQuestPanelOverride($2,$3);if(null==$2)return null;"
|
||||
match: /(?<=function\(\)\{)(let (\i)=\(0,\i\.\i\)\(\)(?:,\i=\(0,\i\.\i\)\(.{0,55}?\))?;)(?=return null==\2(?:&&null!=\i)?\?)/,
|
||||
replace: "void $self.useQuestRerender();$1$2=$self.getQuestPanelOverride($2);"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -484,7 +484,7 @@ export default definePlugin({
|
|||
},
|
||||
{
|
||||
// Adds the Questify sort option to Discord's Quest sort enum.
|
||||
find: "EXPIRING_SOON=\"expiring_soon\"",
|
||||
find: "SUGGESTED=\"suggested\",",
|
||||
predicate: () => !getQuestifySettings().disableQuestsEverything,
|
||||
replacement: {
|
||||
match: /(?<=\(\((\i)=\{\}\))(?=\.SUGGESTED="suggested",)/,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import type { PluginNative } from "@utils/types";
|
|||
import type { Quest, User } from "@vencord/discord-types";
|
||||
import { QuestTargetedContent, QuestTaskType } from "@vencord/discord-types/enums";
|
||||
import { findByCodeLazy, findLazy } from "@webpack";
|
||||
import { AuthorizedAppsStore, FluxDispatcher, QuestStore, RestAPI, showToast, UserStore } from "@webpack/common";
|
||||
import { AuthorizedAppsStore, FluxDispatcher, QuestStore, RestAPI, showToast, Toasts, UserStore } from "@webpack/common";
|
||||
|
||||
import { getCurrentUserId, getQuestifySettings } from "../settings/access";
|
||||
import { autoCompleteQuestTaskTypes, isDesktopCompatible } from "../settings/def";
|
||||
|
|
@ -251,7 +251,7 @@ function showBrokenAutoCompleteToast(): void {
|
|||
}
|
||||
|
||||
didShowBrokenAutoCompleteToast = true;
|
||||
showToast("AutoComplete is broken. A fix will be implemented shortly.", "failure");
|
||||
showToast("AutoComplete is broken. A fix will be implemented shortly.", Toasts.Type.FAILURE);
|
||||
}
|
||||
|
||||
export function hasEnabledAutoCompleteQuestTypes(): boolean {
|
||||
|
|
@ -613,7 +613,7 @@ function blockQuestEnrollmentForRetryAfter(retryAfter: number | null): void {
|
|||
function showQuestEnrollmentFailureToast(quest: Quest, result: Exclude<QuestEnrollmentResult, { type: "success"; }>): void {
|
||||
const rateLimitSuffix = result.type === "rate_limited" ? " due to rate limits" : "";
|
||||
|
||||
showToast(`Enrollment in ${normalizeQuestName(quest)} Quest failed${rateLimitSuffix}.`, "failure");
|
||||
showToast(`Enrollment in ${normalizeQuestName(quest)} Quest failed${rateLimitSuffix}.`, Toasts.Type.FAILURE);
|
||||
}
|
||||
|
||||
export async function enrollInQuestManually(quest: Quest): Promise<QuestManualEnrollResult> {
|
||||
|
|
|
|||
|
|
@ -43,11 +43,6 @@ const questProgressTaskPriority = [
|
|||
QuestTaskType.PLAY_ON_XBOX,
|
||||
] as const satisfies readonly QuestTaskType[];
|
||||
|
||||
interface QuestPanelCreative {
|
||||
type: number;
|
||||
quest?: Quest;
|
||||
}
|
||||
|
||||
interface QuestPanelPercentCompleteOptions {
|
||||
quest?: Quest | null;
|
||||
percentCompleteText?: string;
|
||||
|
|
@ -220,7 +215,7 @@ function getMostRecentlyCompletedUnclaimedQuest(): Quest | null {
|
|||
})[0] ?? null;
|
||||
}
|
||||
|
||||
export function getQuestPanelOverride(creative: QuestPanelCreative, questType: number): QuestPanelCreative | null {
|
||||
export function getQuestPanelOverride(quest: Quest | null): Quest | null {
|
||||
const panelState = useQuestifySettings(["disableQuestsEverything", "disableAccountPanelPromo", "disableAccountPanelQuestProgress"]);
|
||||
|
||||
if (panelState.disableQuestsEverything) {
|
||||
|
|
@ -232,16 +227,12 @@ export function getQuestPanelOverride(creative: QuestPanelCreative, questType: n
|
|||
}
|
||||
|
||||
if (panelState.disableAccountPanelQuestProgress) {
|
||||
return creative;
|
||||
return quest;
|
||||
}
|
||||
|
||||
const nextQuest = getAutoCompleteShowcaseQuest() ?? getMostRecentlyCompletedUnclaimedQuest();
|
||||
|
||||
if (nextQuest) {
|
||||
return { ...creative, type: questType, quest: nextQuest };
|
||||
}
|
||||
|
||||
return panelState.disableAccountPanelPromo ? null : creative;
|
||||
return nextQuest ?? (panelState.disableAccountPanelPromo ? null : quest);
|
||||
}
|
||||
|
||||
export function shouldForceQuestPanelVisible(quest: Quest | null): boolean {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { Paragraph } from "@components/Paragraph";
|
|||
import { debounce } from "@shared/debounce";
|
||||
import { Devs, IS_MAC } from "@utils/constants";
|
||||
import definePlugin, { OptionType, StartAt } from "@utils/types";
|
||||
import { showToast } from "@webpack/common";
|
||||
import { showToast, Toasts } from "@webpack/common";
|
||||
|
||||
const { VencordNative } = window;
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ const refreshThemeList = async (silent = false) => {
|
|||
const diff = themeList.length - oldCount;
|
||||
const action = diff > 0 ? "Added" : "Removed";
|
||||
const count = Math.abs(diff);
|
||||
showToast(`${action} ${count} theme${count > 1 ? "s" : ""}`, "success");
|
||||
showToast(`${action} ${count} theme${count > 1 ? "s" : ""}`, Toasts.Type.SUCCESS);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -186,7 +186,7 @@ function toggleCurrentTheme(enable: boolean) {
|
|||
|
||||
async function reloadThemes() {
|
||||
await refreshThemeList(true);
|
||||
showToast(`Reloaded ${themeList.length} themes`, "success");
|
||||
showToast(`Reloaded ${themeList.length} themes`, Toasts.Type.SUCCESS);
|
||||
}
|
||||
|
||||
async function watchForLocalThemeChanges() {
|
||||
|
|
@ -204,7 +204,7 @@ async function watchForLocalThemeChanges() {
|
|||
if (settings.store.showNotifications) {
|
||||
const action = diff > 0 ? "Added" : "Removed";
|
||||
const count = Math.abs(diff);
|
||||
showToast(`${action} ${count} local theme${count > 1 ? "s" : ""}`, "success");
|
||||
showToast(`${action} ${count} local theme${count > 1 ? "s" : ""}`, Toasts.Type.SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,10 +15,9 @@ import { debounce } from "@shared/debounce";
|
|||
import { Devs, EquicordDevs, IS_MAC } from "@utils/constants";
|
||||
import { classNameFactory } from "@utils/css";
|
||||
import definePlugin, { makeRange, OptionType } from "@utils/types";
|
||||
import type { Channel, ToastType, VoiceState } from "@vencord/discord-types";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import type { Channel, VoiceState } from "@vencord/discord-types";
|
||||
import { findByCodeLazy } from "@webpack";
|
||||
import { ChannelActions, ChannelRouter, ChannelStore, ContextMenuApi, FluxDispatcher, GuildStore, MediaEngineStore, Menu, PermissionsBits, PermissionStore, React, RelationshipStore, SelectedChannelStore, showToast as originalShowToast, useEffect, UserStore, useState, VoiceActions, VoiceStateStore } from "@webpack/common";
|
||||
import { ChannelActions, ChannelRouter, ChannelStore, ContextMenuApi, FluxDispatcher, GuildStore, MediaEngineStore, Menu, PermissionsBits, PermissionStore, React, RelationshipStore, SelectedChannelStore, Toasts, useEffect, UserStore, useState, VoiceActions, VoiceStateStore } from "@webpack/common";
|
||||
|
||||
const startStream = findByCodeLazy('type:"STREAM_START"');
|
||||
const getDesktopSources = findByCodeLazy("desktop sources");
|
||||
|
|
@ -373,8 +372,13 @@ const settings = definePluginSettings({
|
|||
},
|
||||
});
|
||||
|
||||
function showToast(message: string, type: ToastType) {
|
||||
originalShowToast(message, type, { position: ToastPosition.BOTTOM });
|
||||
function showToast(message: string, type: (typeof Toasts.Type)[keyof typeof Toasts.Type]) {
|
||||
Toasts.show({
|
||||
message,
|
||||
type,
|
||||
id: Toasts.genId(),
|
||||
options: { position: Toasts.Position.BOTTOM },
|
||||
});
|
||||
}
|
||||
|
||||
function RandomVoiceIcon({ className }: { className?: string; }) {
|
||||
|
|
@ -590,13 +594,13 @@ function runAfterVoiceJoin(channelId: string, callbacks: PostJoinAction[]) {
|
|||
async function joinRandomVoice() {
|
||||
const channelId = pickRandomChannel();
|
||||
if (!channelId) {
|
||||
showToast("Failed to find a voice channel.", "message");
|
||||
showToast("Failed to find a voice channel.", Toasts.Type.MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
const channel = ChannelStore.getChannel(channelId);
|
||||
if (!channel) {
|
||||
showToast("Voice channel is unavailable.", "failure");
|
||||
showToast("Voice channel is unavailable.", Toasts.Type.FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,7 @@ import { definePluginSettings } from "@api/Settings";
|
|||
import { EquicordDevs, IS_MAC } from "@utils/constants";
|
||||
import { classNameFactory } from "@utils/css";
|
||||
import definePlugin, { makeRange, OptionType } from "@utils/types";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { Button, ChannelRouter, ChannelStore, closeModal, IconUtils, openModal, React, RelationshipStore, SelectedChannelStore, showToast,UserStore } from "@webpack/common";
|
||||
import { Button, ChannelRouter, ChannelStore, closeModal, IconUtils, openModal,React, RelationshipStore, SelectedChannelStore, Toasts, UserStore } from "@webpack/common";
|
||||
|
||||
const STORAGE_KEY = "RDMSwitch_history";
|
||||
|
||||
|
|
@ -77,7 +76,7 @@ const settings = definePluginSettings({
|
|||
cycleSnapshot = [];
|
||||
cycleIndex = -1;
|
||||
await DataStore.set(STORAGE_KEY, []);
|
||||
showToast("Cleared RDMS history", "success");
|
||||
Toasts.show({ id: Toasts.genId(), type: Toasts.Type.SUCCESS, message: "Cleared RDMS history" });
|
||||
}}>
|
||||
"Clear RDMS History
|
||||
</Button>
|
||||
|
|
@ -85,6 +84,7 @@ const settings = definePluginSettings({
|
|||
}
|
||||
});
|
||||
|
||||
let activeToastId: string | null = null;
|
||||
let overlayModalKey: string | null = null;
|
||||
let overlayRerender: (() => void) | null = null;
|
||||
|
||||
|
|
@ -164,6 +164,7 @@ function endCycleSession() {
|
|||
|
||||
cycleSnapshot = [];
|
||||
cycleIndex = -1;
|
||||
activeToastId = null;
|
||||
|
||||
const visEnd = (settings as any).store?.visualStyle;
|
||||
if (visEnd === "overlay") unmountOverlay();
|
||||
|
|
@ -318,7 +319,13 @@ function showCycleToast() {
|
|||
const id = cycleSnapshot[cycleIndex];
|
||||
if (!id) return;
|
||||
const { name } = getDisplayForChannel(id);
|
||||
showToast(`Switching to: ${name}`, "message", { position: ToastPosition.BOTTOM, duration: settings.store.toastDurationMs });
|
||||
if (!activeToastId) activeToastId = Toasts.genId();
|
||||
Toasts.show({
|
||||
id: activeToastId,
|
||||
message: `Switching to: ${name}`,
|
||||
type: Toasts.Type.MESSAGE,
|
||||
options: { position: Toasts.Position.BOTTOM, duration: settings.store.toastDurationMs }
|
||||
});
|
||||
}
|
||||
|
||||
export default definePlugin({
|
||||
|
|
@ -362,6 +369,7 @@ export default definePlugin({
|
|||
suppressRdmsWhileCycling = false;
|
||||
cycleSnapshot = [];
|
||||
cycleIndex = -1;
|
||||
activeToastId = null;
|
||||
|
||||
const visEnd = (settings as any).store?.visualStyle;
|
||||
if (visEnd === "overlay") unmountOverlay();
|
||||
|
|
|
|||
|
|
@ -79,8 +79,8 @@ export default definePlugin({
|
|||
{
|
||||
find: '"LocalActivityStore"',
|
||||
replacement: {
|
||||
match: /(function\(\i\)\{.{0,40}activity:(\i).{0,25}=\i),(\i)/,
|
||||
replace: "$1;$self.patchActivity($2);let $3",
|
||||
match: /function\(\i\)\{.{0,40}activity:(\i).*?\i\[\i\];/,
|
||||
replace: "$&$self.patchActivity($1);",
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { Heading } from "@components/Heading";
|
|||
import { classNameFactory } from "@utils/css";
|
||||
import { RenderModalProps } from "@vencord/discord-types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { ChannelStore, closeModal, DraftType, Modal, openModal, showToast, TextInput, UploadManager, useState } from "@webpack/common";
|
||||
import { ChannelStore, closeModal, DraftType, Modal, openModal, showToast, TextInput, Toasts, UploadManager, useState } from "@webpack/common";
|
||||
|
||||
import { ScheduledAttachment } from "../types";
|
||||
import { addScheduledMessage, getChannelDisplayInfo } from "../utils";
|
||||
|
|
@ -61,7 +61,7 @@ function ScheduleTimeModalInner({ channelId, content, attachments, rootProps, cl
|
|||
if (result.success) {
|
||||
ComponentDispatch.dispatchToLastSubscribed("CLEAR_TEXT");
|
||||
UploadManager.clearAll(channelId, DraftType.ChannelMessage);
|
||||
showToast("Message scheduled!", "success");
|
||||
showToast("Message scheduled!", Toasts.Type.SUCCESS);
|
||||
close();
|
||||
} else {
|
||||
setError(result.error ?? "Failed to schedule message");
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { Button } from "@components/Button";
|
|||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { classNameFactory } from "@utils/css";
|
||||
import { RenderModalProps } from "@vencord/discord-types";
|
||||
import { ChannelStore, closeModal, Modal, openModal, showToast, useState } from "@webpack/common";
|
||||
import { ChannelStore, closeModal, Modal, openModal, showToast, Toasts, useState } from "@webpack/common";
|
||||
|
||||
import { clearAllScheduledMessages, getChannelDisplayInfo, getScheduledMessages, removeScheduledMessage } from "../utils";
|
||||
import { CalendarIcon, TimerIcon } from "./Icons";
|
||||
|
|
@ -26,13 +26,13 @@ function ViewScheduledModalInner({ rootProps, close }: ViewScheduledModalProps)
|
|||
const handleDelete = async (id: string) => {
|
||||
await removeScheduledMessage(id);
|
||||
setMessages(getScheduledMessages());
|
||||
showToast("Scheduled message removed", "success");
|
||||
showToast("Scheduled message removed", Toasts.Type.SUCCESS);
|
||||
};
|
||||
|
||||
const handleClearAll = async () => {
|
||||
await clearAllScheduledMessages();
|
||||
setMessages([]);
|
||||
showToast("All scheduled messages cleared", "success");
|
||||
showToast("All scheduled messages cleared", Toasts.Type.SUCCESS);
|
||||
};
|
||||
|
||||
const actions = [
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import * as DataStore from "@api/DataStore";
|
|||
import { Logger } from "@utils/Logger";
|
||||
import { Message } from "@vencord/discord-types";
|
||||
import { CloudUploadPlatform } from "@vencord/discord-types/enums";
|
||||
import { ChannelStore, CloudUploader, Constants, FluxDispatcher, GuildStore, IconUtils, MessageActions, MessageStore, RestAPI, showToast, SnowflakeUtils, UserStore } from "@webpack/common";
|
||||
import { ChannelStore, CloudUploader, Constants, FluxDispatcher, GuildStore, IconUtils, MessageActions, MessageStore, RestAPI, showToast, SnowflakeUtils, Toasts, UserStore } from "@webpack/common";
|
||||
|
||||
import { settings } from ".";
|
||||
import { PhantomMessageData, ScheduledAttachment, ScheduledMessage, ScheduledReaction } from "./types";
|
||||
|
|
@ -374,11 +374,11 @@ async function sendScheduledMessage(msg: ScheduledMessage): Promise<boolean> {
|
|||
}
|
||||
|
||||
if (settings.store.showNotifications) {
|
||||
showToast(`Scheduled message sent to ${getChannelDisplayInfo(msg.channelId).name}`, "success");
|
||||
showToast(`Scheduled message sent to ${getChannelDisplayInfo(msg.channelId).name}`, Toasts.Type.SUCCESS);
|
||||
}
|
||||
return true;
|
||||
} catch {
|
||||
if (settings.store.showNotifications) showToast("Failed to send scheduled message", "failure");
|
||||
if (settings.store.showNotifications) showToast("Failed to send scheduled message", Toasts.Type.FAILURE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,9 +12,8 @@ import { Logger } from "@utils/Logger";
|
|||
import { parseUrl } from "@utils/misc";
|
||||
import definePlugin from "@utils/types";
|
||||
import { Message } from "@vencord/discord-types";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { findByCodeLazy } from "@webpack";
|
||||
import { ChannelStore, Constants, Menu, MessageStore, React, RestAPI, showToast } from "@webpack/common";
|
||||
import { ChannelStore, Constants, Menu, MessageStore, React, RestAPI, showToast, Toasts } from "@webpack/common";
|
||||
|
||||
const logger = new Logger("ShowMessageEmbeds");
|
||||
|
||||
|
|
@ -190,7 +189,7 @@ function removeEmbed(url: string, message: Message) {
|
|||
}
|
||||
|
||||
function showFailureToast(message: string) {
|
||||
showToast(message, "failure", { position: ToastPosition.BOTTOM });
|
||||
showToast(message, Toasts.Type.FAILURE, { position: Toasts.Position.BOTTOM });
|
||||
}
|
||||
|
||||
export default definePlugin({
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import type { UserData } from "@song-spotlight/api/structs";
|
||||
import { showToast, UserStore } from "@webpack/common";
|
||||
import { showToast, Toasts, UserStore } from "@webpack/common";
|
||||
|
||||
import { useAuthorizationStore } from "./stores/AuthorizationStore";
|
||||
import { useSongStore } from "./stores/SongStore";
|
||||
|
|
@ -65,20 +65,20 @@ export async function authFetch(url: string | URL, options?: RequestInit, retrie
|
|||
if (retry) return await authFetch(url, options, true);
|
||||
else {
|
||||
useAuthorizationStore.getState().deleteTokens();
|
||||
showToast("You have been signed out from Song Spotlight. Please sign in again.", "failure");
|
||||
showToast("You have been signed out from Song Spotlight. Please sign in again.", Toasts.Type.FAILURE);
|
||||
}
|
||||
} else {
|
||||
showToast(
|
||||
!text.includes("<body>") && res.status >= 400 && res.status <= 599
|
||||
? `Song Spotlight: ${text}`
|
||||
: `Song Spotlight fetch error at ${url.pathname}`,
|
||||
"failure",
|
||||
Toasts.Type.FAILURE,
|
||||
);
|
||||
}
|
||||
|
||||
throw new Error(text);
|
||||
} catch (error) {
|
||||
showToast(`Song Spotlight: ${error}`, "failure");
|
||||
showToast(`Song Spotlight: ${error}`, Toasts.Type.FAILURE);
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { ApplicationIntegrationType } from "@vencord/discord-types/enums";
|
||||
import { OAuth2AuthorizeModal, openModal, showToast } from "@webpack/common";
|
||||
import { OAuth2AuthorizeModal, openModal,showToast, Toasts } from "@webpack/common";
|
||||
|
||||
import { apiConstants, authFetch, getData } from "./api";
|
||||
import { useAuthorizationStore } from "./stores/AuthorizationStore";
|
||||
|
|
@ -41,10 +41,10 @@ export function presentOAuth2Modal() {
|
|||
useAuthorizationStore.getState().setToken(access, refresh);
|
||||
getData();
|
||||
|
||||
showToast("Successfully authorized!", "success");
|
||||
showToast("Successfully authorized!", Toasts.Type.SUCCESS);
|
||||
} catch (error) {
|
||||
logger.error("Got an error during OAuth2", error);
|
||||
if (typeof error === "string") showToast(error, "failure");
|
||||
if (typeof error === "string") showToast(error, Toasts.Type.FAILURE);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
import { logger } from "@equicordplugins/songSpotlight.desktop/lib/utils";
|
||||
import settings from "@equicordplugins/songSpotlight.desktop/settings";
|
||||
import { RenderInfoEntry, RenderInfoEntryAudio } from "@song-spotlight/api/handlers";
|
||||
import { showToast, useCallback, useEffect, useMemo, useRef } from "@webpack/common";
|
||||
import { showToast, Toasts, useCallback, useEffect, useMemo, useRef } from "@webpack/common";
|
||||
import { RefObject } from "react";
|
||||
|
||||
interface AudioItemProps {
|
||||
|
|
@ -103,7 +103,7 @@ export default function AudioPlayer({ audioRef, list, playing, setPlaying, setLo
|
|||
node.currentTime = audio.previewStart ? audio.previewStart / 1000 : 0;
|
||||
node.volume = BASE_VOLUME * (settings.store.previewVolume / 100);
|
||||
node.play().catch(error => {
|
||||
showToast("Failed to play song preview!", "failure");
|
||||
showToast("Failed to play song preview!", Toasts.Type.FAILURE);
|
||||
logger.error("Failed to play audio", error);
|
||||
setPlaying(undefined);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import { sid } from "@song-spotlight/api/util";
|
|||
import { readClipboard } from "@utils/clipboard";
|
||||
import { copyWithToast } from "@utils/discord";
|
||||
import { RenderModalProps } from "@vencord/discord-types";
|
||||
import { Alerts, Modal, openModal, Parser, showToast, useCallback, useEffect, useMemo, useRef, useState } from "@webpack/common";
|
||||
import { Alerts, Modal,openModal, Parser, showToast, Toasts, useCallback, useEffect, useMemo, useRef, useState } from "@webpack/common";
|
||||
|
||||
interface ImportButtonProps {
|
||||
overwrite: boolean;
|
||||
|
|
@ -39,24 +39,24 @@ function ImportButton({ overwrite, pending, setPending, onImport }: ImportButton
|
|||
json = JSON.parse(await readClipboard());
|
||||
} catch {
|
||||
setPending(false);
|
||||
return showToast("No JSON in clipboard!", "failure");
|
||||
return showToast("No JSON in clipboard!", Toasts.Type.FAILURE);
|
||||
}
|
||||
|
||||
const { error, data } = UserDataSchema.max(apiConstants.songLimit).safeParse(json);
|
||||
if (error) {
|
||||
setPending(false);
|
||||
return showToast("Invalid Song Spotlight data in clipboard!", "failure");
|
||||
return showToast("Invalid Song Spotlight data in clipboard!", Toasts.Type.FAILURE);
|
||||
}
|
||||
|
||||
const validated = await Promise.allSettled(data.map(song => Native.validateSong(song)));
|
||||
if (!validated.every(x => x.status === "fulfilled" && x.value)) {
|
||||
setPending(false);
|
||||
return showToast("One or more imported songs were invalid.", "failure");
|
||||
return showToast("One or more imported songs were invalid.", Toasts.Type.FAILURE);
|
||||
}
|
||||
|
||||
onImport(data);
|
||||
setPending(false);
|
||||
showToast("Imported songs from clipboard!", "success");
|
||||
showToast("Imported songs from clipboard!", Toasts.Type.SUCCESS);
|
||||
}, [pending]);
|
||||
|
||||
return (
|
||||
|
|
@ -153,7 +153,7 @@ export default function Settings({ templateData }: SettingsProps) {
|
|||
setPending(true);
|
||||
try {
|
||||
await saveData(localData);
|
||||
showToast("Successfully saved songs!", "success");
|
||||
showToast("Successfully saved songs!", Toasts.Type.SUCCESS);
|
||||
} finally {
|
||||
setPending(false);
|
||||
}
|
||||
|
|
@ -173,7 +173,7 @@ export default function Settings({ templateData }: SettingsProps) {
|
|||
variant="dangerPrimary"
|
||||
onClick={() => {
|
||||
deleteTokens();
|
||||
showToast("Successfully signed out!", "success");
|
||||
showToast("Successfully signed out!", Toasts.Type.SUCCESS);
|
||||
}}
|
||||
disabled={pending}
|
||||
>
|
||||
|
|
@ -191,7 +191,7 @@ export default function Settings({ templateData }: SettingsProps) {
|
|||
await deleteData();
|
||||
deleteTokens();
|
||||
|
||||
showToast("Successfully deleted songs!", "success");
|
||||
showToast("Successfully deleted songs!", Toasts.Type.SUCCESS);
|
||||
} finally {
|
||||
setPending(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@ import { sid } from "@song-spotlight/api/util";
|
|||
import { classes } from "@utils/misc";
|
||||
import { User } from "@vencord/discord-types";
|
||||
import {
|
||||
openUserProfileModal,
|
||||
SelectedChannelStore,
|
||||
SelectedGuildStore,
|
||||
useEffect,
|
||||
useMemo,
|
||||
UserProfileActions,
|
||||
UserStore,
|
||||
useState,
|
||||
} from "@webpack/common";
|
||||
|
|
@ -70,14 +70,14 @@ export default function CollapsedProfileSongs({ data, user, isSideBar, isRedesig
|
|||
if (!user) return;
|
||||
|
||||
const guildId = SelectedGuildStore.getGuildId();
|
||||
openUserProfileModal({
|
||||
UserProfileActions.openUserProfileModal({
|
||||
userId,
|
||||
guildId,
|
||||
channelId: SelectedChannelStore.getChannelId(),
|
||||
sourceAnalyticsLocations: [
|
||||
"username",
|
||||
"user profile popout",
|
||||
],
|
||||
analyticsLocation: {
|
||||
page: guildId ? "Guild Channel" : "DM Channel",
|
||||
section: "Profile Popout",
|
||||
},
|
||||
tabSection: "SONG_SPOTLIGHT",
|
||||
});
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,21 @@ import { Song as SongType } from "@song-spotlight/api/structs";
|
|||
import { isListLayout, sid } from "@song-spotlight/api/util";
|
||||
import { copyWithToast } from "@utils/discord";
|
||||
import { classes } from "@utils/misc";
|
||||
import { Clickable, ContextMenuApi, FluxDispatcher, Menu, React, ScrollerThin, showToast, Tooltip, useCallback, useMemo, useRef, useState } from "@webpack/common";
|
||||
import {
|
||||
Clickable,
|
||||
ContextMenuApi,
|
||||
FluxDispatcher,
|
||||
Menu,
|
||||
React,
|
||||
ScrollerThin,
|
||||
showToast,
|
||||
Toasts,
|
||||
Tooltip,
|
||||
useCallback,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState
|
||||
} from "@webpack/common";
|
||||
|
||||
interface SongEntryProps {
|
||||
entry: RenderInfoEntryBased;
|
||||
|
|
@ -74,7 +88,7 @@ function SongEntry({ entry, number, isLoaded, isPlaying, big, onClick }: SongEnt
|
|||
|
||||
const song = await Native.parseLink(entry.link);
|
||||
if (!song) {
|
||||
return showToast("Uh oh, this song doesn't exist!", "failure");
|
||||
return showToast("Uh oh, this song doesn't exist!", Toasts.Type.FAILURE);
|
||||
}
|
||||
|
||||
if (self.find(x => sid(x) === sid(song))) {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { Logger } from "@utils/Logger";
|
|||
import { sleep } from "@utils/misc";
|
||||
import definePlugin, { makeRange, OptionType } from "@utils/types";
|
||||
import type { Channel } from "@vencord/discord-types";
|
||||
import { ChannelStore, ComponentDispatch, PermissionsBits, PermissionStore, showToast,UserStore } from "@webpack/common";
|
||||
import { ChannelStore, ComponentDispatch, PermissionsBits, PermissionStore, Toasts, UserStore } from "@webpack/common";
|
||||
|
||||
import { splitMessage, type SplitMode } from "./splitMessage";
|
||||
|
||||
|
|
@ -120,7 +120,11 @@ const listener: MessageSendListener = async (channelId, message) => {
|
|||
|
||||
const channel = ChannelStore.getChannel(channelId);
|
||||
if (!canSplitInChannel(channel)) {
|
||||
showToast("Cannot split this message because of the channel's slowmode.", "failure");
|
||||
Toasts.show({
|
||||
message: "Cannot split this message because of the channel's slowmode.",
|
||||
id: "vc-splitLargeMessages-blocked",
|
||||
type: Toasts.Type.FAILURE,
|
||||
});
|
||||
return { cancel: true };
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +134,11 @@ const listener: MessageSendListener = async (channelId, message) => {
|
|||
const sent = await sendChunks(channelId, chunks, getSendDelay(channel));
|
||||
if (sent !== chunks.length) {
|
||||
restoreUnsentContent(channelId, chunks, sent);
|
||||
showToast(`Only ${sent}/${chunks.length} message parts were sent.`, "failure");
|
||||
Toasts.show({
|
||||
message: `Only ${sent}/${chunks.length} message parts were sent.`,
|
||||
id: "vc-splitLargeMessages-failure",
|
||||
type: Toasts.Type.FAILURE,
|
||||
});
|
||||
}
|
||||
|
||||
return { cancel: true };
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import { proxyLazy } from "@utils/lazy";
|
|||
import { useForceUpdater } from "@utils/react";
|
||||
import definePlugin, { OptionType, StartAt } from "@utils/types";
|
||||
import { extractAndLoadChunksLazy, findComponentByCodeLazy, findModuleId, wreq } from "@webpack";
|
||||
import { Menu, openModalLazy, OverridePremiumTypeStore, showToast } from "@webpack/common";
|
||||
import { Menu, openModalLazy, OverridePremiumTypeStore, Toasts } from "@webpack/common";
|
||||
|
||||
interface Emoji {
|
||||
animated: boolean;
|
||||
|
|
@ -141,7 +141,7 @@ export default definePlugin({
|
|||
{
|
||||
find: "#{intl::STATUS_MENU_LABEL}",
|
||||
replacement: {
|
||||
match: /(popoutContainerRef:\i,scrollerRef:\i.{0,50}\}\))(?=\])/,
|
||||
match: /(popoutContainerRef:\i,forceOpen:\i.{0,25}\}\))(?=\])/,
|
||||
replace: "$1,$self.render()"
|
||||
}
|
||||
},
|
||||
|
|
@ -189,7 +189,11 @@ export default definePlugin({
|
|||
style: { marginLeft: "20px" },
|
||||
onClick: () => {
|
||||
settings.store.StatusPresets[status.text] = status;
|
||||
showToast("Successfully Saved Status", "success");
|
||||
Toasts.show({
|
||||
message: "Successfully Saved Status",
|
||||
type: Toasts.Type.SUCCESS,
|
||||
id: Toasts.genId()
|
||||
});
|
||||
}
|
||||
};
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
import * as DataStore from "@api/DataStore";
|
||||
import { proxyLazy } from "@utils/lazy";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { OAuth2AuthorizeModal, openModal, showToast, UserStore, zustandCreate, zustandPersist } from "@webpack/common";
|
||||
import { OAuth2AuthorizeModal, openModal, showToast, Toasts, UserStore, zustandCreate, zustandPersist } from "@webpack/common";
|
||||
|
||||
import { AUTHORIZE_URL, CLIENT_ID } from "../constants";
|
||||
import { useStreaksStore } from "./StreaksStore";
|
||||
|
|
@ -78,7 +78,7 @@ export const useAuthorizationStore = proxyLazy(() => zustandCreate(
|
|||
resolve(void 0);
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
showToast(`Failed to authorize: ${e.message}`, "failure");
|
||||
showToast(`Failed to authorize: ${e.message}`, Toasts.Type.FAILURE);
|
||||
new Logger("Streaks").error("Failed to authorize", e);
|
||||
reject(e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import { openInviteModal } from "@utils/discord";
|
|||
import { Margins } from "@utils/margins";
|
||||
import type { PluginNative } from "@utils/types";
|
||||
import { findComponentByCodeLazy } from "@webpack";
|
||||
import { Button, Modal, openModal, Parser, React, showToast } from "@webpack/common";
|
||||
import { Button, Modal, openModal, Parser, React, showToast, Toasts } from "@webpack/common";
|
||||
|
||||
import { logger } from "./ThemeTab";
|
||||
|
||||
|
|
@ -25,10 +25,10 @@ const UserSummaryItem = findComponentByCodeLazy("defaultRenderUser", "showDefaul
|
|||
async function downloadTheme(theme: Theme) {
|
||||
try {
|
||||
await Native.downloadTheme(theme);
|
||||
showToast(`Downloaded ${theme.name}!`, "success");
|
||||
showToast(`Downloaded ${theme.name}!`, Toasts.Type.SUCCESS);
|
||||
} catch (err: unknown) {
|
||||
logger.error(err);
|
||||
showToast(`Failed to download ${theme.name}! (check console)`, "failure");
|
||||
showToast(`Failed to download ${theme.name}! (check console)`, Toasts.Type.FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -166,7 +166,7 @@ export const ThemeInfoModal: React.FC<ThemeInfoModalProps> = ({ author, theme, .
|
|||
onClick={async e => {
|
||||
e.preventDefault();
|
||||
const useInvite = guild ? guild.invite_link?.split("discord.gg/")[1] : invite;
|
||||
useInvite != null && openInviteModal(useInvite).catch(() => showToast("Invalid or expired invite!", "failure"));
|
||||
useInvite != null && openInviteModal(useInvite).catch(() => showToast("Invalid or expired invite!", Toasts.Type.FAILURE));
|
||||
}}
|
||||
>
|
||||
Join Discord Server
|
||||
|
|
@ -194,7 +194,7 @@ export const ThemeInfoModal: React.FC<ThemeInfoModalProps> = ({ author, theme, .
|
|||
variant: "primary",
|
||||
onClick: () => {
|
||||
copyToClipboard(themeContent);
|
||||
showToast("Copied to Clipboard", "success");
|
||||
showToast("Copied to Clipboard", Toasts.Type.SUCCESS);
|
||||
}
|
||||
}
|
||||
]}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@
|
|||
import * as DataStore from "@api/DataStore";
|
||||
import { showNotification } from "@api/Notifications";
|
||||
import { logger, themeRequest } from "@equicordplugins/themeLibrary/components/ThemeTab";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { OAuth2AuthorizeModal, openModal, showToast,UserStore } from "@webpack/common";
|
||||
import { OAuth2AuthorizeModal, openModal,Toasts, UserStore } from "@webpack/common";
|
||||
|
||||
export async function authorizeUser(triggerModal: boolean = true) {
|
||||
const isAuthorized = await getAuthorization();
|
||||
|
|
@ -65,10 +64,15 @@ export async function authorizeUser(triggerModal: boolean = true) {
|
|||
export async function deauthorizeUser() {
|
||||
const uniqueToken = await DataStore.get<Record<string, string>>("ThemeLibrary_uniqueToken");
|
||||
|
||||
if (!uniqueToken) return showToast("No uniqueToken present, try authorizing first!", "failure", {
|
||||
if (!uniqueToken) return Toasts.show({
|
||||
message: "No uniqueToken present, try authorizing first!",
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.FAILURE,
|
||||
options: {
|
||||
duration: 2e3,
|
||||
position: ToastPosition.BOTTOM
|
||||
});
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
});
|
||||
|
||||
const res = await themeRequest("/user/revoke", {
|
||||
method: "DELETE",
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ import { Paragraph } from "@components/Paragraph";
|
|||
import { copyToClipboard } from "@utils/clipboard";
|
||||
import { classNameFactory } from "@utils/css";
|
||||
import { OptionType } from "@utils/types";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { Button, showToast } from "@webpack/common";
|
||||
import { Button, Toasts } from "@webpack/common";
|
||||
|
||||
import { authorizeUser, deauthorizeUser } from "./auth";
|
||||
|
||||
|
|
@ -33,17 +32,27 @@ export const settings = definePluginSettings({
|
|||
const handleClick = async () => {
|
||||
const token = await DataStore.get("ThemeLibrary_uniqueToken");
|
||||
|
||||
if (!token) return showToast("No token to copy, try authorizing first!", "failure", {
|
||||
if (!token) return Toasts.show({
|
||||
message: "No token to copy, try authorizing first!",
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.FAILURE,
|
||||
options: {
|
||||
duration: 2.5e3,
|
||||
position: ToastPosition.BOTTOM
|
||||
});
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
});
|
||||
|
||||
copyToClipboard(token);
|
||||
|
||||
showToast("Copied to Clipboard!", "success", {
|
||||
Toasts.show({
|
||||
message: "Copied to Clipboard!",
|
||||
id: Toasts.genId(),
|
||||
type: Toasts.Type.SUCCESS,
|
||||
options: {
|
||||
duration: 2.5e3,
|
||||
position: ToastPosition.BOTTOM
|
||||
});
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { OAuth2AuthorizeModal, openModal, showToast } from "@webpack/common";
|
||||
import { OAuth2AuthorizeModal, openModal, showToast, Toasts } from "@webpack/common";
|
||||
|
||||
import { settings } from ".";
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ function getRedirectUri(): string {
|
|||
function handleApiError(error: any, defaultMessage: string): void {
|
||||
console.error(defaultMessage, error);
|
||||
const message = error?.message || defaultMessage;
|
||||
showToast(message, "failure");
|
||||
showToast(message, Toasts.Type.FAILURE);
|
||||
}
|
||||
|
||||
async function safeJsonParse(response: Response): Promise<any> {
|
||||
|
|
@ -111,7 +111,7 @@ async function setTimezoneInternal(timezone: string): Promise<boolean> {
|
|||
return false;
|
||||
}
|
||||
|
||||
showToast("Timezone updated successfully!", "success");
|
||||
showToast("Timezone updated successfully!", Toasts.Type.SUCCESS);
|
||||
return true;
|
||||
} catch (e) {
|
||||
handleApiError(e, "Failed to set timezone");
|
||||
|
|
@ -149,7 +149,7 @@ async function deleteTimezoneInternal(): Promise<boolean> {
|
|||
return false;
|
||||
}
|
||||
|
||||
showToast("Timezone deleted successfully!", "success");
|
||||
showToast("Timezone deleted successfully!", Toasts.Type.SUCCESS);
|
||||
return true;
|
||||
} catch (e) {
|
||||
handleApiError(e, "Failed to delete timezone");
|
||||
|
|
@ -180,7 +180,7 @@ export function authModal(callback?: () => void) {
|
|||
handleApiError(json, "Authorization failed");
|
||||
return;
|
||||
}
|
||||
showToast("Authorization successful!", "success");
|
||||
showToast("Authorization successful!", Toasts.Type.SUCCESS);
|
||||
callback?.();
|
||||
} catch (e) {
|
||||
handleApiError(e, "Unexpected error during authorization");
|
||||
|
|
|
|||
|
|
@ -13,9 +13,8 @@ import ErrorBoundary from "@components/ErrorBoundary";
|
|||
import { Devs, EquicordDevs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { Message, User } from "@vencord/discord-types";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { findByPropsLazy, findCssClassesLazy } from "@webpack";
|
||||
import { Button, ChannelStore, Menu, openModal, showToast, Tooltip, useEffect, UserStore, useState } from "@webpack/common";
|
||||
import { Button, ChannelStore, Menu, openModal, showToast, Toasts, Tooltip, useEffect, UserStore, useState } from "@webpack/common";
|
||||
|
||||
import { deleteTimezone, getTimezone, loadDatabaseTimezones, setUserDatabaseTimezone } from "./database";
|
||||
import { SetTimezoneModal } from "./TimezoneModal";
|
||||
|
|
@ -128,7 +127,7 @@ export const settings = definePluginSettings({
|
|||
await deleteTimezone();
|
||||
} catch (error) {
|
||||
console.error("Error resetting database timezone:", error);
|
||||
showToast("Failed to reset database timezone", "failure");
|
||||
showToast("Failed to reset database timezone", Toasts.Type.FAILURE);
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
|
@ -313,14 +312,14 @@ export default definePlugin({
|
|||
const good = await loadDatabaseTimezones();
|
||||
|
||||
if (good) {
|
||||
showToast("Timezones refreshed successfully!", "success");
|
||||
showToast("Timezones refreshed successfully!", Toasts.Type.SUCCESS);
|
||||
} else {
|
||||
showToast("Timezones Failed to refresh!", "failure");
|
||||
showToast("Timezones Failed to refresh!", Toasts.Type.FAILURE);
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
console.error("Failed to refresh timezone:", error);
|
||||
showToast("Failed to refresh timezones.", "failure");
|
||||
showToast("Failed to refresh timezones.", Toasts.Type.FAILURE);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -334,7 +333,7 @@ export default definePlugin({
|
|||
if (!settings.store.askedTimezone) {
|
||||
showToast(
|
||||
"",
|
||||
"message",
|
||||
Toasts.Type.MESSAGE,
|
||||
{
|
||||
duration: 10000,
|
||||
component: (
|
||||
|
|
@ -347,7 +346,7 @@ export default definePlugin({
|
|||
Want to save your timezone to the database? Click here to set it.
|
||||
</Button>
|
||||
),
|
||||
position: ToastPosition.BOTTOM
|
||||
position: Toasts.Position.BOTTOM
|
||||
}
|
||||
);
|
||||
settings.store.askedTimezone = true;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { sendBotMessage } from "@api/Commands";
|
|||
import { insertTextIntoChatInputBox, sendMessage } from "@utils/discord";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { Message } from "@vencord/discord-types";
|
||||
import { MessageStore, showToast, UserStore } from "@webpack/common";
|
||||
import { MessageStore, showToast, Toasts, UserStore } from "@webpack/common";
|
||||
|
||||
import { settings } from "./settings";
|
||||
|
||||
|
|
@ -225,7 +225,7 @@ function getSystemPrompt() {
|
|||
|
||||
export async function getResponse(payload: ApiMessage[]): Promise<string> {
|
||||
if (!settings.store.apiKey || !settings.store.endpoint || !settings.store.model) {
|
||||
showToast("TriviaAI: API settings are incomplete.", "failure");
|
||||
showToast("TriviaAI: API settings are incomplete.", Toasts.Type.FAILURE);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
@ -258,7 +258,7 @@ export async function getResponse(payload: ApiMessage[]): Promise<string> {
|
|||
if (!req.ok || data.error) {
|
||||
const errorMsg = data.error?.message ?? rawBody ?? `Status ${req.status}`;
|
||||
logger.error(`API Error: ${errorMsg}`);
|
||||
showToast(errorMsg, "failure");
|
||||
showToast(errorMsg, Toasts.Type.FAILURE);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +271,7 @@ export async function getResponse(payload: ApiMessage[]): Promise<string> {
|
|||
return response;
|
||||
} catch (e) {
|
||||
logger.error("Error getting response from AI model", e);
|
||||
showToast("Error getting response from AI model", "failure");
|
||||
showToast("Error getting response from AI model", Toasts.Type.FAILURE);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { Heading } from "@components/Heading";
|
|||
import { Margins } from "@components/margins";
|
||||
import { classNameFactory } from "@utils/css";
|
||||
import { RenderModalProps } from "@vencord/discord-types";
|
||||
import { IconUtils, Modal, React, showToast,TextInput, UserStore, useState } from "@webpack/common";
|
||||
import { IconUtils, Modal, React, TextInput, Toasts, UserStore, useState } from "@webpack/common";
|
||||
|
||||
import { data, KEY_DATASTORE } from ".";
|
||||
|
||||
|
|
@ -47,7 +47,11 @@ export function SetAvatarModal({ userId, modalProps }: { userId: string; modalPr
|
|||
if (!file.type.startsWith("image/")) return;
|
||||
|
||||
if (file.type === "image/gif" || file.type === "image/webp") {
|
||||
showToast("GIFs/WebP must be added via URL. Upload your GIF/WebP to a image hosting service and paste the link.", "failure");
|
||||
Toasts.show({
|
||||
message: "GIFs/WebP must be added via URL. Upload your GIF/WebP to a image hosting service and paste the link.",
|
||||
type: Toasts.Type.FAILURE,
|
||||
id: Toasts.genId(),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import {
|
|||
} from "@components/settings/tabs/BaseTab";
|
||||
import { classes, isObjectEmpty } from "@utils/misc";
|
||||
import { relaunch } from "@utils/native";
|
||||
import { Alerts, closeAllModals, NavigationRouter, showToast,useEffect, useState } from "@webpack/common";
|
||||
import { Alerts, closeAllModals,NavigationRouter, Toasts, useEffect, useState } from "@webpack/common";
|
||||
|
||||
import userpluginInstaller, { Native } from "..";
|
||||
import {
|
||||
|
|
@ -236,7 +236,11 @@ function UserPluginsTab() {
|
|||
setEnabled={t => {
|
||||
Vencord.Settings.plugins[pl.name].enabled = t;
|
||||
if (pluginRequiresRestart(pl)) {
|
||||
showToast("Restart to apply changes!", "message");
|
||||
Toasts.show({
|
||||
id: Toasts.genId(),
|
||||
message: "Restart to apply changes!",
|
||||
type: Toasts.Type.MESSAGE
|
||||
});
|
||||
} else {
|
||||
(t ? startPlugin : stopPlugin)(pl);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,9 +12,8 @@ import { definePluginSettings } from "@api/Settings";
|
|||
import { EquicordDevs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { chooseFile, saveFile } from "@utils/web";
|
||||
import { CustomEmoji, ToastType, UnicodeEmoji } from "@vencord/discord-types";
|
||||
import { ToastPosition } from "@vencord/discord-types/enums";
|
||||
import { Alerts, Button, EmojiStore, GuildStore, IconUtils, Menu, showToast as originalShowToast, useEffect, useState } from "@webpack/common";
|
||||
import { CustomEmoji, UnicodeEmoji } from "@vencord/discord-types";
|
||||
import { Alerts, Button, EmojiStore, GuildStore, IconUtils, Menu, Toasts, useEffect, useState } from "@webpack/common";
|
||||
import { JSX } from "react";
|
||||
|
||||
import { ContextMenuEmoji, SavedEmoji, Target } from "./types";
|
||||
|
|
@ -74,9 +73,14 @@ function buildSaveData(item: ContextMenuEmoji): SavedEmoji {
|
|||
return saveData;
|
||||
}
|
||||
|
||||
function showToast(message: string, type: ToastType = "success") {
|
||||
function showToast(message: string, type = Toasts.Type.SUCCESS) {
|
||||
if (settings.store.disableToasts) return;
|
||||
originalShowToast(message, type, { duration: 3000, position: ToastPosition.BOTTOM });
|
||||
Toasts.show({
|
||||
message,
|
||||
type,
|
||||
id: Toasts.genId(),
|
||||
options: { duration: 3000, position: Toasts.Position.BOTTOM }
|
||||
});
|
||||
}
|
||||
|
||||
function addBulkToAllowedList(items: ContextMenuEmoji[]) {
|
||||
|
|
@ -100,7 +104,7 @@ function removeBulkFromAllowedList(items: ContextMenuEmoji[]) {
|
|||
function addToAllowedList(item: ContextMenuEmoji) {
|
||||
return withWriteLock(async () => {
|
||||
if (itemAlreadyInList(item)) {
|
||||
showToast(`"${item.name}" is already in the list`, "failure");
|
||||
showToast(`"${item.name}" is already in the list`, Toasts.Type.FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -112,7 +116,7 @@ function addToAllowedList(item: ContextMenuEmoji) {
|
|||
function removeFromAllowedList(item: ContextMenuEmoji) {
|
||||
return withWriteLock(async () => {
|
||||
if (!itemAlreadyInList(item)) {
|
||||
showToast(`"${item.name}" is not in the list`, "failure");
|
||||
showToast(`"${item.name}" is not in the list`, Toasts.Type.FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -319,10 +323,10 @@ const importEmojis = (data: string) => withWriteLock(async () => {
|
|||
await setAllowedList(parsed.emojis);
|
||||
showToast("Successfully imported emojis");
|
||||
} else {
|
||||
showToast("Invalid JSON data", "failure");
|
||||
showToast("Invalid JSON data", Toasts.Type.FAILURE);
|
||||
}
|
||||
} catch (err) {
|
||||
showToast(`Failed to import emojis: ${err}`, "failure");
|
||||
showToast(`Failed to import emojis: ${err}`, Toasts.Type.FAILURE);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ if (!IS_VANILLA) {
|
|||
return;
|
||||
}
|
||||
|
||||
const { frameless, mainWindowFrameless, nativeTitleBar, disableMinSize, transparent, macosVibrancyStyle, windowsMaterial } = settings;
|
||||
const { frameless, mainWindowFrameless, winNativeTitleBar, disableMinSize, transparent, macosVibrancyStyle, windowsMaterial } = settings;
|
||||
|
||||
const original = options.webPreferences.preload;
|
||||
const isMainWindow = options.title === "Discord";
|
||||
|
|
@ -98,7 +98,7 @@ if (!IS_VANILLA) {
|
|||
options.frame = false;
|
||||
} else if (frameless) {
|
||||
options.frame = false;
|
||||
} else if (process.platform === "win32" && nativeTitleBar) {
|
||||
} else if (process.platform === "win32" && winNativeTitleBar) {
|
||||
delete options.frame;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,27 @@
|
|||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { gitHash } from "@shared/vencordUserAgent";
|
||||
import { app, BaseWindow, BrowserWindow, dialog, Menu, MenuItemConstructorOptions, shell } from "electron";
|
||||
import { IpcEvents } from "@shared/IpcEvents";
|
||||
import { gitHashShort } from "@shared/vencordUserAgent";
|
||||
import { BrowserWindow, ipcMain, Menu, MenuItemConstructorOptions, shell } from "electron";
|
||||
import aboutHtml from "file://about.html?minify";
|
||||
|
||||
import updater from "./updater";
|
||||
import { SETTINGS_DIR, THEMES_DIR } from "./utils/constants";
|
||||
|
||||
let cachedUpdateAvailable = false;
|
||||
|
||||
ipcMain.on(IpcEvents.SET_TRAY_UPDATE_STATE, (_, available: boolean) => {
|
||||
cachedUpdateAvailable = available;
|
||||
});
|
||||
|
||||
function getMainWindow(): BrowserWindow | undefined {
|
||||
return BrowserWindow.getFocusedWindow() ?? BrowserWindow.getAllWindows()[0];
|
||||
}
|
||||
|
||||
function sendToRenderer(event: IpcEvents): void {
|
||||
getMainWindow()?.webContents.send(event);
|
||||
}
|
||||
|
||||
function findInsertIndex(template: MenuItemConstructorOptions[]): number {
|
||||
const openIndex = template.findIndex(item => {
|
||||
const label = item.label?.toLowerCase() ?? "";
|
||||
|
|
@ -47,11 +61,14 @@ function openAboutWindow() {
|
|||
return;
|
||||
}
|
||||
|
||||
const height = 750;
|
||||
const width = height * (4 / 3);
|
||||
|
||||
aboutWindow = new BrowserWindow({
|
||||
center: true,
|
||||
autoHideMenuBar: true,
|
||||
height: 525,
|
||||
width: 900
|
||||
height,
|
||||
width
|
||||
});
|
||||
|
||||
aboutWindow.webContents.setWindowOpenHandler(({ url }) => {
|
||||
|
|
@ -66,7 +83,7 @@ function openAboutWindow() {
|
|||
|
||||
const aboutParams = aboutHtml
|
||||
.replaceAll("{{VERSION}}", VERSION)
|
||||
.replaceAll("{{GIT_HASH}}", gitHash); // change to gitHashShort if/when its added
|
||||
.replaceAll("{{GIT_HASH}}", gitHashShort);
|
||||
const base64Html = Buffer.from(aboutParams).toString("base64");
|
||||
aboutWindow.loadURL(`data:text/html;base64,${base64Html}`);
|
||||
aboutWindow.on("closed", () => {
|
||||
|
|
@ -74,9 +91,7 @@ function openAboutWindow() {
|
|||
});
|
||||
}
|
||||
|
||||
const notify = (window: BaseWindow, title: string, message: string) => dialog.showMessageBox(window, { title, message });
|
||||
|
||||
function createVencordMenuItems(): MenuItemConstructorOptions[] {
|
||||
function createEquicordMenuItems(): MenuItemConstructorOptions[] {
|
||||
return [
|
||||
{
|
||||
label: "Equicord",
|
||||
|
|
@ -86,28 +101,12 @@ function createVencordMenuItems(): MenuItemConstructorOptions[] {
|
|||
click: () => openAboutWindow()
|
||||
},
|
||||
{
|
||||
label: "Update Equicord",
|
||||
async click(_item, window) {
|
||||
if (!window) return;
|
||||
|
||||
try {
|
||||
const updateAvailable = await updater.fetchUpdate();
|
||||
if (!updateAvailable) {
|
||||
return notify(window, "No Update Available", "You are already using the latest version of Equicord.");
|
||||
}
|
||||
|
||||
const result = await updater.applyUpdate();
|
||||
if (!result) {
|
||||
return notify(window, "Update Failed", "Failed to apply the update for Equicord.");
|
||||
}
|
||||
|
||||
await notify(window, "Update Successful", "Now relaunching Equicord to apply the update.");
|
||||
app.relaunch();
|
||||
app.exit();
|
||||
} catch (e) {
|
||||
notify(window, "Update Error", `An error occurred while updating Equicord.\n\n${String(e)}`);
|
||||
}
|
||||
}
|
||||
label: cachedUpdateAvailable ? "Update Equicord" : "Check for Updates",
|
||||
click: () => sendToRenderer(IpcEvents.TRAY_CHECK_UPDATES)
|
||||
},
|
||||
{
|
||||
label: "Repair Equicord",
|
||||
click: () => sendToRenderer(IpcEvents.TRAY_REPAIR)
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
|
|
@ -120,6 +119,7 @@ function createVencordMenuItems(): MenuItemConstructorOptions[] {
|
|||
}
|
||||
]
|
||||
},
|
||||
{ type: "separator" }
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -130,8 +130,8 @@ export function patchTrayMenu(): void {
|
|||
const alreadyPatched = template.some(item => item.label === "Equicord");
|
||||
if (isTrayMenu(template) && !alreadyPatched) {
|
||||
const insertIndex = findInsertIndex(template);
|
||||
const vencordItems = createVencordMenuItems();
|
||||
template.splice(insertIndex, 0, ...vencordItems);
|
||||
const equicordItems = createEquicordMenuItems();
|
||||
template.splice(insertIndex, 0, ...equicordItems);
|
||||
}
|
||||
|
||||
return originalBuildFromTemplate.call(this, template);
|
||||
|
|
|
|||
|
|
@ -16,11 +16,13 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { IpcEvents } from "@shared/IpcEvents";
|
||||
import { execFile as cpExecFile } from "child_process";
|
||||
import { ipcMain } from "electron";
|
||||
import { join } from "path";
|
||||
import { promisify } from "util";
|
||||
|
||||
import { Updater } from ".";
|
||||
import { serializeErrors } from "./common";
|
||||
|
||||
const VENCORD_SRC_DIR = join(__dirname, "..");
|
||||
const EQUICORD_DIR = join(__dirname, "../../");
|
||||
|
|
@ -83,11 +85,7 @@ async function build() {
|
|||
return !res.stderr.includes("Build failed");
|
||||
}
|
||||
|
||||
const GitUpdater: Updater = {
|
||||
getRepo,
|
||||
listUpdates: calculateGitChanges,
|
||||
fetchUpdate: pull,
|
||||
applyUpdate: build
|
||||
};
|
||||
|
||||
export default GitUpdater;
|
||||
ipcMain.handle(IpcEvents.GET_REPO, serializeErrors(getRepo));
|
||||
ipcMain.handle(IpcEvents.GET_UPDATES, serializeErrors(calculateGitChanges));
|
||||
ipcMain.handle(IpcEvents.UPDATE, serializeErrors(pull));
|
||||
ipcMain.handle(IpcEvents.BUILD, serializeErrors(build));
|
||||
|
|
|
|||
|
|
@ -17,14 +17,15 @@
|
|||
*/
|
||||
|
||||
import { fetchBuffer, fetchJson } from "@main/utils/http";
|
||||
import { IpcEvents } from "@shared/IpcEvents";
|
||||
import { VENCORD_USER_AGENT } from "@shared/vencordUserAgent";
|
||||
import { ipcMain } from "electron";
|
||||
import { writeFileSync } from "original-fs";
|
||||
|
||||
import gitHash from "~git-hash";
|
||||
import gitRemote from "~git-remote";
|
||||
|
||||
import { Updater } from ".";
|
||||
import { ASAR_FILE } from "./common";
|
||||
import { ASAR_FILE, serializeErrors } from "./common";
|
||||
|
||||
const API_BASE = `https://api.github.com/repos/${gitRemote}`;
|
||||
let PendingUpdate: string | null = null;
|
||||
|
|
@ -40,8 +41,8 @@ async function githubGet<T = any>(endpoint: string) {
|
|||
});
|
||||
}
|
||||
|
||||
async function listUpdates() {
|
||||
const isOutdated = await fetchUpdate();
|
||||
async function calculateGitChanges() {
|
||||
const isOutdated = await fetchUpdates();
|
||||
if (!isOutdated) return [];
|
||||
|
||||
const data = await githubGet(`/compare/${gitHash}...HEAD`);
|
||||
|
|
@ -53,7 +54,7 @@ async function listUpdates() {
|
|||
}));
|
||||
}
|
||||
|
||||
async function fetchUpdate() {
|
||||
async function fetchUpdates() {
|
||||
const data = await githubGet("/releases/latest");
|
||||
|
||||
const hash = data.name.slice(data.name.lastIndexOf(" ") + 1);
|
||||
|
|
@ -66,7 +67,7 @@ async function fetchUpdate() {
|
|||
return true;
|
||||
}
|
||||
|
||||
async function applyUpdate() {
|
||||
async function applyUpdates() {
|
||||
if (!PendingUpdate) return true;
|
||||
|
||||
const data = await fetchBuffer(PendingUpdate);
|
||||
|
|
@ -77,11 +78,7 @@ async function applyUpdate() {
|
|||
return true;
|
||||
}
|
||||
|
||||
const HttpUpdater: Updater = {
|
||||
getRepo: async () => `https://github.com/${gitRemote}`,
|
||||
listUpdates,
|
||||
fetchUpdate,
|
||||
applyUpdate
|
||||
};
|
||||
|
||||
export default HttpUpdater;
|
||||
ipcMain.handle(IpcEvents.GET_REPO, serializeErrors(() => `https://github.com/${gitRemote}`));
|
||||
ipcMain.handle(IpcEvents.GET_UPDATES, serializeErrors(calculateGitChanges));
|
||||
ipcMain.handle(IpcEvents.UPDATE, serializeErrors(fetchUpdates));
|
||||
ipcMain.handle(IpcEvents.BUILD, serializeErrors(applyUpdates));
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue