Compare commits
12 commits
4b33625d78
...
7907bf7120
Author | SHA1 | Date | |
---|---|---|---|
7907bf7120 | |||
4deb52028a | |||
f713398070 | |||
056a1b0e1e | |||
66492344a9 | |||
fb940489b0 | |||
|
9d4e859a0a | ||
|
439a4f8eb6 | ||
|
00f82e96bd | ||
|
5216bcca1e | ||
|
e7e298d2e7 | ||
|
d897dab054 |
89 changed files with 402 additions and 252 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "vencord",
|
"name": "vencord",
|
||||||
"private": "true",
|
"private": "true",
|
||||||
"version": "1.10.5",
|
"version": "1.10.6",
|
||||||
"description": "The cutest Discord client mod",
|
"description": "The cutest Discord client mod",
|
||||||
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
"testTsc": "tsc --noEmit"
|
"testTsc": "tsc --noEmit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@intrnl/xxhash64": "^0.1.2",
|
||||||
"@sapphi-red/web-noise-suppressor": "0.3.5",
|
"@sapphi-red/web-noise-suppressor": "0.3.5",
|
||||||
"@vap/core": "0.0.12",
|
"@vap/core": "0.0.12",
|
||||||
"@vap/shiki": "0.10.5",
|
"@vap/shiki": "0.10.5",
|
||||||
|
|
|
@ -16,6 +16,9 @@ importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@intrnl/xxhash64':
|
||||||
|
specifier: ^0.1.2
|
||||||
|
version: 0.1.2
|
||||||
'@sapphi-red/web-noise-suppressor':
|
'@sapphi-red/web-noise-suppressor':
|
||||||
specifier: 0.3.5
|
specifier: 0.3.5
|
||||||
version: 0.3.5
|
version: 0.3.5
|
||||||
|
@ -549,6 +552,9 @@ packages:
|
||||||
resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==}
|
resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==}
|
||||||
engines: {node: '>=18.18'}
|
engines: {node: '>=18.18'}
|
||||||
|
|
||||||
|
'@intrnl/xxhash64@0.1.2':
|
||||||
|
resolution: {integrity: sha512-1+lx7j99fdph+uy3EnjQyr39KQZ7LP56+aWOr6finJWpgYpvb7XrhFUqDwnEk/wpPC98nCjAT6RulpW3crWjlg==}
|
||||||
|
|
||||||
'@jridgewell/gen-mapping@0.3.5':
|
'@jridgewell/gen-mapping@0.3.5':
|
||||||
resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
|
resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
|
@ -2971,6 +2977,8 @@ snapshots:
|
||||||
|
|
||||||
'@humanwhocodes/retry@0.3.0': {}
|
'@humanwhocodes/retry@0.3.0': {}
|
||||||
|
|
||||||
|
'@intrnl/xxhash64@0.1.2': {}
|
||||||
|
|
||||||
'@jridgewell/gen-mapping@0.3.5':
|
'@jridgewell/gen-mapping@0.3.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/set-array': 1.2.1
|
'@jridgewell/set-array': 1.2.1
|
||||||
|
|
|
@ -18,9 +18,8 @@
|
||||||
|
|
||||||
import "./iconStyles.css";
|
import "./iconStyles.css";
|
||||||
|
|
||||||
import { getTheme, Theme } from "@utils/discord";
|
import { getIntlMessage, getTheme, Theme } from "@utils/discord";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { i18n } from "@webpack/common";
|
|
||||||
import type { PropsWithChildren } from "react";
|
import type { PropsWithChildren } from "react";
|
||||||
|
|
||||||
interface BaseIconProps extends IconProps {
|
interface BaseIconProps extends IconProps {
|
||||||
|
@ -133,7 +132,7 @@ export function InfoIcon(props: IconProps) {
|
||||||
export function OwnerCrownIcon(props: IconProps) {
|
export function OwnerCrownIcon(props: IconProps) {
|
||||||
return (
|
return (
|
||||||
<Icon
|
<Icon
|
||||||
aria-label={i18n.Messages.GUILD_OWNER}
|
aria-label={getIntlMessage("GUILD_OWNER")}
|
||||||
{...props}
|
{...props}
|
||||||
className={classes(props.className, "vc-owner-crown-icon")}
|
className={classes(props.className, "vc-owner-crown-icon")}
|
||||||
role="img"
|
role="img"
|
||||||
|
|
|
@ -31,9 +31,7 @@ export async function loadLazyChunks() {
|
||||||
const lazyChunks = factoryCode.matchAll(LazyChunkRegex);
|
const lazyChunks = factoryCode.matchAll(LazyChunkRegex);
|
||||||
const validChunkGroups = new Set<[chunkIds: number[], entryPoint: number]>();
|
const validChunkGroups = new Set<[chunkIds: number[], entryPoint: number]>();
|
||||||
|
|
||||||
// Workaround for a chunk that depends on the ChannelMessage component but may be be force loaded before
|
const shouldForceDefer = false;
|
||||||
// the chunk containing the component
|
|
||||||
const shouldForceDefer = factoryCode.includes(".Messages.GUILD_FEED_UNFEATURE_BUTTON_TEXT");
|
|
||||||
|
|
||||||
await Promise.all(Array.from(lazyChunks).map(async ([, rawChunkIds, entryPoint]) => {
|
await Promise.all(Array.from(lazyChunks).map(async ([, rawChunkIds, entryPoint]) => {
|
||||||
const chunkIds = rawChunkIds ? Array.from(rawChunkIds.matchAll(Webpack.ChunkIdsRegex)).map(m => Number(m[1])) : [];
|
const chunkIds = rawChunkIds ? Array.from(rawChunkIds.matchAll(Webpack.ChunkIdsRegex)).map(m => Number(m[1])) : [];
|
||||||
|
|
|
@ -31,7 +31,7 @@ export default definePlugin({
|
||||||
match: /let\{[^}]*lostPermissionTooltipText:\i[^}]*\}=(\i),/,
|
match: /let\{[^}]*lostPermissionTooltipText:\i[^}]*\}=(\i),/,
|
||||||
replace: "$&vencordProps=$1,"
|
replace: "$&vencordProps=$1,"
|
||||||
}, {
|
}, {
|
||||||
match: /\.Messages\.GUILD_OWNER(?=.+?decorators:(\i)\(\)).+?\1=?\(\)=>.+?children:\[/,
|
match: /#{intl::GUILD_OWNER}(?=.+?decorators:(\i)\(\)).+?\1=?\(\)=>.+?children:\[/,
|
||||||
replace: "$&...(typeof vencordProps=='undefined'?[]:Vencord.Api.MemberListDecorators.__getDecorators(vencordProps)),"
|
replace: "$&...(typeof vencordProps=='undefined'?[]:Vencord.Api.MemberListDecorators.__getDecorators(vencordProps)),"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -25,7 +25,7 @@ export default definePlugin({
|
||||||
authors: [Devs.Cyn],
|
authors: [Devs.Cyn],
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".Messages.REMOVE_ATTACHMENT_BODY",
|
find: "#{intl::REMOVE_ATTACHMENT_BODY}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=.container\)?,children:)(\[.+?\])/,
|
match: /(?<=.container\)?,children:)(\[.+?\])/,
|
||||||
replace: "Vencord.Api.MessageAccessories._modifyAccessories($1,this.props)",
|
replace: "Vencord.Api.MessageAccessories._modifyAccessories($1,this.props)",
|
||||||
|
|
|
@ -27,7 +27,7 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: '"Message Username"',
|
find: '"Message Username"',
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\.Messages\.GUILD_COMMUNICATION_DISABLED_BOTTOM_SHEET_TITLE.+?}\),\i(?=\])/,
|
match: /#{intl::GUILD_COMMUNICATION_DISABLED_BOTTOM_SHEET_TITLE}.+?}\),\i(?=\])/,
|
||||||
replace: "$&,...Vencord.Api.MessageDecorations.__addDecorationsToMessage(arguments[0])"
|
replace: "$&,...Vencord.Api.MessageDecorations.__addDecorationsToMessage(arguments[0])"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ export default definePlugin({
|
||||||
authors: [Devs.Arjix, Devs.hunt, Devs.Ven],
|
authors: [Devs.Arjix, Devs.hunt, Devs.Ven],
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".Messages.EDIT_TEXTAREA_HELP",
|
find: "#{intl::EDIT_TEXTAREA_HELP}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=,channel:\i\}\)\.then\().+?(?=return \i\.content!==this\.props\.message\.content&&\i\((.+?)\))/,
|
match: /(?<=,channel:\i\}\)\.then\().+?(?=return \i\.content!==this\.props\.message\.content&&\i\((.+?)\))/,
|
||||||
replace: (match, args) => "" +
|
replace: (match, args) => "" +
|
||||||
|
|
|
@ -24,9 +24,9 @@ export default definePlugin({
|
||||||
description: "API to add buttons to message popovers.",
|
description: "API to add buttons to message popovers.",
|
||||||
authors: [Devs.KingFish, Devs.Ven, Devs.Nuckyz],
|
authors: [Devs.KingFish, Devs.Ven, Devs.Nuckyz],
|
||||||
patches: [{
|
patches: [{
|
||||||
find: "Messages.MESSAGE_UTILITIES_A11Y_LABEL",
|
find: "#{intl::MESSAGE_UTILITIES_A11Y_LABEL}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\.jsx\)\((\i\.\i),\{label:\i\.\i\.Messages\.MESSAGE_ACTION_REPLY.{0,200}?"reply-self".{0,50}?\}\):null(?=,.+?message:(\i))/,
|
match: /\.jsx\)\((\i\.\i),\{label:\i\.\i\.string\(\i\.\i#{intl::MESSAGE_ACTION_REPLY}.{0,200}?"reply-self".{0,50}?\}\):null(?=,.+?message:(\i))/,
|
||||||
replace: "$&,Vencord.Api.MessagePopover._buildPopoverElements($1,$2)"
|
replace: "$&,Vencord.Api.MessagePopover._buildPopoverElements($1,$2)"
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
|
|
|
@ -25,16 +25,16 @@ export default definePlugin({
|
||||||
description: "Api required for plugins that modify the server list",
|
description: "Api required for plugins that modify the server list",
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "Messages.DISCODO_DISABLED",
|
find: "#{intl::DISCODO_DISABLED}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=Messages\.DISCODO_DISABLED.+?return)(\(.{0,75}?tutorialContainer.+?}\))(?=}function)/,
|
match: /(?<=#{intl::DISCODO_DISABLED}.+?return)(\(.{0,75}?tutorialContainer.+?}\))(?=}function)/,
|
||||||
replace: "[$1].concat(Vencord.Api.ServerList.renderAll(Vencord.Api.ServerList.ServerListRenderPosition.Above))"
|
replace: "[$1].concat(Vencord.Api.ServerList.renderAll(Vencord.Api.ServerList.ServerListRenderPosition.Above))"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: "Messages.SERVERS,children",
|
find: "#{intl::SERVERS}),children",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=Messages\.SERVERS,children:)\i\.map\(\i\)/,
|
match: /(?<=#{intl::SERVERS}\),children:)\i\.map\(\i\)/,
|
||||||
replace: "Vencord.Api.ServerList.renderAll(Vencord.Api.ServerList.ServerListRenderPosition.In).concat($&)"
|
replace: "Vencord.Api.ServerList.renderAll(Vencord.Api.ServerList.ServerListRenderPosition.In).concat($&)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,9 @@ import ThemesTab from "@components/VencordSettings/ThemesTab";
|
||||||
import UpdaterTab from "@components/VencordSettings/UpdaterTab";
|
import UpdaterTab from "@components/VencordSettings/UpdaterTab";
|
||||||
import VencordTab from "@components/VencordSettings/VencordTab";
|
import VencordTab from "@components/VencordSettings/VencordTab";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
|
import { getIntlMessage } from "@utils/discord";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { i18n, React } from "@webpack/common";
|
import { React } from "@webpack/common";
|
||||||
|
|
||||||
import gitHash from "~git-hash";
|
import gitHash from "~git-hash";
|
||||||
|
|
||||||
|
@ -57,7 +58,7 @@ export default definePlugin({
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: "Messages.ACTIVITY_SETTINGS",
|
find: ".SEARCH_NO_RESULTS&&0===",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /(?<=section:(.{0,50})\.DIVIDER\}\))([,;])(?=.{0,200}(\i)\.push.{0,100}label:(\i)\.header)/,
|
match: /(?<=section:(.{0,50})\.DIVIDER\}\))([,;])(?=.{0,200}(\i)\.push.{0,100}label:(\i)\.header)/,
|
||||||
|
@ -70,7 +71,7 @@ export default definePlugin({
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: "Messages.USER_SETTINGS_ACTIONS_MENU_LABEL",
|
find: "#{intl::USER_SETTINGS_ACTIONS_MENU_LABEL}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=function\((\i),\i\)\{)(?=let \i=Object.values\(\i.\i\).*?(\i\.\i)\.open\()/,
|
match: /(?<=function\((\i),\i\)\{)(?=let \i=Object.values\(\i.\i\).*?(\i\.\i)\.open\()/,
|
||||||
replace: "$2.open($1);return;"
|
replace: "$2.open($1);return;"
|
||||||
|
@ -148,13 +149,18 @@ export default definePlugin({
|
||||||
|
|
||||||
if (!header) return;
|
if (!header) return;
|
||||||
|
|
||||||
|
try {
|
||||||
const names = {
|
const names = {
|
||||||
top: i18n.Messages.USER_SETTINGS,
|
top: getIntlMessage("USER_SETTINGS"),
|
||||||
aboveNitro: i18n.Messages.BILLING_SETTINGS,
|
aboveNitro: getIntlMessage("BILLING_SETTINGS"),
|
||||||
belowNitro: i18n.Messages.APP_SETTINGS,
|
belowNitro: getIntlMessage("APP_SETTINGS"),
|
||||||
aboveActivity: i18n.Messages.ACTIVITY_SETTINGS
|
aboveActivity: getIntlMessage("ACTIVITY_SETTINGS")
|
||||||
};
|
};
|
||||||
|
|
||||||
return header === names[settingsLocation];
|
return header === names[settingsLocation];
|
||||||
|
} catch {
|
||||||
|
return firstChild === "PREMIUM";
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
patchedSettings: new WeakSet(),
|
patchedSettings: new WeakSet(),
|
||||||
|
|
|
@ -147,9 +147,9 @@ export default definePlugin({
|
||||||
settings,
|
settings,
|
||||||
|
|
||||||
patches: [{
|
patches: [{
|
||||||
find: ".BEGINNING_DM.format",
|
find: "#{intl::BEGINNING_DM}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /BEGINNING_DM\.format\(\{.+?\}\),(?=.{0,300}(\i)\.isMultiUserDM)/,
|
match: /#{intl::BEGINNING_DM},{.+?}\),(?=.{0,300}(\i)\.isMultiUserDM)/,
|
||||||
replace: "$& $self.renderContributorDmWarningCard({ channel: $1 }),"
|
replace: "$& $self.renderContributorDmWarningCard({ channel: $1 }),"
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
|
|
|
@ -69,7 +69,7 @@ export default definePlugin({
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".Messages.ACCOUNT_SPEAKING_WHILE_MUTED",
|
find: "#{intl::ACCOUNT_SPEAKING_WHILE_MUTED}",
|
||||||
group: true,
|
group: true,
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,7 +41,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Status emojis
|
// Status emojis
|
||||||
find: ".Messages.GUILD_OWNER,",
|
find: "#{intl::GUILD_OWNER}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=\.activityEmoji,.+?animate:)\i/,
|
match: /(?<=\.activityEmoji,.+?animate:)\i/,
|
||||||
replace: "!0"
|
replace: "!0"
|
||||||
|
|
|
@ -86,9 +86,9 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.ATTACHMENT_UTILITIES_SPOILER",
|
find: "#{intl::ATTACHMENT_UTILITIES_SPOILER}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=children:\[)(?=.{10,80}tooltip:.{0,100}\i\.\i\.Messages\.ATTACHMENT_UTILITIES_SPOILER)/,
|
match: /(?<=children:\[)(?=.{10,80}tooltip:.{0,100}#{intl::ATTACHMENT_UTILITIES_SPOILER})/,
|
||||||
replace: "arguments[0].canEdit!==false?$self.renderIcon(arguments[0]):null,"
|
replace: "arguments[0].canEdit!==false?$self.renderIcon(arguments[0]):null,"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -36,7 +36,7 @@ export default definePlugin({
|
||||||
settings,
|
settings,
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "BAN_CONFIRM_TITLE.",
|
find: "#{intl::BAN_CONFIRM_TITLE}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /src:\i\("?\d+"?\)/g,
|
match: /src:\i\("?\d+"?\)/g,
|
||||||
replace: "src:$self.source"
|
replace: "src:$self.source"
|
||||||
|
|
|
@ -18,9 +18,10 @@
|
||||||
|
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
|
import { getIntlMessage } from "@utils/discord";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy, findLazy, findStoreLazy } from "@webpack";
|
import { findByPropsLazy, findLazy, findStoreLazy } from "@webpack";
|
||||||
import { FluxDispatcher, i18n, useMemo } from "@webpack/common";
|
import { FluxDispatcher, useMemo } from "@webpack/common";
|
||||||
|
|
||||||
import FolderSideBar from "./FolderSideBar";
|
import FolderSideBar from "./FolderSideBar";
|
||||||
|
|
||||||
|
@ -172,7 +173,7 @@ export default definePlugin({
|
||||||
// Disable expanding and collapsing folders transition in the normal GuildsBar sidebar
|
// Disable expanding and collapsing folders transition in the normal GuildsBar sidebar
|
||||||
{
|
{
|
||||||
predicate: () => !settings.store.keepIcons,
|
predicate: () => !settings.store.keepIcons,
|
||||||
match: /(?<=\.Messages\.SERVER_FOLDER_PLACEHOLDER.+?useTransition\)\()/,
|
match: /(?<=#{intl::SERVER_FOLDER_PLACEHOLDER}.+?useTransition\)\()/,
|
||||||
replace: "$self.shouldShowTransition(arguments[0])&&"
|
replace: "$self.shouldShowTransition(arguments[0])&&"
|
||||||
},
|
},
|
||||||
// If we are rendering the normal GuildsBar sidebar, we avoid rendering guilds from folders that are expanded
|
// If we are rendering the normal GuildsBar sidebar, we avoid rendering guilds from folders that are expanded
|
||||||
|
@ -205,7 +206,7 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.DISCODO_DISABLED",
|
find: "#{intl::DISCODO_DISABLED}",
|
||||||
predicate: () => settings.store.closeAllHomeButton,
|
predicate: () => settings.store.closeAllHomeButton,
|
||||||
replacement: {
|
replacement: {
|
||||||
// Close all folders when clicking the home button
|
// Close all folders when clicking the home button
|
||||||
|
@ -274,12 +275,16 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
|
|
||||||
makeGuildsBarGuildListFilter(isBetterFolders: boolean) {
|
makeGuildsBarGuildListFilter(isBetterFolders: boolean) {
|
||||||
|
try {
|
||||||
return child => {
|
return child => {
|
||||||
if (isBetterFolders) {
|
if (isBetterFolders) {
|
||||||
return child?.props?.["aria-label"] === i18n.Messages.SERVERS;
|
return child?.props?.["aria-label"] === getIntlMessage("SERVERS");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
} catch {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
makeGuildsBarTreeFilter(isBetterFolders: boolean) {
|
makeGuildsBarTreeFilter(isBetterFolders: boolean) {
|
||||||
|
|
|
@ -34,9 +34,9 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.GIF,",
|
find: "#{intl::GIF}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /alt:(\i)=(\i\.\i\.Messages\.GIF)(?=,[^}]*\}=(\i))/,
|
match: /alt:(\i)=(\i\.\i\.string\(\i\.\i#{intl::GIF}\))(?=,[^}]*\}=(\i))/,
|
||||||
replace:
|
replace:
|
||||||
// rename prop so we can always use default value
|
// rename prop so we can always use default value
|
||||||
"alt_$$:$1=$self.altify($3)||$2",
|
"alt_$$:$1=$self.altify($3)||$2",
|
||||||
|
|
|
@ -63,9 +63,9 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: "Messages.NOTE_PLACEHOLDER",
|
find: "#{intl::NOTE_PLACEHOLDER}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\.NOTE_PLACEHOLDER,/,
|
match: /#{intl::NOTE_PLACEHOLDER}\),/,
|
||||||
replace: "$&spellCheck:!$self.noSpellCheck,"
|
replace: "$&spellCheck:!$self.noSpellCheck,"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
find: ".ADD_ROLE_A11Y_LABEL",
|
find: "#{intl::ADD_ROLE_A11Y_LABEL}",
|
||||||
all: true,
|
all: true,
|
||||||
predicate: () => Settings.plugins.BetterRoleDot.copyRoleColorInProfilePopout && !Settings.plugins.BetterRoleDot.bothStyles,
|
predicate: () => Settings.plugins.BetterRoleDot.copyRoleColorInProfilePopout && !Settings.plugins.BetterRoleDot.bothStyles,
|
||||||
noWarn: true,
|
noWarn: true,
|
||||||
|
|
|
@ -60,7 +60,7 @@ export default definePlugin({
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "Messages.AUTH_SESSIONS_SESSION_LOG_OUT",
|
find: "#{intl::AUTH_SESSIONS_SESSION_LOG_OUT}",
|
||||||
replacement: [
|
replacement: [
|
||||||
// Replace children with a single label with state
|
// Replace children with a single label with state
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,8 +5,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { openPluginModal } from "@components/PluginSettings/PluginModal";
|
import { openPluginModal } from "@components/PluginSettings/PluginModal";
|
||||||
|
import { getIntlMessage } from "@utils/discord";
|
||||||
import { isObjectEmpty } from "@utils/misc";
|
import { isObjectEmpty } from "@utils/misc";
|
||||||
import { Alerts, i18n, Menu, useMemo, useState } from "@webpack/common";
|
import { Alerts, Menu, useMemo, useState } from "@webpack/common";
|
||||||
|
|
||||||
import Plugins from "~plugins";
|
import Plugins from "~plugins";
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ export default function PluginsSubmenu() {
|
||||||
query={query}
|
query={query}
|
||||||
onChange={setQuery}
|
onChange={setQuery}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
placeholder={i18n.Messages.SEARCH}
|
placeholder={getIntlMessage("SEARCH")}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -7,10 +7,11 @@
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { classNameFactory } from "@api/Styles";
|
import { classNameFactory } from "@api/Styles";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
|
import { getIntlMessage } from "@utils/discord";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { waitFor } from "@webpack";
|
import { waitFor } from "@webpack";
|
||||||
import { ComponentDispatch, FocusLock, i18n, Menu, useEffect, useRef } from "@webpack/common";
|
import { ComponentDispatch, FocusLock, Menu, useEffect, useRef } from "@webpack/common";
|
||||||
import type { HTMLAttributes, ReactElement } from "react";
|
import type { HTMLAttributes, ReactElement } from "react";
|
||||||
|
|
||||||
import PluginsSubmenu from "./PluginsSubmenu";
|
import PluginsSubmenu from "./PluginsSubmenu";
|
||||||
|
@ -111,7 +112,7 @@ export default definePlugin({
|
||||||
predicate: () => settings.store.disableFade
|
predicate: () => settings.store.disableFade
|
||||||
},
|
},
|
||||||
{ // Load menu TOC eagerly
|
{ // Load menu TOC eagerly
|
||||||
find: "Messages.USER_SETTINGS_WITH_BUILD_OVERRIDE.format",
|
find: "#{intl::USER_SETTINGS_WITH_BUILD_OVERRIDE}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(\i)\(this,"handleOpenSettingsContextMenu",.{0,100}?null!=\i&&.{0,100}?(await Promise\.all[^};]*?\)\)).*?,(?=\1\(this)/,
|
match: /(\i)\(this,"handleOpenSettingsContextMenu",.{0,100}?null!=\i&&.{0,100}?(await Promise\.all[^};]*?\)\)).*?,(?=\1\(this)/,
|
||||||
replace: "$&(async ()=>$2)(),"
|
replace: "$&(async ()=>$2)(),"
|
||||||
|
@ -119,7 +120,7 @@ export default definePlugin({
|
||||||
predicate: () => settings.store.eagerLoad
|
predicate: () => settings.store.eagerLoad
|
||||||
},
|
},
|
||||||
{ // Settings cog context menu
|
{ // Settings cog context menu
|
||||||
find: "Messages.USER_SETTINGS_ACTIONS_MENU_LABEL",
|
find: "#{intl::USER_SETTINGS_ACTIONS_MENU_LABEL}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /(EXPERIMENTS:.+?)(\(0,\i.\i\)\(\))(?=\.filter\(\i=>\{let\{section:\i\}=)/,
|
match: /(EXPERIMENTS:.+?)(\(0,\i.\i\)\(\))(?=\.filter\(\i=>\{let\{section:\i\}=)/,
|
||||||
|
@ -159,7 +160,7 @@ export default definePlugin({
|
||||||
if (item.section === "HEADER") {
|
if (item.section === "HEADER") {
|
||||||
items.push({ label: item.label, items: [] });
|
items.push({ label: item.label, items: [] });
|
||||||
} else if (item.section === "DIVIDER") {
|
} else if (item.section === "DIVIDER") {
|
||||||
items.push({ label: i18n.Messages.OTHER_OPTIONS, items: [] });
|
items.push({ label: getIntlMessage("OTHER_OPTIONS"), items: [] });
|
||||||
} else {
|
} else {
|
||||||
items.at(-1)!.items.push(item);
|
items.at(-1)!.items.push(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import definePlugin, { OptionType, StartAt } from "@utils/types";
|
||||||
import { findByCodeLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
|
import { findByCodeLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
|
||||||
import { Button, Forms, ThemeStore, useStateFromStores } from "@webpack/common";
|
import { Button, Forms, ThemeStore, useStateFromStores } from "@webpack/common";
|
||||||
|
|
||||||
const ColorPicker = findComponentByCodeLazy(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
|
const ColorPicker = findComponentByCodeLazy("#{intl::USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR}", ".BACKGROUND_PRIMARY)");
|
||||||
|
|
||||||
const colorPresets = [
|
const colorPresets = [
|
||||||
"#1E1514", "#172019", "#13171B", "#1C1C28", "#402D2D",
|
"#1E1514", "#172019", "#13171B", "#1C1C28", "#402D2D",
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { getCurrentChannel, getCurrentGuild } from "@utils/discord";
|
import { getCurrentChannel, getCurrentGuild } from "@utils/discord";
|
||||||
|
import { runtimeHashMessageKey } from "@utils/intlHash";
|
||||||
import { SYM_LAZY_CACHED, SYM_LAZY_GET } from "@utils/lazy";
|
import { SYM_LAZY_CACHED, SYM_LAZY_GET } from "@utils/lazy";
|
||||||
import { relaunch } from "@utils/native";
|
import { relaunch } from "@utils/native";
|
||||||
import { canonicalizeMatch, canonicalizeReplace, canonicalizeReplacement } from "@utils/patches";
|
import { canonicalizeMatch, canonicalizeReplace, canonicalizeReplacement } from "@utils/patches";
|
||||||
|
@ -104,6 +105,7 @@ function makeShortcuts() {
|
||||||
canonicalizeMatch,
|
canonicalizeMatch,
|
||||||
canonicalizeReplace,
|
canonicalizeReplace,
|
||||||
canonicalizeReplacement,
|
canonicalizeReplacement,
|
||||||
|
runtimeHashMessageKey,
|
||||||
fakeRender: (component: ComponentType, props: any) => {
|
fakeRender: (component: ComponentType, props: any) => {
|
||||||
const prevWin = fakeRenderWin?.deref();
|
const prevWin = fakeRenderWin?.deref();
|
||||||
const win = prevWin?.closed === false
|
const win = prevWin?.closed === false
|
||||||
|
|
|
@ -25,7 +25,7 @@ export default definePlugin({
|
||||||
authors: [Devs.Obsidian, Devs.Nuckyz],
|
authors: [Devs.Obsidian, Devs.Nuckyz],
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".Messages.PREVIEW_BYTES_LEFT.format(",
|
find: "#{intl::PREVIEW_BYTES_LEFT}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\.footerGap.+?url:\i,fileName:\i,fileSize:\i}\),(?<=fileContents:(\i),bytesLeft:(\i).+?)/g,
|
match: /\.footerGap.+?url:\i,fileName:\i,fileSize:\i}\),(?<=fileContents:(\i),bytesLeft:(\i).+?)/g,
|
||||||
replace: "$&$self.addCopyButton({fileContents:$1,bytesLeft:$2}),"
|
replace: "$&$self.addCopyButton({fileContents:$1,bytesLeft:$2}),"
|
||||||
|
|
|
@ -67,7 +67,7 @@ export default definePlugin({
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".Messages.ERRORS_UNEXPECTED_CRASH",
|
find: "#{intl::ERRORS_UNEXPECTED_CRASH}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /this\.setState\((.+?)\)/,
|
match: /this\.setState\((.+?)\)/,
|
||||||
replace: "$self.handleCrash(this,$1);"
|
replace: "$self.handleCrash(this,$1);"
|
||||||
|
|
|
@ -41,7 +41,7 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: "DefaultCustomizationSections",
|
find: "DefaultCustomizationSections",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=USER_SETTINGS_AVATAR_DECORATION},"decoration"\),)/,
|
match: /(?<=#{intl::USER_SETTINGS_AVATAR_DECORATION}\)},"decoration"\),)/,
|
||||||
replace: "$self.DecorSection(),"
|
replace: "$self.DecorSection(),"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { PlusIcon } from "@components/Icons";
|
import { PlusIcon } from "@components/Icons";
|
||||||
import { i18n, Text } from "@webpack/common";
|
import { getIntlMessage } from "@utils/discord";
|
||||||
|
import { Text } from "@webpack/common";
|
||||||
import { HTMLProps } from "react";
|
import { HTMLProps } from "react";
|
||||||
|
|
||||||
import { DecorationGridItem } from ".";
|
import { DecorationGridItem } from ".";
|
||||||
|
@ -24,7 +25,7 @@ export default function DecorationGridCreate(props: DecorationGridCreateProps) {
|
||||||
variant="text-xs/normal"
|
variant="text-xs/normal"
|
||||||
color="header-primary"
|
color="header-primary"
|
||||||
>
|
>
|
||||||
{i18n.Messages.CREATE}
|
{getIntlMessage("CREATE")}
|
||||||
</Text>
|
</Text>
|
||||||
</DecorationGridItem >;
|
</DecorationGridItem >;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { NoEntrySignIcon } from "@components/Icons";
|
import { NoEntrySignIcon } from "@components/Icons";
|
||||||
import { i18n, Text } from "@webpack/common";
|
import { getIntlMessage } from "@utils/discord";
|
||||||
|
import { Text } from "@webpack/common";
|
||||||
import { HTMLProps } from "react";
|
import { HTMLProps } from "react";
|
||||||
|
|
||||||
import { DecorationGridItem } from ".";
|
import { DecorationGridItem } from ".";
|
||||||
|
@ -24,7 +25,7 @@ export default function DecorationGridNone(props: DecorationGridNoneProps) {
|
||||||
variant="text-xs/normal"
|
variant="text-xs/normal"
|
||||||
color="header-primary"
|
color="header-primary"
|
||||||
>
|
>
|
||||||
{i18n.Messages.NONE}
|
{getIntlMessage("NONE")}
|
||||||
</Text>
|
</Text>
|
||||||
</DecorationGridItem >;
|
</DecorationGridItem >;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ export default definePlugin({
|
||||||
authors: [Devs.Nuckyz],
|
authors: [Devs.Nuckyz],
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".Messages.BOT_CALL_IDLE_DISCONNECT",
|
find: "#{intl::BOT_CALL_IDLE_DISCONNECT_2}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /,?(?=\i\(this,"idleTimeout",new \i\.\i\))/,
|
match: /,?(?=\i\(this,"idleTimeout",new \i\.\i\))/,
|
||||||
replace: ";return;"
|
replace: ";return;"
|
||||||
|
|
|
@ -285,7 +285,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
// Remove boost requirements to stream with high quality
|
// Remove boost requirements to stream with high quality
|
||||||
{
|
{
|
||||||
find: "STREAM_FPS_OPTION.format",
|
find: "#{intl::STREAM_FPS_OPTION}",
|
||||||
predicate: () => settings.store.enableStreamQualityBypass,
|
predicate: () => settings.store.enableStreamQualityBypass,
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /guildPremiumTier:\i\.\i\.TIER_\d,?/g,
|
match: /guildPremiumTier:\i\.\i\.TIER_\d,?/g,
|
||||||
|
@ -356,7 +356,7 @@ export default definePlugin({
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.STICKER_POPOUT_UNJOINED_PRIVATE_GUILD_DESCRIPTION.format",
|
find: "#{intl::STICKER_POPOUT_UNJOINED_PRIVATE_GUILD_DESCRIPTION}",
|
||||||
predicate: () => settings.store.transformStickers,
|
predicate: () => settings.store.transformStickers,
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
|
@ -381,7 +381,7 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.EMOJI_POPOUT_UNJOINED_DISCOVERABLE_GUILD_DESCRIPTION",
|
find: "#{intl::EMOJI_POPOUT_UNJOINED_DISCOVERABLE_GUILD_DESCRIPTION}",
|
||||||
predicate: () => settings.store.transformEmojis,
|
predicate: () => settings.store.transformEmojis,
|
||||||
replacement: {
|
replacement: {
|
||||||
// Add the fake nitro emoji notice
|
// Add the fake nitro emoji notice
|
||||||
|
|
|
@ -108,10 +108,10 @@ interface ProfileModalProps {
|
||||||
isTryItOutFlow: boolean;
|
isTryItOutFlow: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ColorPicker = findComponentByCodeLazy<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
|
const ColorPicker = findComponentByCodeLazy<ColorPickerProps>("#{intl::USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR}", ".BACKGROUND_PRIMARY)");
|
||||||
const ProfileModal = findComponentByCodeLazy<ProfileModalProps>("isTryItOutFlow:", "pendingThemeColors:", "pendingAvatarDecoration:", "EDIT_PROFILE_BANNER");
|
const ProfileModal = findComponentByCodeLazy<ProfileModalProps>("isTryItOutFlow:", "pendingThemeColors:", "pendingAvatarDecoration:", "EDIT_PROFILE_BANNER");
|
||||||
|
|
||||||
const requireColorPicker = extractAndLoadChunksLazy(["USER_SETTINGS_PROFILE_COLOR_DEFAULT_BUTTON.format"], /createPromise:\(\)=>\i\.\i(\("?.+?"?\)).then\(\i\.bind\(\i,"?(.+?)"?\)\)/);
|
const requireColorPicker = extractAndLoadChunksLazy(["#{intl::USER_SETTINGS_PROFILE_COLOR_DEFAULT_BUTTON}"], /createPromise:\(\)=>\i\.\i(\("?.+?"?\)).then\(\i\.bind\(\i,"?(.+?)"?\)\)/);
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "FakeProfileThemes",
|
name: "FakeProfileThemes",
|
||||||
|
@ -126,9 +126,9 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".USER_SETTINGS_RESET_PROFILE_THEME",
|
find: "#{intl::USER_SETTINGS_RESET_PROFILE_THEME}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /RESET_PROFILE_THEME}\)(?<=color:(\i),.{0,500}?color:(\i),.{0,500}?)/,
|
match: /#{intl::USER_SETTINGS_RESET_PROFILE_THEME}\)}\)(?<=color:(\i),.{0,500}?color:(\i),.{0,500}?)/,
|
||||||
replace: "$&,$self.addCopy3y3Button({primary:$1,accent:$2})"
|
replace: "$&,$self.addCopy3y3Button({primary:$1,accent:$2})"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ export default definePlugin({
|
||||||
authors: [Devs.D3SOX, Devs.Nickyux],
|
authors: [Devs.D3SOX, Devs.Nickyux],
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".Messages.GUILD_OWNER,",
|
find: "#{intl::GUILD_OWNER}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /,isOwner:(\i),/,
|
match: /,isOwner:(\i),/,
|
||||||
replace: ",_isOwner:$1=$self.isGuildOwner(e),"
|
replace: ",_isOwner:$1=$self.isGuildOwner(e),"
|
||||||
|
|
|
@ -26,7 +26,7 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: ".PANEL}),nicknameIcons",
|
find: ".PANEL}),nicknameIcons",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /USER_PROFILE_MEMBER_SINCE,.{0,100}userId:(\i\.id)}\)}\)/,
|
match: /#{intl::USER_PROFILE_MEMBER_SINCE}\),.{0,100}userId:(\i\.id)}\)}\)/,
|
||||||
replace: "$&,$self.FriendsSinceComponent({userId:$1,isSidebar:true})"
|
replace: "$&,$self.FriendsSinceComponent({userId:$1,isSidebar:true})"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -34,7 +34,7 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: "action:\"PRESS_APP_CONNECTION\"",
|
find: "action:\"PRESS_APP_CONNECTION\"",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /USER_PROFILE_MEMBER_SINCE,.{0,100}userId:(\i\.id),.{0,100}}\)}\),/,
|
match: /#{intl::USER_PROFILE_MEMBER_SINCE}\),.{0,100}userId:(\i\.id),.{0,100}}\)}\),/,
|
||||||
replace: "$&,$self.FriendsSinceComponent({userId:$1,isSidebar:false}),"
|
replace: "$&,$self.FriendsSinceComponent({userId:$1,isSidebar:false}),"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,11 @@
|
||||||
import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";
|
import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||||
import { migratePluginSettings } from "@api/Settings";
|
import { migratePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
|
import { getIntlMessage } from "@utils/discord";
|
||||||
import { NoopComponent } from "@utils/react";
|
import { NoopComponent } from "@utils/react";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { filters, findByPropsLazy, waitFor } from "@webpack";
|
import { filters, findByPropsLazy, waitFor } from "@webpack";
|
||||||
import { ChannelStore, ContextMenuApi, i18n, UserStore } from "@webpack/common";
|
import { ChannelStore, ContextMenuApi, UserStore } from "@webpack/common";
|
||||||
import { Message } from "discord-types/general";
|
import { Message } from "discord-types/general";
|
||||||
|
|
||||||
const { useMessageMenu } = findByPropsLazy("useMessageMenu");
|
const { useMessageMenu } = findByPropsLazy("useMessageMenu");
|
||||||
|
@ -41,7 +42,7 @@ function MessageMenu({ message, channel, onHeightUpdate }) {
|
||||||
|
|
||||||
return useMessageMenu({
|
return useMessageMenu({
|
||||||
navId: "message-actions",
|
navId: "message-actions",
|
||||||
ariaLabel: i18n.Messages.MESSAGE_UTILITIES_A11Y_LABEL,
|
ariaLabel: getIntlMessage("MESSAGE_UTILITIES_A11Y_LABEL"),
|
||||||
|
|
||||||
message,
|
message,
|
||||||
channel,
|
channel,
|
||||||
|
@ -72,7 +73,7 @@ const contextMenuPatch: NavContextMenuPatchCallback = (children, props: MessageA
|
||||||
|
|
||||||
const group = findGroupChildrenByChildId("devmode-copy-id", children, true);
|
const group = findGroupChildrenByChildId("devmode-copy-id", children, true);
|
||||||
group?.push(
|
group?.push(
|
||||||
CopyIdMenuItem({ id: props.message.author.id, label: i18n.Messages.COPY_ID_AUTHOR })
|
CopyIdMenuItem({ id: props.message.author.id, label: getIntlMessage("COPY_ID_AUTHOR") })
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ export default definePlugin({
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".Messages.ACCOUNT_SPEAKING_WHILE_MUTED",
|
find: "#{intl::ACCOUNT_SPEAKING_WHILE_MUTED}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /this\.renderNameZone\(\).+?children:\[/,
|
match: /this\.renderNameZone\(\).+?children:\[/,
|
||||||
replace: "$&$self.GameActivityToggleButton(),"
|
replace: "$&$self.GameActivityToggleButton(),"
|
||||||
|
|
|
@ -166,7 +166,7 @@ export default definePlugin({
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "Messages.WELCOME_CTA_LABEL",
|
find: "#{intl::WELCOME_CTA_LABEL}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /innerClassName:\i\.welcomeCTAButton,(?<={channel:\i,message:\i}=(\i).{0,400}?)/,
|
match: /innerClassName:\i\.welcomeCTAButton,(?<={channel:\i,message:\i}=(\i).{0,400}?)/,
|
||||||
replace: "$&onContextMenu:(vcEvent)=>$self.pickSticker(vcEvent, $1),"
|
replace: "$&onContextMenu:(vcEvent)=>$self.pickSticker(vcEvent, $1),"
|
||||||
|
|
|
@ -260,9 +260,9 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.SETTINGS_GAMES_TOGGLE_OVERLAY",
|
find: "#{intl::SETTINGS_GAMES_TOGGLE_OVERLAY}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\.Messages\.SETTINGS_GAMES_TOGGLE_OVERLAY.+?}\(\),(?<={overlay:\i,.+?=(\i),.+?)(?=!(\i))/,
|
match: /#{intl::SETTINGS_GAMES_TOGGLE_OVERLAY}.+?}\(\),(?<={overlay:\i,.+?=(\i),.+?)(?=!(\i))/,
|
||||||
replace: (m, props, nowPlaying) => `${m}$self.renderToggleGameActivityButton(${props},${nowPlaying}),`
|
replace: (m, props, nowPlaying) => `${m}$self.renderToggleGameActivityButton(${props},${nowPlaying}),`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -32,7 +32,7 @@ export default definePlugin({
|
||||||
patches: [
|
patches: [
|
||||||
// Counts header
|
// Counts header
|
||||||
{
|
{
|
||||||
find: ".FRIENDS_ALL_HEADER",
|
find: "#{intl::FRIENDS_ALL_HEADER}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /toString\(\)\}\);case (\i\.\i)\.BLOCKED/,
|
match: /toString\(\)\}\);case (\i\.\i)\.BLOCKED/,
|
||||||
replace: 'toString()});case $1.IMPLICIT:return "Implicit — "+arguments[1];case $1.BLOCKED'
|
replace: 'toString()});case $1.IMPLICIT:return "Implicit — "+arguments[1];case $1.BLOCKED'
|
||||||
|
@ -48,9 +48,9 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
// Sections header
|
// Sections header
|
||||||
{
|
{
|
||||||
find: ".FRIENDS_SECTION_ONLINE",
|
find: "#{intl::FRIENDS_SECTION_ONLINE}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(\(0,\i\.jsx\)\(\i\.TabBar\.Item,\{id:\i\.\i)\.BLOCKED,className:([^\s]+?)\.item,children:\i\.\i\.Messages\.BLOCKED\}\)/,
|
match: /(\(0,\i\.jsx\)\(\i\.TabBar\.Item,\{id:\i\.\i)\.BLOCKED,className:([^\s]+?)\.item,children:\i\.\i\.string\(\i\.\i#{intl::BLOCKED}\)\}\)/,
|
||||||
replace: "$1.IMPLICIT,className:$2.item,children:\"Implicit\"}),$&"
|
replace: "$1.IMPLICIT,className:$2.item,children:\"Implicit\"}),$&"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -117,7 +117,7 @@ export default definePlugin({
|
||||||
|
|
||||||
wrapSort(comparator: Function, row: any) {
|
wrapSort(comparator: Function, row: any) {
|
||||||
return row.type === 5
|
return row.type === 5
|
||||||
? -UserAffinitiesStore.getUserAffinity(row.user.id)?.affinity ?? 0
|
? -(UserAffinitiesStore.getUserAffinity(row.user.id)?.affinity ?? 0)
|
||||||
: comparator(row);
|
: comparator(row);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ export default definePlugin({
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
// Indicator
|
// Indicator
|
||||||
find: ".Messages.MESSAGE_EDITED,",
|
find: "#{intl::MESSAGE_EDITED}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /let\{className:\i,message:\i[^}]*\}=(\i)/,
|
match: /let\{className:\i,message:\i[^}]*\}=(\i)/,
|
||||||
replace: "try {$1 && $self.INV_REGEX.test($1.message.content) ? $1.content.push($self.indicator()) : null } catch {};$&"
|
replace: "try {$1 && $self.INV_REGEX.test($1.message.content) ? $1.content.push($self.indicator()) : null } catch {};$&"
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
import * as DataStore from "@api/DataStore";
|
import * as DataStore from "@api/DataStore";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { ChannelRouter, SelectedChannelStore, SelectedGuildStore } from "@webpack/common";
|
import { ChannelRouter, ChannelStore, NavigationRouter, SelectedChannelStore, SelectedGuildStore } from "@webpack/common";
|
||||||
|
|
||||||
export interface LogoutEvent {
|
export interface LogoutEvent {
|
||||||
type: "LOGOUT";
|
type: "LOGOUT";
|
||||||
|
@ -45,6 +45,16 @@ export default definePlugin({
|
||||||
description: "Attempt to navigate to the channel you were in before switching accounts or loading Discord.",
|
description: "Attempt to navigate to the channel you were in before switching accounts or loading Discord.",
|
||||||
authors: [Devs.Nuckyz],
|
authors: [Devs.Nuckyz],
|
||||||
|
|
||||||
|
patches: [
|
||||||
|
{
|
||||||
|
find: '"Switching accounts"',
|
||||||
|
replacement: {
|
||||||
|
match: /goHomeAfterSwitching:\i/,
|
||||||
|
replace: "goHomeAfterSwitching:!1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
flux: {
|
flux: {
|
||||||
LOGOUT(e: LogoutEvent) {
|
LOGOUT(e: LogoutEvent) {
|
||||||
({ isSwitchingAccount } = e);
|
({ isSwitchingAccount } = e);
|
||||||
|
@ -55,7 +65,11 @@ export default definePlugin({
|
||||||
isSwitchingAccount = false;
|
isSwitchingAccount = false;
|
||||||
|
|
||||||
if (previousCache?.channelId) {
|
if (previousCache?.channelId) {
|
||||||
|
if (ChannelStore.hasChannel(previousCache.channelId)) {
|
||||||
ChannelRouter.transitionToChannel(previousCache.channelId);
|
ChannelRouter.transitionToChannel(previousCache.channelId);
|
||||||
|
} else {
|
||||||
|
NavigationRouter.transitionToGuild("@me");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ export default definePlugin({
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".LOADING_DID_YOU_KNOW",
|
find: "#{intl::LOADING_DID_YOU_KNOW}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /"_loadingText".+?(?=(\i)\[.{0,10}\.random)/,
|
match: /"_loadingText".+?(?=(\i)\[.{0,10}\.random)/,
|
||||||
|
|
|
@ -74,7 +74,7 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: ".invitesDisabledTooltip",
|
find: ".invitesDisabledTooltip",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\.VIEW_AS_ROLES_MENTIONS_WARNING.{0,100}(?=])/,
|
match: /#{intl::VIEW_AS_ROLES_MENTIONS_WARNING}.{0,100}(?=])/,
|
||||||
replace: "$&,$self.renderTooltip(arguments[0].guild)"
|
replace: "$&,$self.renderTooltip(arguments[0].guild)"
|
||||||
},
|
},
|
||||||
predicate: () => settings.store.toolTip
|
predicate: () => settings.store.toolTip
|
||||||
|
|
|
@ -24,12 +24,12 @@ import { Settings } from "@api/Settings";
|
||||||
import { disableStyle, enableStyle } from "@api/Styles";
|
import { disableStyle, enableStyle } from "@api/Styles";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { proxyLazy } from "@utils/lazy";
|
import { getIntlMessage } from "@utils/discord";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByCodeLazy, findByPropsLazy } from "@webpack";
|
import { findByCodeLazy, findByPropsLazy } from "@webpack";
|
||||||
import { ChannelStore, FluxDispatcher, i18n, Menu, MessageStore, Parser, SelectedChannelStore, Timestamp, UserStore, useStateFromStores } from "@webpack/common";
|
import { ChannelStore, FluxDispatcher, Menu, MessageStore, Parser, SelectedChannelStore, Timestamp, UserStore, useStateFromStores } from "@webpack/common";
|
||||||
import { Message } from "discord-types/general";
|
import { Message } from "discord-types/general";
|
||||||
|
|
||||||
import overlayStyle from "./deleteStyleOverlay.css?managed";
|
import overlayStyle from "./deleteStyleOverlay.css?managed";
|
||||||
|
@ -178,7 +178,7 @@ export default definePlugin({
|
||||||
isEdited={true}
|
isEdited={true}
|
||||||
isInline={false}
|
isInline={false}
|
||||||
>
|
>
|
||||||
<span className={styles.edited}>{" "}({i18n.Messages.MESSAGE_EDITED})</span>
|
<span className={styles.edited}>{" "}({getIntlMessage("MESSAGE_EDITED")})</span>
|
||||||
</Timestamp>
|
</Timestamp>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
@ -312,9 +312,35 @@ export default definePlugin({
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
Messages: proxyLazy(() => ({
|
Messages: {
|
||||||
DELETED_MESSAGE_COUNT: getMessage("{count, plural, =0 {No deleted messages} one {{count} deleted message} other {{count} deleted messages}}")
|
// DELETED_MESSAGE_COUNT: getMessage("{count, plural, =0 {No deleted messages} one {{count} deleted message} other {{count} deleted messages}}")
|
||||||
})),
|
// TODO: find a better way to generate intl messages
|
||||||
|
DELETED_MESSAGE_COUNT: () => ({
|
||||||
|
ast: [[
|
||||||
|
6,
|
||||||
|
"count",
|
||||||
|
{
|
||||||
|
"=0": ["No deleted messages"],
|
||||||
|
one: [
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
"count"
|
||||||
|
],
|
||||||
|
" deleted message"
|
||||||
|
],
|
||||||
|
other: [
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
"count"
|
||||||
|
],
|
||||||
|
" deleted messages"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
"cardinal"
|
||||||
|
]]
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
|
@ -445,7 +471,7 @@ export default definePlugin({
|
||||||
|
|
||||||
{
|
{
|
||||||
// Message content renderer
|
// Message content renderer
|
||||||
find: "Messages.MESSAGE_EDITED,\")\"",
|
find: "#{intl::MESSAGE_EDITED}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
// Render editHistory in the deepest div for message content
|
// Render editHistory in the deepest div for message content
|
||||||
|
@ -497,7 +523,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Message group rendering
|
// Message group rendering
|
||||||
find: "Messages.NEW_MESSAGES_ESTIMATED_WITH_DATE",
|
find: "#{intl::NEW_MESSAGES_ESTIMATED_WITH_DATE}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /(\i).type===\i\.\i\.MESSAGE_GROUP_BLOCKED\|\|/,
|
match: /(\i).type===\i\.\i\.MESSAGE_GROUP_BLOCKED\|\|/,
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Flex } from "@components/Flex";
|
import { Flex } from "@components/Flex";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
|
import { getIntlMessage } from "@utils/discord";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByCodeLazy, findLazy } from "@webpack";
|
import { findByCodeLazy, findLazy } from "@webpack";
|
||||||
|
@ -187,13 +188,13 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".DISCORD_SYSTEM_MESSAGE_BOT_TAG_TOOLTIP_OFFICIAL,",
|
find: "#{intl::DISCORD_SYSTEM_MESSAGE_BOT_TAG_TOOLTIP_OFFICIAL}",
|
||||||
replacement: [
|
replacement: [
|
||||||
// make the tag show the right text
|
// make the tag show the right text
|
||||||
{
|
{
|
||||||
match: /(switch\((\i)\){.+?)case (\i(?:\.\i)?)\.BOT:default:(\i)=.{0,40}(\i\.\i\.Messages)\.APP_TAG/,
|
match: /(switch\((\i)\){.+?)case (\i(?:\.\i)?)\.BOT:default:(\i)=(.{0,40}#{intl::APP_TAG}\))/,
|
||||||
replace: (_, origSwitch, variant, tags, displayedText, strings) =>
|
replace: (_, origSwitch, variant, tags, displayedText, originalText) =>
|
||||||
`${origSwitch}default:{${displayedText} = $self.getTagText(${tags}[${variant}], ${strings})}`
|
`${origSwitch}default:{${displayedText} = $self.getTagText(${tags}[${variant}],${originalText})}`
|
||||||
},
|
},
|
||||||
// show OP tags correctly
|
// show OP tags correctly
|
||||||
{
|
{
|
||||||
|
@ -217,7 +218,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
// in the member list
|
// in the member list
|
||||||
{
|
{
|
||||||
find: ".Messages.GUILD_OWNER,",
|
find: "#{intl::GUILD_OWNER}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<type>\i)=\(null==.{0,100}\.BOT;return null!=(?<user>\i)&&\i\.bot/,
|
match: /(?<type>\i)=\(null==.{0,100}\.BOT;return null!=(?<user>\i)&&\i\.bot/,
|
||||||
replace: "$<type> = $self.getTag({user: $<user>, channel: arguments[0].channel, origType: $<user>.bot ? 0 : null, location: 'not-chat' }); return typeof $<type> === 'number'"
|
replace: "$<type> = $self.getTag({user: $<user>, channel: arguments[0].channel, origType: $<user>.bot ? 0 : null, location: 'not-chat' }); return typeof $<type> === 'number'"
|
||||||
|
@ -232,7 +233,7 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.USER_PROFILE_PRONOUNS",
|
find: "#{intl::USER_PROFILE_PRONOUNS}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?=,hideBotTag:!0)/,
|
match: /(?=,hideBotTag:!0)/,
|
||||||
replace: ",moreTags_channelId:arguments[0].moreTags_channelId"
|
replace: ",moreTags_channelId:arguments[0].moreTags_channelId"
|
||||||
|
@ -295,22 +296,26 @@ export default definePlugin({
|
||||||
|
|
||||||
isOPTag: (tag: number) => tag === Tag.Types.ORIGINAL_POSTER || tags.some(t => tag === Tag.Types[`${t.name}-OP`]),
|
isOPTag: (tag: number) => tag === Tag.Types.ORIGINAL_POSTER || tags.some(t => tag === Tag.Types[`${t.name}-OP`]),
|
||||||
|
|
||||||
getTagText(passedTagName: string, strings: Record<string, string>) {
|
getTagText(passedTagName: string, originalText: string) {
|
||||||
if (!passedTagName) return strings.APP_TAG;
|
try {
|
||||||
const [tagName, variant] = passedTagName.split("-");
|
const [tagName, variant] = passedTagName.split("-");
|
||||||
|
if (!passedTagName) return getIntlMessage("APP_TAG");
|
||||||
const tag = tags.find(({ name }) => tagName === name);
|
const tag = tags.find(({ name }) => tagName === name);
|
||||||
if (!tag) return strings.APP_TAG;
|
if (!tag) return getIntlMessage("APP_TAG");
|
||||||
if (variant === "BOT" && tagName !== "WEBHOOK" && this.settings.store.dontShowForBots) return strings.APP_TAG;
|
if (variant === "BOT" && tagName !== "WEBHOOK" && this.settings.store.dontShowForBots) return getIntlMessage("APP_TAG");
|
||||||
|
|
||||||
const tagText = settings.store.tagSettings?.[tag.name]?.text || tag.displayName;
|
const tagText = settings.store.tagSettings?.[tag.name]?.text || tag.displayName;
|
||||||
switch (variant) {
|
switch (variant) {
|
||||||
case "OP":
|
case "OP":
|
||||||
return `${strings.BOT_TAG_FORUM_ORIGINAL_POSTER} • ${tagText}`;
|
return `${getIntlMessage("BOT_TAG_FORUM_ORIGINAL_POSTER")} • ${tagText}`;
|
||||||
case "BOT":
|
case "BOT":
|
||||||
return `${strings.APP_TAG} • ${tagText}`;
|
return `${getIntlMessage("APP_TAG")} • ${tagText}`;
|
||||||
default:
|
default:
|
||||||
return tagText;
|
return tagText;
|
||||||
}
|
}
|
||||||
|
} catch {
|
||||||
|
return originalText;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getTag({
|
getTag({
|
||||||
|
|
|
@ -18,17 +18,18 @@
|
||||||
|
|
||||||
import { Settings } from "@api/Settings";
|
import { Settings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
|
import { runtimeHashMessageKey } from "@utils/intlHash";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByPropsLazy } from "@webpack";
|
||||||
|
import { i18n } from "@webpack/common";
|
||||||
import { Message } from "discord-types/general";
|
import { Message } from "discord-types/general";
|
||||||
|
|
||||||
const RelationshipStore = findByPropsLazy("getRelationships", "isBlocked");
|
const RelationshipStore = findByPropsLazy("getRelationships", "isBlocked");
|
||||||
|
|
||||||
interface MessageDeleteProps {
|
interface MessageDeleteProps {
|
||||||
collapsedReason: {
|
// i18n message i18n.t["+FcYMz"] if deleted, with args
|
||||||
message: string;
|
collapsedReason: () => any
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
|
@ -37,7 +38,7 @@ export default definePlugin({
|
||||||
authors: [Devs.rushii, Devs.Samu],
|
authors: [Devs.rushii, Devs.Samu],
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "Messages.BLOCKED_MESSAGES_HIDE",
|
find: "#{intl::BLOCKED_MESSAGES_HIDE}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /let\{[^}]*collapsedReason[^}]*\}/,
|
match: /let\{[^}]*collapsedReason[^}]*\}/,
|
||||||
|
@ -77,6 +78,11 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
|
|
||||||
shouldHide(props: MessageDeleteProps) {
|
shouldHide(props: MessageDeleteProps) {
|
||||||
return !props?.collapsedReason?.message.includes("deleted");
|
try {
|
||||||
|
return props.collapsedReason() === i18n.t[runtimeHashMessageKey("BLOCKED_MESSAGE_COUNT")]();
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -25,7 +25,7 @@ export default definePlugin({
|
||||||
authors: [Devs.nekohaxx],
|
authors: [Devs.nekohaxx],
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "Messages.ONBOARDING_COVER_WELCOME_SUBTITLE",
|
find: "#{intl::ONBOARDING_COVER_WELCOME_SUBTITLE}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: "3e3",
|
match: "3e3",
|
||||||
replace: "0"
|
replace: "0"
|
||||||
|
|
|
@ -28,21 +28,21 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: '.id,"Search Results"',
|
find: '.id,"Search Results"',
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /if\(.{1,10}\)(.{1,10}\.show\({.{1,50}UNBLOCK_TO_JUMP_TITLE)/,
|
match: /if\(.{1,10}\)(.{1,10}\.show\({.{1,50}#{intl::UNBLOCK_TO_JUMP_TITLE})/,
|
||||||
replace: "if(false)$1"
|
replace: "if(false)$1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: "renderJumpButton()",
|
find: "renderJumpButton()",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /if\(.{1,10}\)(.{1,10}\.show\({.{1,50}UNBLOCK_TO_JUMP_TITLE)/,
|
match: /if\(.{1,10}\)(.{1,10}\.show\({.{1,50}#{intl::UNBLOCK_TO_JUMP_TITLE})/,
|
||||||
replace: "if(false)$1"
|
replace: "if(false)$1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: "flash:!0,returnMessageId",
|
find: "flash:!0,returnMessageId",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /.\?(.{1,10}\.show\({.{1,50}UNBLOCK_TO_JUMP_TITLE)/,
|
match: /.\?(.{1,10}\.show\({.{1,50}#{intl::UNBLOCK_TO_JUMP_TITLE})/,
|
||||||
replace: "false?$1"
|
replace: "false?$1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ export default definePlugin({
|
||||||
authors: [Devs.bb010g],
|
authors: [Devs.bb010g],
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".Messages.COPY_MESSAGE_LINK,",
|
find: "#{intl::COPY_MESSAGE_LINK}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\.concat\(location\.host\)/,
|
match: /\.concat\(location\.host\)/,
|
||||||
replace: ".concat($self.normalizeHost(location.host))",
|
replace: ".concat($self.normalizeHost(location.host))",
|
||||||
|
|
|
@ -18,8 +18,9 @@
|
||||||
|
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
|
import { getIntlMessage } from "@utils/discord";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { Constants, GuildStore, i18n, RestAPI } from "@webpack/common";
|
import { Constants, GuildStore, RestAPI } from "@webpack/common";
|
||||||
|
|
||||||
function showDisableInvites(guildId: string) {
|
function showDisableInvites(guildId: string) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
@ -43,15 +44,15 @@ export default definePlugin({
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "Messages.GUILD_INVITE_DISABLE_ACTION_SHEET_DESCRIPTION",
|
find: "#{intl::GUILD_INVITE_DISABLE_ACTION_SHEET_DESCRIPTION}",
|
||||||
group: true,
|
group: true,
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /children:\i\.\i\.\i\.GUILD_INVITE_DISABLE_ACTION_SHEET_DESCRIPTION/,
|
match: /children:\i\.\i\.string\(\i\.\i#{intl::GUILD_INVITE_DISABLE_ACTION_SHEET_DESCRIPTION}\)/,
|
||||||
replace: "children: $self.renderInvitesLabel({guildId:arguments[0].guildId,setChecked})",
|
replace: "children: $self.renderInvitesLabel({guildId:arguments[0].guildId,setChecked})",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
match: /\.INVITES_DISABLED\)(?=.+?\.Messages\.INVITES_PERMANENTLY_DISABLED_TIP.+?checked:(\i)).+?\[\1,(\i)\]=\i.useState\(\i\)/,
|
match: /\.INVITES_DISABLED\)(?=.+?#{intl::INVITES_PERMANENTLY_DISABLED_TIP}.+?checked:(\i)).+?\[\1,(\i)\]=\i.useState\(\i\)/,
|
||||||
replace: "$&,setChecked=$2"
|
replace: "$&,setChecked=$2"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -61,7 +62,7 @@ export default definePlugin({
|
||||||
renderInvitesLabel: ErrorBoundary.wrap(({ guildId, setChecked }) => {
|
renderInvitesLabel: ErrorBoundary.wrap(({ guildId, setChecked }) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{i18n.Messages.GUILD_INVITE_DISABLE_ACTION_SHEET_DESCRIPTION}
|
{getIntlMessage("GUILD_INVITE_DISABLE_ACTION_SHEET_DESCRIPTION")}
|
||||||
{showDisableInvites(guildId) && <a role="button" onClick={() => {
|
{showDisableInvites(guildId) && <a role="button" onClick={() => {
|
||||||
setChecked(true);
|
setChecked(true);
|
||||||
disableInvites(guildId);
|
disableInvites(guildId);
|
||||||
|
|
|
@ -32,7 +32,7 @@ export default definePlugin({
|
||||||
patches: [
|
patches: [
|
||||||
// Permission lockout, just set the check to true
|
// Permission lockout, just set the check to true
|
||||||
{
|
{
|
||||||
find: ".STAGE_CHANNEL_CANNOT_OVERWRITE_PERMISSION",
|
find: "#{intl::STAGE_CHANNEL_CANNOT_OVERWRITE_PERMISSION}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /case"DENY":.{0,50}if\((?=\i\.\i\.can)/,
|
match: /case"DENY":.{0,50}if\((?=\i\.\i\.can)/,
|
||||||
|
@ -43,7 +43,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
// Onboarding, same thing but we need to prevent the check
|
// Onboarding, same thing but we need to prevent the check
|
||||||
{
|
{
|
||||||
find: ".ONBOARDING_CHANNEL_THRESHOLD_WARNING",
|
find: "#{intl::ONBOARDING_CHANNEL_THRESHOLD_WARNING}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /{(\i:function\(\){return \i},?){2}}/,
|
match: /{(\i:function\(\){return \i},?){2}}/,
|
||||||
|
|
|
@ -19,10 +19,10 @@
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Flex } from "@components/Flex";
|
import { Flex } from "@components/Flex";
|
||||||
import { InfoIcon, OwnerCrownIcon } from "@components/Icons";
|
import { InfoIcon, OwnerCrownIcon } from "@components/Icons";
|
||||||
import { getUniqueUsername } from "@utils/discord";
|
import { getIntlMessage, getUniqueUsername } from "@utils/discord";
|
||||||
import { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
import { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
||||||
import { findByCodeLazy } from "@webpack";
|
import { findByCodeLazy } from "@webpack";
|
||||||
import { Clipboard, ContextMenuApi, FluxDispatcher, GuildMemberStore, GuildStore, i18n, Menu, PermissionsBits, ScrollerThin, Text, Tooltip, useEffect, UserStore, useState, useStateFromStores } from "@webpack/common";
|
import { Clipboard, ContextMenuApi, FluxDispatcher, GuildMemberStore, GuildStore, Menu, PermissionsBits, ScrollerThin, Text, Tooltip, useEffect, UserStore, useState, useStateFromStores } from "@webpack/common";
|
||||||
import { UnicodeEmoji } from "@webpack/types";
|
import { UnicodeEmoji } from "@webpack/types";
|
||||||
import type { Guild, Role, User } from "discord-types/general";
|
import type { Guild, Role, User } from "discord-types/general";
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ function RoleContextMenu({ guild, roleId, onClose }: { guild: Guild; roleId: str
|
||||||
>
|
>
|
||||||
<Menu.MenuItem
|
<Menu.MenuItem
|
||||||
id={cl("copy-role-id")}
|
id={cl("copy-role-id")}
|
||||||
label={i18n.Messages.COPY_ID_ROLE}
|
label={getIntlMessage("COPY_ID_ROLE")}
|
||||||
action={() => {
|
action={() => {
|
||||||
Clipboard.copy(roleId);
|
Clipboard.copy(roleId);
|
||||||
}}
|
}}
|
||||||
|
@ -225,7 +225,7 @@ function RoleContextMenu({ guild, roleId, onClose }: { guild: Guild; roleId: str
|
||||||
{(settings.store as any).unsafeViewAsRole && (
|
{(settings.store as any).unsafeViewAsRole && (
|
||||||
<Menu.MenuItem
|
<Menu.MenuItem
|
||||||
id={cl("view-as-role")}
|
id={cl("view-as-role")}
|
||||||
label={i18n.Messages.VIEW_AS_ROLE}
|
label={getIntlMessage("VIEW_AS_ROLE")}
|
||||||
action={() => {
|
action={() => {
|
||||||
const role = GuildStore.getRole(guild.id, roleId);
|
const role = GuildStore.getRole(guild.id, roleId);
|
||||||
if (!role) return;
|
if (!role) return;
|
||||||
|
@ -257,7 +257,7 @@ function UserContextMenu({ userId }: { userId: string; }) {
|
||||||
>
|
>
|
||||||
<Menu.MenuItem
|
<Menu.MenuItem
|
||||||
id={cl("copy-user-id")}
|
id={cl("copy-user-id")}
|
||||||
label={i18n.Messages.COPY_ID_USER}
|
label={getIntlMessage("COPY_ID_USER")}
|
||||||
action={() => {
|
action={() => {
|
||||||
Clipboard.copy(userId);
|
Clipboard.copy(userId);
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -18,9 +18,10 @@
|
||||||
|
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { ExpandableHeader } from "@components/ExpandableHeader";
|
import { ExpandableHeader } from "@components/ExpandableHeader";
|
||||||
|
import { getIntlMessage } from "@utils/discord";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { filters, findBulk, proxyLazyWebpack } from "@webpack";
|
import { filters, findBulk, proxyLazyWebpack } from "@webpack";
|
||||||
import { i18n, PermissionsBits, Text, Tooltip, useMemo, UserStore } from "@webpack/common";
|
import { PermissionsBits, Text, Tooltip, useMemo, UserStore } from "@webpack/common";
|
||||||
import type { Guild, GuildMember } from "discord-types/general";
|
import type { Guild, GuildMember } from "discord-types/general";
|
||||||
|
|
||||||
import { PermissionsSortOrder, settings } from "..";
|
import { PermissionsSortOrder, settings } from "..";
|
||||||
|
@ -105,7 +106,7 @@ function UserPermissionsComponent({ guild, guildMember, forceOpen = false }: { g
|
||||||
permissions: Object.values(PermissionsBits).reduce((prev, curr) => prev | curr, 0n)
|
permissions: Object.values(PermissionsBits).reduce((prev, curr) => prev | curr, 0n)
|
||||||
});
|
});
|
||||||
|
|
||||||
const OWNER = i18n.Messages.GUILD_OWNER || "Server Owner";
|
const OWNER = getIntlMessage("GUILD_OWNER") || "Server Owner";
|
||||||
userPermissions.push({
|
userPermissions.push({
|
||||||
permission: OWNER,
|
permission: OWNER,
|
||||||
roleName: "Owner",
|
roleName: "Owner",
|
||||||
|
|
|
@ -170,7 +170,7 @@ export default definePlugin({
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".VIEW_ALL_ROLES,",
|
find: "#{intl::VIEW_ALL_ROLES}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\.expandButton,.+?null,/,
|
match: /\.expandButton,.+?null,/,
|
||||||
replace: "$&$self.ViewPermissionsButton(arguments[0]),"
|
replace: "$&$self.ViewPermissionsButton(arguments[0]),"
|
||||||
|
|
|
@ -17,8 +17,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { classNameFactory } from "@api/Styles";
|
import { classNameFactory } from "@api/Styles";
|
||||||
|
import { getIntlMessage } from "@utils/discord";
|
||||||
import { wordsToTitle } from "@utils/text";
|
import { wordsToTitle } from "@utils/text";
|
||||||
import { GuildStore, i18n, Parser } from "@webpack/common";
|
import { GuildStore, Parser } from "@webpack/common";
|
||||||
import { Guild, GuildMember, Role } from "discord-types/general";
|
import { Guild, GuildMember, Role } from "discord-types/general";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ const PermissionKeyMap = {
|
||||||
export function getPermissionString(permission: string) {
|
export function getPermissionString(permission: string) {
|
||||||
permission = PermissionKeyMap[permission] || permission;
|
permission = PermissionKeyMap[permission] || permission;
|
||||||
|
|
||||||
return i18n.Messages[permission] ||
|
return getIntlMessage(permission) ||
|
||||||
// shouldn't get here but just in case
|
// shouldn't get here but just in case
|
||||||
formatPermissionWithoutMatchingString(permission);
|
formatPermissionWithoutMatchingString(permission);
|
||||||
}
|
}
|
||||||
|
@ -58,7 +59,7 @@ export function getPermissionDescription(permission: string): ReactNode {
|
||||||
else if (permission !== "STREAM")
|
else if (permission !== "STREAM")
|
||||||
permission = PermissionKeyMap[permission] || permission;
|
permission = PermissionKeyMap[permission] || permission;
|
||||||
|
|
||||||
const msg = i18n.Messages[`ROLE_PERMISSIONS_${permission}_DESCRIPTION`] as any;
|
const msg = getIntlMessage(`ROLE_PERMISSIONS_${permission}_DESCRIPTION`) as any;
|
||||||
if (msg?.hasMarkdown)
|
if (msg?.hasMarkdown)
|
||||||
return Parser.parse(msg.message);
|
return Parser.parse(msg.message);
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ interface ColorPickerWithSwatchesProps {
|
||||||
renderCustomButton?: () => React.ReactNode;
|
renderCustomButton?: () => React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ColorPicker = findComponentByCodeLazy<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
|
const ColorPicker = findComponentByCodeLazy<ColorPickerProps>("#{intl::USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR}", ".BACKGROUND_PRIMARY)");
|
||||||
const ColorPickerWithSwatches = findExportedComponentLazy<ColorPickerWithSwatchesProps>("ColorPicker", "CustomColorPicker");
|
const ColorPickerWithSwatches = findExportedComponentLazy<ColorPickerWithSwatchesProps>("ColorPicker", "CustomColorPicker");
|
||||||
|
|
||||||
export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}Promise\.all\((\[\i\.\i\("?.+?"?\).+?\])\).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}"UserSettings"/);
|
export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}Promise\.all\((\[\i\.\i\("?.+?"?\).+?\])\).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}"UserSettings"/);
|
||||||
|
|
|
@ -67,7 +67,7 @@ export default definePlugin({
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".REPLY_QUOTE_MESSAGE_BLOCKED",
|
find: "#{intl::REPLY_QUOTE_MESSAGE_BLOCKED}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\.onClickReply,.+?}\),(?=\i,\i,\i\])/,
|
match: /\.onClickReply,.+?}\),(?=\i,\i,\i\])/,
|
||||||
replace: "$&$self.ReplyTimestamp(arguments[0]),"
|
replace: "$&$self.ReplyTimestamp(arguments[0]),"
|
||||||
|
|
|
@ -108,7 +108,7 @@ export default definePlugin({
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".Messages.MESSAGE_ACTIONS_MENU_LABEL,shouldHideMediaOptions",
|
find: "#{intl::MESSAGE_ACTIONS_MENU_LABEL}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /favoriteableType:\i,(?<=(\i)\.getAttribute\("data-type"\).+?)/,
|
match: /favoriteableType:\i,(?<=(\i)\.getAttribute\("data-type"\).+?)/,
|
||||||
replace: (m, target) => `${m}reverseImageSearchType:${target}.getAttribute("data-role"),`
|
replace: (m, target) => `${m}reverseImageSearchType:${target}.getAttribute("data-role"),`
|
||||||
|
|
|
@ -104,7 +104,7 @@ export default definePlugin({
|
||||||
predicate: () => settings.store.memberList,
|
predicate: () => settings.store.memberList,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.THREAD_BROWSER_PRIVATE",
|
find: "#{intl::THREAD_BROWSER_PRIVATE}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /children:\[\i," — ",\i\]/,
|
match: /children:\[\i," — ",\i\]/,
|
||||||
|
@ -132,7 +132,7 @@ export default definePlugin({
|
||||||
predicate: () => settings.store.reactorsList,
|
predicate: () => settings.store.reactorsList,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: '.Messages.MESSAGE_EDITED,")"',
|
find: "#{intl::MESSAGE_EDITED}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=isUnsupported\]:(\i)\.isUnsupported\}\),)(?=children:\[)/,
|
match: /(?<=isUnsupported\]:(\i)\.isUnsupported\}\),)(?=children:\[)/,
|
||||||
replace: "style:{color:$self.useMessageColor($1)},"
|
replace: "style:{color:$self.useMessageColor($1)},"
|
||||||
|
|
|
@ -46,7 +46,7 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".PREVIEW_NUM_LINES",
|
find: "#{intl::PREVIEW_NUM_LINES}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=function \i\((\i)\)\{)(?=let\{text:\i,language:)/,
|
match: /(?<=function \i\((\i)\)\{)(?=let\{text:\i,language:)/,
|
||||||
replace: "return $self.renderHighlighter({lang:$1.language,content:$1.text});"
|
replace: "return $self.renderHighlighter({lang:$1.language,content:$1.text});"
|
||||||
|
|
|
@ -26,7 +26,7 @@ export default definePlugin({
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".Messages.MESSAGE_UTILITIES_A11Y_LABEL",
|
find: "#{intl::MESSAGE_UTILITIES_A11Y_LABEL}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /isExpanded:\i&&(.+?),/,
|
match: /isExpanded:\i&&(.+?),/,
|
||||||
replace: "isExpanded:$1,"
|
replace: "isExpanded:$1,"
|
||||||
|
|
|
@ -16,11 +16,12 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { getIntlMessage } from "@utils/discord";
|
||||||
import { findComponentByCodeLazy, findLazy } from "@webpack";
|
import { findComponentByCodeLazy, findLazy } from "@webpack";
|
||||||
import { i18n, useToken } from "@webpack/common";
|
import { useToken } from "@webpack/common";
|
||||||
|
|
||||||
const ColorMap = findLazy(m => m.colors?.INTERACTIVE_MUTED?.css);
|
const ColorMap = findLazy(m => m.colors?.INTERACTIVE_MUTED?.css);
|
||||||
const VerifiedIconComponent = findComponentByCodeLazy(".CONNECTIONS_ROLE_OFFICIAL_ICON_TOOLTIP");
|
const VerifiedIconComponent = findComponentByCodeLazy("#{intl::CONNECTIONS_ROLE_OFFICIAL_ICON_TOOLTIP}");
|
||||||
|
|
||||||
export function VerifiedIcon() {
|
export function VerifiedIcon() {
|
||||||
const color = useToken(ColorMap.colors.INTERACTIVE_MUTED).hex();
|
const color = useToken(ColorMap.colors.INTERACTIVE_MUTED).hex();
|
||||||
|
@ -31,7 +32,7 @@ export function VerifiedIcon() {
|
||||||
color={color}
|
color={color}
|
||||||
forcedIconColor={forcedIconColor}
|
forcedIconColor={forcedIconColor}
|
||||||
size={16}
|
size={16}
|
||||||
tooltipText={i18n.Messages.CONNECTION_VERIFIED}
|
tooltipText={getIntlMessage("CONNECTION_VERIFIED")}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
import { Settings } from "@api/Settings";
|
import { Settings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { formatDuration } from "@utils/text";
|
import { formatDuration } from "@utils/text";
|
||||||
import { findByPropsLazy, findComponentByCodeLazy, findComponentLazy } from "@webpack";
|
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
|
||||||
import { EmojiStore, FluxDispatcher, GuildMemberStore, GuildStore, Parser, PermissionsBits, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip, useEffect, useState } from "@webpack/common";
|
import { EmojiStore, FluxDispatcher, GuildMemberStore, GuildStore, Parser, PermissionsBits, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip, useEffect, useState } from "@webpack/common";
|
||||||
import type { Channel } from "discord-types/general";
|
import type { Channel } from "discord-types/general";
|
||||||
|
|
||||||
|
@ -80,14 +80,8 @@ const enum ChannelFlags {
|
||||||
|
|
||||||
const ChatScrollClasses = findByPropsLazy("auto", "managedReactiveScroller");
|
const ChatScrollClasses = findByPropsLazy("auto", "managedReactiveScroller");
|
||||||
const ChatClasses = findByPropsLazy("chat", "content", "noChat", "chatContent");
|
const ChatClasses = findByPropsLazy("chat", "content", "noChat", "chatContent");
|
||||||
const ChannelBeginHeader = findComponentByCodeLazy(".Messages.ROLE_REQUIRED_SINGLE_USER_MESSAGE");
|
const ChannelBeginHeader = findComponentByCodeLazy("#{intl::ROLE_REQUIRED_SINGLE_USER_MESSAGE}");
|
||||||
const TagComponent = findComponentLazy(m => {
|
const TagComponent = findComponentByCodeLazy("#{intl::FORUM_TAG_A11Y_FILTER_BY_TAG}");
|
||||||
if (typeof m !== "function") return false;
|
|
||||||
|
|
||||||
const code = Function.prototype.toString.call(m);
|
|
||||||
// Get the component which doesn't include increasedActivity
|
|
||||||
return code.includes(".Messages.FORUM_TAG_A11Y_FILTER_BY_TAG") && !code.includes("increasedActivityPill");
|
|
||||||
});
|
|
||||||
|
|
||||||
const EmojiParser = findByPropsLazy("convertSurrogateToName");
|
const EmojiParser = findByPropsLazy("convertSurrogateToName");
|
||||||
const EmojiUtils = findByPropsLazy("getURL", "getEmojiColors");
|
const EmojiUtils = findByPropsLazy("getURL", "getEmojiColors");
|
||||||
|
|
|
@ -103,7 +103,7 @@ export default definePlugin({
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
// Do not show confirmation to join a voice channel when already connected to another if clicking on a hidden voice channel
|
// Do not show confirmation to join a voice channel when already connected to another if clicking on a hidden voice channel
|
||||||
match: /(?<=getBlockedUsersForVoiceChannel\((\i)\.id\);return)/,
|
match: /(?<=getBlockedUsersForVoiceChannel\((\i)\.id\);return\()/,
|
||||||
replace: (_, channel) => `!$self.isHiddenChannel(${channel})&&`
|
replace: (_, channel) => `!$self.isHiddenChannel(${channel})&&`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -149,7 +149,7 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.CHANNEL_TOOLTIP_DIRECTORY",
|
find: "#{intl::CHANNEL_TOOLTIP_DIRECTORY}",
|
||||||
predicate: () => settings.store.showMode === ShowMode.LockIcon,
|
predicate: () => settings.store.showMode === ShowMode.LockIcon,
|
||||||
replacement: {
|
replacement: {
|
||||||
// Lock Icon
|
// Lock Icon
|
||||||
|
@ -274,7 +274,7 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.ROLE_REQUIRED_SINGLE_USER_MESSAGE",
|
find: "#{intl::ROLE_REQUIRED_SINGLE_USER_MESSAGE}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
// Change the role permission check to CONNECT if the channel is locked
|
// Change the role permission check to CONNECT if the channel is locked
|
||||||
|
@ -336,7 +336,7 @@ export default definePlugin({
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.CHANNEL_CALL_CURRENT_SPEAKER.format",
|
find: "#{intl::CHANNEL_CALL_CURRENT_SPEAKER}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
// Remove the divider and the open chat button for the HiddenChannelLockScreen
|
// Remove the divider and the open chat button for the HiddenChannelLockScreen
|
||||||
|
@ -351,7 +351,7 @@ export default definePlugin({
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.EMBEDDED_ACTIVITIES_DEVELOPER_ACTIVITY_SHELF_FETCH_ERROR",
|
find: "#{intl::EMBEDDED_ACTIVITIES_DEVELOPER_ACTIVITY_SHELF_FETCH_ERROR}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
// Render our HiddenChannelLockScreen component instead of the main voice channel component
|
// Render our HiddenChannelLockScreen component instead of the main voice channel component
|
||||||
|
@ -401,7 +401,7 @@ export default definePlugin({
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.STAGE_FULL_MODERATOR_TITLE",
|
find: "#{intl::STAGE_FULL_MODERATOR_TITLE}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
// Remove the divider and amount of users in stage channel components for the HiddenChannelLockScreen
|
// Remove the divider and amount of users in stage channel components for the HiddenChannelLockScreen
|
||||||
|
@ -463,7 +463,7 @@ export default definePlugin({
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.FORM_LABEL_MUTED",
|
find: "#{intl::FORM_LABEL_MUTED}",
|
||||||
replacement: {
|
replacement: {
|
||||||
// Make GuildChannelStore.getChannels return hidden channels
|
// Make GuildChannelStore.getChannels return hidden channels
|
||||||
match: /(?<=getChannels\(\i)(?=\))/,
|
match: /(?<=getChannels\(\i)(?=\))/,
|
||||||
|
|
|
@ -68,7 +68,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
// fixes a bug where Members page must be loaded to see highest role, why is Discord depending on MemberSafetyStore.getEnhancedMember for something that can be obtained here?
|
// fixes a bug where Members page must be loaded to see highest role, why is Discord depending on MemberSafetyStore.getEnhancedMember for something that can be obtained here?
|
||||||
{
|
{
|
||||||
find: "Messages.GUILD_MEMBER_MOD_VIEW_PERMISSION_GRANTED_BY_ARIA_LABEL,allowOverflow",
|
find: "#{intl::GUILD_MEMBER_MOD_VIEW_PERMISSION_GRANTED_BY_ARIA_LABEL}",
|
||||||
predicate: () => settings.store.showModView,
|
predicate: () => settings.store.showModView,
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(role:)\i(?=,guildId.{0,100}role:(\i\[))/,
|
match: /(role:)\i(?=,guildId.{0,100}role:(\i\[))/,
|
||||||
|
|
|
@ -9,13 +9,16 @@ import "./styles.css";
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
|
import { getIntlMessage } from "@utils/discord";
|
||||||
|
import { canonicalizeMatch } from "@utils/patches";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findComponentLazy } from "@webpack";
|
import { findComponentLazy } from "@webpack";
|
||||||
import { ChannelStore, GuildMemberStore, i18n, Text, Tooltip } from "@webpack/common";
|
import { ChannelStore, GuildMemberStore, Text, Tooltip } from "@webpack/common";
|
||||||
import { Message } from "discord-types/general";
|
import { Message } from "discord-types/general";
|
||||||
import { FunctionComponent, ReactNode } from "react";
|
import { FunctionComponent, ReactNode } from "react";
|
||||||
|
|
||||||
const CountDown = findComponentLazy(m => m.prototype?.render?.toString().includes(".MAX_AGE_NEVER"));
|
const countDownFilter = canonicalizeMatch("#{intl::MAX_AGE_NEVER}");
|
||||||
|
const CountDown = findComponentLazy(m => m.prototype?.render?.toString().includes(countDownFilter));
|
||||||
|
|
||||||
const enum DisplayStyle {
|
const enum DisplayStyle {
|
||||||
Tooltip = "tooltip",
|
Tooltip = "tooltip",
|
||||||
|
@ -48,9 +51,14 @@ function renderTimeout(message: Message, inline: boolean) {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
getIntlMessage("GUILD_ENABLE_COMMUNICATION_TIME_REMAINING", {
|
||||||
|
username: message.author.username,
|
||||||
|
countdown
|
||||||
|
});
|
||||||
|
|
||||||
return inline
|
return inline
|
||||||
? countdown()
|
? countdown()
|
||||||
: i18n.Messages.GUILD_ENABLE_COMMUNICATION_TIME_REMAINING.format({
|
: getIntlMessage("GUILD_ENABLE_COMMUNICATION_TIME_REMAINING", {
|
||||||
username: message.author.username,
|
username: message.author.username,
|
||||||
countdown
|
countdown
|
||||||
});
|
});
|
||||||
|
@ -65,10 +73,10 @@ export default definePlugin({
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".GUILD_COMMUNICATION_DISABLED_ICON_TOOLTIP_BODY",
|
find: "#{intl::GUILD_COMMUNICATION_DISABLED_ICON_TOOLTIP_BODY}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /(\i)\.Tooltip,{(text:.{0,30}\.Messages\.GUILD_COMMUNICATION_DISABLED_ICON_TOOLTIP_BODY)/,
|
match: /(\i)\.Tooltip,{(text:.{0,30}#{intl::GUILD_COMMUNICATION_DISABLED_ICON_TOOLTIP_BODY}\))/,
|
||||||
replace: "$self.TooltipWrapper,{message:arguments[0].message,$2"
|
replace: "$self.TooltipWrapper,{message:arguments[0].message,$2"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -45,7 +45,7 @@ export default definePlugin({
|
||||||
replace: "}).sortBy(row => $self.wrapSort(($1), row)).value()"
|
replace: "}).sortBy(row => $self.wrapSort(($1), row)).value()"
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
find: ".Messages.FRIEND_REQUEST_CANCEL",
|
find: "#{intl::FRIEND_REQUEST_CANCEL}",
|
||||||
replacement: {
|
replacement: {
|
||||||
predicate: () => settings.store.showDates,
|
predicate: () => settings.store.showDates,
|
||||||
match: /subText:(\i)(?<=user:(\i).+?)/,
|
match: /subText:(\i)(?<=user:(\i).+?)/,
|
||||||
|
|
|
@ -26,7 +26,7 @@ export default definePlugin({
|
||||||
description: "Adds Startup Timings to the Settings menu",
|
description: "Adds Startup Timings to the Settings menu",
|
||||||
authors: [Devs.Megu],
|
authors: [Devs.Megu],
|
||||||
patches: [{
|
patches: [{
|
||||||
find: "Messages.ACTIVITY_SETTINGS",
|
find: "#{intl::ACTIVITY_SETTINGS}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=}\)([,;])(\i\.settings)\.forEach.+?(\i)\.push.+}\)}\))/,
|
match: /(?<=}\)([,;])(\i\.settings)\.forEach.+?(\i)\.push.+}\)}\))/,
|
||||||
replace: (_, commaOrSemi, settings, elements) => "" +
|
replace: (_, commaOrSemi, settings, elements) => "" +
|
||||||
|
|
|
@ -38,7 +38,7 @@ export default definePlugin({
|
||||||
// add --avatar-url-<resolution> css variable to avatar img elements
|
// add --avatar-url-<resolution> css variable to avatar img elements
|
||||||
// popout profiles
|
// popout profiles
|
||||||
{
|
{
|
||||||
find: ".LABEL_WITH_ONLINE_STATUS",
|
find: "#{intl::LABEL_WITH_ONLINE_STATUS}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /src:null!=\i\?(\i).{1,50}"aria-hidden":!0/,
|
match: /src:null!=\i\?(\i).{1,50}"aria-hidden":!0/,
|
||||||
replace: "$&,style:$self.getAvatarStyles($1)"
|
replace: "$&,style:$self.getAvatarStyles($1)"
|
||||||
|
@ -55,6 +55,8 @@ export default definePlugin({
|
||||||
],
|
],
|
||||||
|
|
||||||
getAvatarStyles(src: string) {
|
getAvatarStyles(src: string) {
|
||||||
|
if (src.startsWith("data:")) return {};
|
||||||
|
|
||||||
return Object.fromEntries(
|
return Object.fromEntries(
|
||||||
[128, 256, 512, 1024, 2048, 4096].map(size => [
|
[128, 256, 512, 1024, 2048, 4096].map(size => [
|
||||||
`--avatar-url-${size}`,
|
`--avatar-url-${size}`,
|
||||||
|
|
|
@ -21,9 +21,10 @@ import "./style.css";
|
||||||
import { definePluginSettings, Settings } from "@api/Settings";
|
import { definePluginSettings, Settings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
|
import { getIntlMessage } from "@utils/discord";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findComponentByCodeLazy, findExportedComponentLazy, findStoreLazy } from "@webpack";
|
import { findComponentByCodeLazy, findExportedComponentLazy, findStoreLazy } from "@webpack";
|
||||||
import { ChannelStore, GuildMemberStore, i18n, RelationshipStore, SelectedChannelStore, Tooltip, UserStore, useStateFromStores } from "@webpack/common";
|
import { ChannelStore, GuildMemberStore, RelationshipStore, SelectedChannelStore, Tooltip, UserStore, useStateFromStores } from "@webpack/common";
|
||||||
|
|
||||||
import { buildSeveralUsers } from "../typingTweaks";
|
import { buildSeveralUsers } from "../typingTweaks";
|
||||||
|
|
||||||
|
@ -75,21 +76,21 @@ function TypingIndicator({ channelId }: { channelId: string; }) {
|
||||||
switch (typingUsersArray.length) {
|
switch (typingUsersArray.length) {
|
||||||
case 0: break;
|
case 0: break;
|
||||||
case 1: {
|
case 1: {
|
||||||
tooltipText = i18n.Messages.ONE_USER_TYPING.format({ a: getDisplayName(guildId, typingUsersArray[0]) });
|
tooltipText = getIntlMessage("ONE_USER_TYPING", { a: getDisplayName(guildId, typingUsersArray[0]) });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
tooltipText = i18n.Messages.TWO_USERS_TYPING.format({ a: getDisplayName(guildId, typingUsersArray[0]), b: getDisplayName(guildId, typingUsersArray[1]) });
|
tooltipText = getIntlMessage("TWO_USERS_TYPING", { a: getDisplayName(guildId, typingUsersArray[0]), b: getDisplayName(guildId, typingUsersArray[1]) });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3: {
|
case 3: {
|
||||||
tooltipText = i18n.Messages.THREE_USERS_TYPING.format({ a: getDisplayName(guildId, typingUsersArray[0]), b: getDisplayName(guildId, typingUsersArray[1]), c: getDisplayName(guildId, typingUsersArray[2]) });
|
tooltipText = getIntlMessage("THREE_USERS_TYPING", { a: getDisplayName(guildId, typingUsersArray[0]), b: getDisplayName(guildId, typingUsersArray[1]), c: getDisplayName(guildId, typingUsersArray[2]) });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
tooltipText = Settings.plugins.TypingTweaks.enabled
|
tooltipText = Settings.plugins.TypingTweaks.enabled
|
||||||
? buildSeveralUsers({ a: getDisplayName(guildId, typingUsersArray[0]), b: getDisplayName(guildId, typingUsersArray[1]), count: typingUsersArray.length - 2 })
|
? buildSeveralUsers({ a: getDisplayName(guildId, typingUsersArray[0]), b: getDisplayName(guildId, typingUsersArray[1]), count: typingUsersArray.length - 2 })
|
||||||
: i18n.Messages.SEVERAL_USERS_TYPING;
|
: getIntlMessage("SEVERAL_USERS_TYPING");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,8 +112,8 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: "getCooldownTextStyle",
|
find: "getCooldownTextStyle",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=(\i)\.length\?\i.\i\.Messages.THREE_USERS_TYPING\.format\({\i:(\i),(?:\i:)?(\i),\i:\i}\):)\i\.\i\.Messages\.SEVERAL_USERS_TYPING/,
|
match: /(,{a:(\i),b:(\i),c:\i}\):)\i\.\i\.string\(\i\.\i#{intl::SEVERAL_USERS_TYPING}\)(?<=(\i)\.length.+?)/,
|
||||||
replace: (_, users, a, b) => `$self.buildSeveralUsers({ a: ${a}, b: ${b}, count: ${users}.length - 2 })`
|
replace: (_, rest, a, b, users) => `${rest}$self.buildSeveralUsers({ a: ${a}, b: ${b}, count: ${users}.length - 2 })`
|
||||||
},
|
},
|
||||||
predicate: () => settings.store.alternativeFormatting
|
predicate: () => settings.store.alternativeFormatting
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ export default definePlugin({
|
||||||
settings,
|
settings,
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".Messages.AVATAR_UPLOAD_EDIT_MEDIA",
|
find: "#{intl::AVATAR_UPLOAD_EDIT_MEDIA}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /maxValue:\d/,
|
match: /maxValue:\d/,
|
||||||
replace: "maxValue:$self.settings.store.zoomMultiplier",
|
replace: "maxValue:$self.settings.store.zoomMultiplier",
|
||||||
|
|
|
@ -18,9 +18,10 @@
|
||||||
|
|
||||||
import { getUserSettingLazy } from "@api/UserSettings";
|
import { getUserSettingLazy } from "@api/UserSettings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
|
import { getIntlMessage } from "@utils/discord";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByPropsLazy } from "@webpack";
|
||||||
import { i18n, Tooltip, UserStore } from "@webpack/common";
|
import { Tooltip, UserStore } from "@webpack/common";
|
||||||
import { Message } from "discord-types/general";
|
import { Message } from "discord-types/general";
|
||||||
|
|
||||||
import { settings } from "./settings";
|
import { settings } from "./settings";
|
||||||
|
@ -44,7 +45,7 @@ function PronounsChatComponent({ message }: { message: Message; }) {
|
||||||
const pronouns = useFormattedPronouns(message.author.id);
|
const pronouns = useFormattedPronouns(message.author.id);
|
||||||
|
|
||||||
return pronouns && (
|
return pronouns && (
|
||||||
<Tooltip text={i18n.Messages.USER_PROFILE_PRONOUNS}>
|
<Tooltip text={getIntlMessage("USER_PROFILE_PRONOUNS")}>
|
||||||
{tooltipProps => (
|
{tooltipProps => (
|
||||||
<span
|
<span
|
||||||
{...tooltipProps}
|
{...tooltipProps}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { Channel } from "discord-types/general";
|
||||||
const cl = classNameFactory("vc-uvs-");
|
const cl = classNameFactory("vc-uvs-");
|
||||||
|
|
||||||
const { selectVoiceChannel } = findByPropsLazy("selectVoiceChannel", "selectChannel");
|
const { selectVoiceChannel } = findByPropsLazy("selectVoiceChannel", "selectChannel");
|
||||||
const { useChannelName } = mapMangledModuleLazy(".Messages.GROUP_DM_ALONE", {
|
const { useChannelName } = mapMangledModuleLazy("#{intl::GROUP_DM_ALONE}", {
|
||||||
useChannelName: filters.byCode("()=>null==")
|
useChannelName: filters.byCode("()=>null==")
|
||||||
});
|
});
|
||||||
const getDMChannelIcon = findByCodeLazy(".getChannelIconURL({");
|
const getDMChannelIcon = findByCodeLazy(".getChannelIconURL({");
|
||||||
|
|
|
@ -57,7 +57,7 @@ export default definePlugin({
|
||||||
patches: [
|
patches: [
|
||||||
// User Popout, Full Size Profile, Direct Messages Side Profile
|
// User Popout, Full Size Profile, Direct Messages Side Profile
|
||||||
{
|
{
|
||||||
find: ".Messages.USER_PROFILE_LOAD_ERROR",
|
find: "#{intl::USER_PROFILE_LOAD_ERROR}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(\.fetchError.+?\?)null/,
|
match: /(\.fetchError.+?\?)null/,
|
||||||
replace: (_, rest) => `${rest}$self.VoiceChannelIndicator({userId:arguments[0]?.userId,isProfile:true})`
|
replace: (_, rest) => `${rest}$self.VoiceChannelIndicator({userId:arguments[0]?.userId,isProfile:true})`
|
||||||
|
@ -78,7 +78,7 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: "PrivateChannel.renderAvatar",
|
find: "PrivateChannel.renderAvatar",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\.Messages\.CLOSE_DM.+?}\)(?=])/,
|
match: /#{intl::CLOSE_DM}.+?}\)(?=])/,
|
||||||
replace: "$&,$self.VoiceChannelIndicator({userId:arguments[0]?.user?.id})"
|
replace: "$&,$self.VoiceChannelIndicator({userId:arguments[0]?.user?.id})"
|
||||||
},
|
},
|
||||||
predicate: () => settings.store.showVoiceChannelIndicator
|
predicate: () => settings.store.showVoiceChannelIndicator
|
||||||
|
|
|
@ -37,9 +37,9 @@ export default definePlugin({
|
||||||
authors: [Devs.newwares],
|
authors: [Devs.newwares],
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "Messages.REPLY_QUOTE_MESSAGE_NOT_LOADED",
|
find: "#{intl::REPLY_QUOTE_MESSAGE_NOT_LOADED}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /Messages\.REPLY_QUOTE_MESSAGE_NOT_LOADED/,
|
match: /#{intl::REPLY_QUOTE_MESSAGE_NOT_LOADED}\)/,
|
||||||
replace: "$&,onMouseEnter:()=>$self.fetchReply(arguments[0])"
|
replace: "$&,onMouseEnter:()=>$self.fetchReply(arguments[0])"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,11 +23,12 @@ import { CodeBlock } from "@components/CodeBlock";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Flex } from "@components/Flex";
|
import { Flex } from "@components/Flex";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
|
import { getIntlMessage } from "@utils/discord";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { copyWithToast } from "@utils/misc";
|
import { copyWithToast } from "@utils/misc";
|
||||||
import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { Button, ChannelStore, Forms, i18n, Menu, Text } from "@webpack/common";
|
import { Button, ChannelStore, Forms, Menu, Text } from "@webpack/common";
|
||||||
import { Message } from "discord-types/general";
|
import { Message } from "discord-types/general";
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ function MakeContextCallback(name: "Guild" | "User" | "Channel"): NavContextMenu
|
||||||
return (children, props) => {
|
return (children, props) => {
|
||||||
const value = props[name.toLowerCase()];
|
const value = props[name.toLowerCase()];
|
||||||
if (!value) return;
|
if (!value) return;
|
||||||
if (props.label === i18n.Messages.CHANNEL_ACTIONS_MENU_LABEL) return; // random shit like notification settings
|
if (props.label === getIntlMessage("CHANNEL_ACTIONS_MENU_LABEL")) return; // random shit like notification settings
|
||||||
|
|
||||||
const lastChild = children.at(-1);
|
const lastChild = children.at(-1);
|
||||||
if (lastChild?.key === "developer-actions") {
|
if (lastChild?.key === "developer-actions") {
|
||||||
|
|
|
@ -57,7 +57,7 @@ export default definePlugin({
|
||||||
patches: [
|
patches: [
|
||||||
// Change the max volume for sliders to allow for values above 200
|
// Change the max volume for sliders to allow for values above 200
|
||||||
...[
|
...[
|
||||||
".Messages.USER_VOLUME",
|
"#{intl::USER_VOLUME}",
|
||||||
"currentVolume:"
|
"currentVolume:"
|
||||||
].map(find => ({
|
].map(find => ({
|
||||||
find,
|
find,
|
||||||
|
|
|
@ -127,11 +127,11 @@ export default definePlugin({
|
||||||
replace: "return [true"
|
replace: "return [true"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
match: /(?<=COPY_IMAGE_MENU_ITEM,)action:/,
|
match: /(?<=#{intl::COPY_IMAGE_MENU_ITEM}\),)action:/,
|
||||||
replace: "action:()=>$self.copyImage(arguments[0]),oldAction:"
|
replace: "action:()=>$self.copyImage(arguments[0]),oldAction:"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
match: /(?<=SAVE_IMAGE_MENU_ITEM,)action:/,
|
match: /(?<=#{intl::SAVE_IMAGE_MENU_ITEM}\),)action:/,
|
||||||
replace: "action:()=>$self.saveImage(arguments[0]),oldAction:"
|
replace: "action:()=>$self.saveImage(arguments[0]),oldAction:"
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -202,14 +202,14 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.SEARCH_WITH_GOOGLE",
|
find: "#{intl::SEARCH_WITH_GOOGLE}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\i\.isPlatformEmbedded/,
|
match: /\i\.isPlatformEmbedded/,
|
||||||
replace: "true"
|
replace: "true"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".Messages.COPY,hint:",
|
find: "#{intl::COPY}),hint:",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /\i\.isPlatformEmbedded/,
|
match: /\i\.isPlatformEmbedded/,
|
||||||
|
|
|
@ -19,12 +19,39 @@
|
||||||
import "./discord.css";
|
import "./discord.css";
|
||||||
|
|
||||||
import { MessageObject } from "@api/MessageEvents";
|
import { MessageObject } from "@api/MessageEvents";
|
||||||
import { ChannelStore, ComponentDispatch, Constants, FluxDispatcher, GuildStore, InviteActions, MessageActions, PrivateChannelsStore, RestAPI, SelectedChannelStore, SelectedGuildStore, UserProfileActions, UserProfileStore, UserSettingsActionCreators, UserUtils } from "@webpack/common";
|
import { ChannelStore, ComponentDispatch, Constants, FluxDispatcher, GuildStore, i18n, InviteActions, MessageActions, PrivateChannelsStore, RestAPI, SelectedChannelStore, SelectedGuildStore, UserProfileActions, UserProfileStore, UserSettingsActionCreators, UserUtils } from "@webpack/common";
|
||||||
import { Channel, Guild, Message, User } from "discord-types/general";
|
import { Channel, Guild, Message, User } from "discord-types/general";
|
||||||
import { Except } from "type-fest";
|
import { Except } from "type-fest";
|
||||||
|
|
||||||
|
import { runtimeHashMessageKey } from "./intlHash";
|
||||||
|
import { Logger } from "./Logger";
|
||||||
import { MediaModalItem, MediaModalProps, openMediaModal } from "./modal";
|
import { MediaModalItem, MediaModalProps, openMediaModal } from "./modal";
|
||||||
|
|
||||||
|
const IntlManagerLogger = new Logger("IntlManager");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an internationalized message from a non hashed key
|
||||||
|
* @param key The plain message key
|
||||||
|
* @param values The values to interpolate, if it's a rich message
|
||||||
|
*/
|
||||||
|
export function getIntlMessage(key: string, values?: Record<PropertyKey, any>): any {
|
||||||
|
return getIntlMessageFromHash(runtimeHashMessageKey(key), values, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an internationalized message from a hashed key
|
||||||
|
* @param hashedKey The hashed message key
|
||||||
|
* @param values The values to interpolate, if it's a rich message
|
||||||
|
*/
|
||||||
|
export function getIntlMessageFromHash(hashedKey: string, values?: Record<PropertyKey, any>, originalKey?: string): any {
|
||||||
|
try {
|
||||||
|
return values == null ? i18n.intl.string(i18n.t[hashedKey]) : i18n.intl.format(i18n.t[hashedKey], values);
|
||||||
|
} catch (e) {
|
||||||
|
IntlManagerLogger.error(`Failed to get intl message for key: ${originalKey ?? hashedKey}`, e);
|
||||||
|
return originalKey ?? "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the invite modal
|
* Open the invite modal
|
||||||
* @param code The invite code
|
* @param code The invite code
|
||||||
|
|
|
@ -22,6 +22,7 @@ export * from "./ChangeList";
|
||||||
export * from "./constants";
|
export * from "./constants";
|
||||||
export * from "./discord";
|
export * from "./discord";
|
||||||
export * from "./guards";
|
export * from "./guards";
|
||||||
|
export * from "./intlHash";
|
||||||
export * from "./lazy";
|
export * from "./lazy";
|
||||||
export * from "./lazyReact";
|
export * from "./lazyReact";
|
||||||
export * from "./localStorage";
|
export * from "./localStorage";
|
||||||
|
|
52
src/utils/intlHash.ts
Normal file
52
src/utils/intlHash.ts
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/* eslint-disable simple-header/header */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* discord-intl
|
||||||
|
*
|
||||||
|
* @copyright 2024 Discord, Inc.
|
||||||
|
* @link https://github.com/discord/discord-intl
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { hash as h64 } from "@intrnl/xxhash64";
|
||||||
|
|
||||||
|
const BASE64_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");
|
||||||
|
const IS_BIG_ENDIAN = (() => {
|
||||||
|
const array = new Uint8Array(4);
|
||||||
|
const view = new Uint32Array(array.buffer);
|
||||||
|
return !((view[0] = 1) & array[0]);
|
||||||
|
})();
|
||||||
|
|
||||||
|
function numberToBytes(number: number | bigint) {
|
||||||
|
number = BigInt(number);
|
||||||
|
const array: number[] = [];
|
||||||
|
const byteCount = Math.ceil(Math.floor(Math.log2(Number(number)) + 1) / 8);
|
||||||
|
for (let i = 0; i < byteCount; i++) {
|
||||||
|
array.unshift(Number((number >> BigInt(8 * i)) & BigInt(255)));
|
||||||
|
}
|
||||||
|
|
||||||
|
const bytes = new Uint8Array(array);
|
||||||
|
// The native `hashToMessageKey` always works in Big/Network Endian bytes, so this array
|
||||||
|
// needs to be converted to the same endianness to get the same base64 result.
|
||||||
|
return IS_BIG_ENDIAN ? bytes : bytes.reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a consistent, short hash of the given key by first processing it through a hash digest,
|
||||||
|
* then encoding the first few bytes to base64.
|
||||||
|
*
|
||||||
|
* This function is specifically written to mirror the native backend hashing function used by
|
||||||
|
* `@discord/intl-loader-core`, to be able to hash names at runtime.
|
||||||
|
*/
|
||||||
|
export function runtimeHashMessageKey(key: string): string {
|
||||||
|
const hash = h64(key, 0);
|
||||||
|
const bytes = numberToBytes(hash);
|
||||||
|
return [
|
||||||
|
BASE64_TABLE[bytes[0] >> 2],
|
||||||
|
BASE64_TABLE[((bytes[0] & 0x03) << 4) | (bytes[1] >> 4)],
|
||||||
|
BASE64_TABLE[((bytes[1] & 0x0f) << 2) | (bytes[2] >> 6)],
|
||||||
|
BASE64_TABLE[bytes[2] & 0x3f],
|
||||||
|
BASE64_TABLE[bytes[3] >> 2],
|
||||||
|
BASE64_TABLE[((bytes[3] & 0x03) << 4) | (bytes[3] >> 4)],
|
||||||
|
].join("");
|
||||||
|
}
|
|
@ -16,12 +16,31 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { runtimeHashMessageKey } from "./intlHash";
|
||||||
import { Patch, PatchReplacement, ReplaceFn } from "./types";
|
import { Patch, PatchReplacement, ReplaceFn } from "./types";
|
||||||
|
|
||||||
export function canonicalizeMatch<T extends RegExp | string>(match: T): T {
|
export function canonicalizeMatch<T extends RegExp | string>(match: T): T {
|
||||||
if (typeof match === "string") return match;
|
let partialCanon = typeof match === "string" ? match : match.source;
|
||||||
const canonSource = match.source
|
partialCanon = partialCanon.replaceAll(/#{intl::([A-Za-z_$][\w$]*)}/g, (_, key) => {
|
||||||
.replaceAll("\\i", "[A-Za-z_$][\\w$]*");
|
const hashed = runtimeHashMessageKey(key);
|
||||||
|
|
||||||
|
const isString = typeof match === "string";
|
||||||
|
const hasSpecialChars = !Number.isNaN(Number(hashed[0])) || hashed.includes("+") || hashed.includes("/");
|
||||||
|
|
||||||
|
if (hasSpecialChars) {
|
||||||
|
return isString
|
||||||
|
? `["${hashed}"]`
|
||||||
|
: String.raw`(?:\["${hashed}"\])`.replaceAll("+", "\\+");
|
||||||
|
}
|
||||||
|
|
||||||
|
return isString ? `.${hashed}` : String.raw`(?:\.${hashed})`;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (typeof match === "string") {
|
||||||
|
return partialCanon as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
const canonSource = partialCanon.replaceAll(String.raw`\i`, String.raw`(?:[A-Za-z_$][\w$]*)`);
|
||||||
return new RegExp(canonSource, match.flags) as T;
|
return new RegExp(canonSource, match.flags) as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ export let FocusLock: t.FocusLock;
|
||||||
export let useToken: t.useToken;
|
export let useToken: t.useToken;
|
||||||
|
|
||||||
export const MaskedLink = waitForComponent<t.MaskedLink>("MaskedLink", filters.componentByCode("MASKED_LINK)"));
|
export const MaskedLink = waitForComponent<t.MaskedLink>("MaskedLink", filters.componentByCode("MASKED_LINK)"));
|
||||||
export const Timestamp = waitForComponent<t.Timestamp>("Timestamp", filters.byCode(".Messages.MESSAGE_EDITED_TIMESTAMP_A11Y_LABEL.format"));
|
export const Timestamp = waitForComponent<t.Timestamp>("Timestamp", filters.byCode("#{intl::MESSAGE_EDITED_TIMESTAMP_A11Y_LABEL}"));
|
||||||
export const Flex = waitForComponent<t.Flex>("Flex", ["Justify", "Align", "Wrap"]);
|
export const Flex = waitForComponent<t.Flex>("Flex", ["Justify", "Align", "Wrap"]);
|
||||||
|
|
||||||
export const { OAuth2AuthorizeModal } = findByPropsLazy("OAuth2AuthorizeModal");
|
export const { OAuth2AuthorizeModal } = findByPropsLazy("OAuth2AuthorizeModal");
|
||||||
|
|
File diff suppressed because one or more lines are too long
1
src/webpack/common/types/index.d.ts
vendored
1
src/webpack/common/types/index.d.ts
vendored
|
@ -19,7 +19,6 @@
|
||||||
export * from "./classes";
|
export * from "./classes";
|
||||||
export * from "./components";
|
export * from "./components";
|
||||||
export * from "./fluxEvents";
|
export * from "./fluxEvents";
|
||||||
export * from "./i18nMessages";
|
|
||||||
export * from "./menu";
|
export * from "./menu";
|
||||||
export * from "./stores";
|
export * from "./stores";
|
||||||
export * from "./utils";
|
export * from "./utils";
|
||||||
|
|
14
src/webpack/common/types/utils.d.ts
vendored
14
src/webpack/common/types/utils.d.ts
vendored
|
@ -21,7 +21,6 @@ import type { ReactNode } from "react";
|
||||||
import { LiteralUnion } from "type-fest";
|
import { LiteralUnion } from "type-fest";
|
||||||
|
|
||||||
import type { FluxEvents } from "./fluxEvents";
|
import type { FluxEvents } from "./fluxEvents";
|
||||||
import { i18nMessages } from "./i18nMessages";
|
|
||||||
|
|
||||||
export { FluxEvents };
|
export { FluxEvents };
|
||||||
|
|
||||||
|
@ -148,19 +147,6 @@ export interface LocaleInfo {
|
||||||
postgresLang: string;
|
postgresLang: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface i18n {
|
|
||||||
getAvailableLocales(): Locale[];
|
|
||||||
getLanguages(): LocaleInfo[];
|
|
||||||
getDefaultLocale(): string;
|
|
||||||
getLocale(): string;
|
|
||||||
getLocaleInfo(): LocaleInfo;
|
|
||||||
setLocale(locale: string): void;
|
|
||||||
|
|
||||||
loadPromise: Promise<void>;
|
|
||||||
|
|
||||||
Messages: Record<i18nMessages, any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Clipboard {
|
export interface Clipboard {
|
||||||
copy(text: string): void;
|
copy(text: string): void;
|
||||||
SUPPORTS_COPY: boolean;
|
SUPPORTS_COPY: boolean;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { runtimeHashMessageKey } from "@utils/intlHash";
|
||||||
import type { Channel } from "discord-types/general";
|
import type { Channel } from "discord-types/general";
|
||||||
|
|
||||||
// eslint-disable-next-line path-alias/no-relative
|
// eslint-disable-next-line path-alias/no-relative
|
||||||
|
@ -56,7 +57,10 @@ export const { match, P }: Pick<typeof import("ts-pattern"), "match" | "P"> = ma
|
||||||
|
|
||||||
export const lodash: typeof import("lodash") = findByPropsLazy("debounce", "cloneDeep");
|
export const lodash: typeof import("lodash") = findByPropsLazy("debounce", "cloneDeep");
|
||||||
|
|
||||||
export const i18n: t.i18n = findLazy(m => m.Messages?.["en-US"]);
|
export const i18n = mapMangledModuleLazy('defaultLocale:"en-US"', {
|
||||||
|
intl: filters.byProps("string", "format"),
|
||||||
|
t: filters.byProps(runtimeHashMessageKey("DISCORD"))
|
||||||
|
});
|
||||||
|
|
||||||
export let SnowflakeUtils: t.SnowflakeUtils;
|
export let SnowflakeUtils: t.SnowflakeUtils;
|
||||||
waitFor(["fromTimestamp", "extractTimestamp"], m => SnowflakeUtils = m);
|
waitFor(["fromTimestamp", "extractTimestamp"], m => SnowflakeUtils = m);
|
||||||
|
@ -131,7 +135,7 @@ export const UserUtils = {
|
||||||
|
|
||||||
export const UploadManager = findByPropsLazy("clearAll", "addFile");
|
export const UploadManager = findByPropsLazy("clearAll", "addFile");
|
||||||
export const UploadHandler = {
|
export const UploadHandler = {
|
||||||
promptToUpload: findByCodeLazy(".ATTACHMENT_TOO_MANY_ERROR_TITLE,") as (files: File[], channel: Channel, draftType: Number) => void
|
promptToUpload: findByCodeLazy("#{intl::ATTACHMENT_TOO_MANY_ERROR_TITLE}") as (files: File[], channel: Channel, draftType: Number) => void
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ApplicationAssetUtils = findByPropsLazy("fetchAssetIds", "getAssetImage") as {
|
export const ApplicationAssetUtils = findByPropsLazy("fetchAssetIds", "getAssetImage") as {
|
||||||
|
|
Loading…
Reference in a new issue