Compare commits

...

27 Commits

Author SHA1 Message Date
Vendicated
86e94343cc bump to v1.6.3 2023-11-05 02:07:33 +01:00
Vendicated
dd44ac1ad2 OpenInApp: Support podcasts 2023-11-04 19:08:44 +01:00
Vendicated
370b3d366d OpenInApp: Fix links in messages 2023-11-04 18:59:16 +01:00
Vendicated
a67c7f841d Fix ViewIcons correctly 2023-11-04 18:54:29 +01:00
Vendicated
2c9793202d Revert "Fix ViewIcons"
This reverts commit 098da8c3fd95cdd1f299b86d0b919b001009a1df.
2023-11-04 18:54:02 +01:00
AutumnVN
a257926609 customRpc: fix discord attachment link (#1949) 2023-11-04 18:45:17 +01:00
AutumnVN
77659be4f0 fakeNitro: disallow emoji in add reaction (#1954) 2023-11-04 18:44:53 +01:00
AutumnVN
37b9a62460 favGifSearch: fix search bar (#1955) 2023-11-04 18:44:29 +01:00
Lewis Crichton
7f73e13364 docs: point people to advisories for security bugs (#1957) 2023-11-04 18:41:38 +01:00
Vendicated
fcf2bdda70 fix TypingTweaks 2023-11-03 02:03:58 +01:00
AutumnVN
fa9da2d693 noMosaic: play video inline + optional media layout type (#1946) 2023-11-03 01:57:39 +01:00
AutumnVN
44b21394b3 gifPaste: fix unable to use gif picker in profile customization (#1947) 2023-11-03 01:56:31 +01:00
Nuckyz
27fffc8bc3 Fix ShowMeYourName 2023-11-01 23:28:52 -03:00
Nuckyz
098da8c3fd Fix ViewIcons 2023-11-01 23:26:13 -03:00
Nuckyz
9cf88d4232 Fix MessageDecorationsAPI 2023-11-01 22:46:06 -03:00
Vendicated
dd61b0c999 bump to v1.6.2 2023-11-01 02:25:13 +01:00
Haruka
5dc0d06be1 EmoteCloner: make the error toasts useful (#1938)
Co-authored-by: Vendicated <vendicated@riseup.net>
2023-11-01 02:23:45 +01:00
AutumnVN
9de6c2d4ff previewMessage: fix button (#1919) 2023-11-01 02:19:26 +01:00
AutumnVN
e37f62ac0a imageZoom: dont close carousel modal on image click (#1926)
Co-authored-by: Vendicated <vendicated@riseup.net>
2023-11-01 02:19:02 +01:00
AutumnVN
56a9d79f85 PiP: fix issues / styles (#1927) 2023-11-01 02:14:32 +01:00
Nuckyz
9d78233afa Fix displaying BetterFolders sidebar when watching streams in fullscreen 2023-11-01 02:10:58 +01:00
Vendicated
9af2ec65ae OnePingPerDM: fix server pings 2023-11-01 02:09:43 +01:00
Vendicated
584885acf5 [skip ci] Revert "add react linting"
doesnt work properly :(

This reverts commit 18fdc33ee7d1f60d58645c2a98f402988b97e996.
2023-10-31 23:56:13 +01:00
Vendicated
18fdc33ee7 [skip ci] add react linting 2023-10-31 23:50:55 +01:00
V
522fdcd15d WebKeyBinds: Fix & make available on ArmCord 2023-10-28 23:51:04 +02:00
Nuckyz
af135b9245 Fix AlwaysAnimate 2023-10-28 17:43:27 -03:00
Nuckyz
4b958d17fd Fix BetterFolders freeze and add new options (#1923) 2023-10-28 20:18:00 +00:00
22 changed files with 221 additions and 81 deletions

View File

@ -14,7 +14,8 @@ body:
DO NOT USE THIS FORM, unless
- you are a vencord contributor
- you were given explicit permission to use this form by a moderator in our support server
- you are filing a security related report
DO NOT USE THIS FORM FOR SECURITY RELATED ISSUES. [CREATE A SECURITY ADVISORY INSTEAD.](https://github.com/Vendicated/Vencord/security/advisories/new)
- type: input
id: discord

View File

@ -1,7 +1,7 @@
{
"name": "vencord",
"private": "true",
"version": "1.6.1",
"version": "1.6.3",
"description": "The cutest Discord client mod",
"homepage": "https://github.com/Vendicated/Vencord#readme",
"bugs": {

View File

@ -27,8 +27,8 @@ export default definePlugin({
{
find: '"Message Username"',
replacement: {
match: /currentUserIsPremium:.{0,70}{children:\i(?=}\))/,
replace: "$&.concat(Vencord.Api.MessageDecorations.__addDecorationsToMessage(arguments[0]))"
match: /\.Messages\.GUILD_COMMUNICATION_DISABLED_BOTTOM_SHEET_TITLE.+?}\),\i(?=\])/,
replace: "$&,...Vencord.Api.MessageDecorations.__addDecorationsToMessage(arguments[0])"
}
}
],

View File

@ -21,16 +21,30 @@ import definePlugin from "@utils/types";
export default definePlugin({
name: "AlwaysAnimate",
description: "Animates anything that can be animated, besides status emojis.",
description: "Animates anything that can be animated",
authors: [Devs.FieryFlames],
patches: [
{
find: ".canAnimate",
find: "canAnimate:",
all: true,
// Some modules match the find but the replacement is returned untouched
noWarn: true,
replacement: {
match: /\.canAnimate\b/g,
replace: ".canAnimate || true"
match: /canAnimate:.+?(?=([,}].*?\)))/g,
replace: (m, rest) => {
const destructuringMatch = rest.match(/}=.+/);
if (destructuringMatch == null) return "canAnimate:!0";
return m;
}
}
},
{
// Status emojis
find: ".Messages.GUILD_OWNER,",
replacement: {
match: /(?<=\.activityEmoji,.+?animate:)\i/,
replace: "!0"
}
}
]

View File

@ -18,30 +18,40 @@
import ErrorBoundary from "@components/ErrorBoundary";
import { LazyComponent } from "@utils/react";
import { find, findByPropsLazy } from "@webpack";
import { React, useStateFromStores } from "@webpack/common";
import { find, findByPropsLazy, findStoreLazy } from "@webpack";
import { useStateFromStores } from "@webpack/common";
import type { CSSProperties } from "react";
import { ExpandedGuildFolderStore, settings } from ".";
const ChannelRTCStore = findStoreLazy("ChannelRTCStore");
const Animations = findByPropsLazy("a", "animated", "useTransition");
const GuildsBar = LazyComponent(() => find(m => m.type?.toString().includes('("guildsnav")')));
export default ErrorBoundary.wrap(guildsBarProps => {
const expandedFolders = useStateFromStores([ExpandedGuildFolderStore], () => ExpandedGuildFolderStore.getExpandedFolders());
const isFullscreen = useStateFromStores([ChannelRTCStore], () => ChannelRTCStore.isFullscreenInContext());
const Sidebar = (
<GuildsBar
{...guildsBarProps}
isBetterFolders={true}
betterFoldersExpandedIds={expandedFolders}
/>
);
const visible = !!expandedFolders.size;
const guilds = document.querySelector(guildsBarProps.className.split(" ").map(c => `.${c}`).join(""));
// We need to display none if we are in fullscreen. Yes this seems horrible doing with css, but it's literally how Discord does it.
// Also display flex otherwise to fix scrolling
const barStyle = {
display: isFullscreen ? "none" : "flex",
} as CSSProperties;
if (!guilds || !settings.store.sidebarAnim) {
return visible
? <div style={{ display: "flex " }}>{Sidebar}</div>
? <div style={barStyle}>{Sidebar}</div>
: null;
}
@ -53,9 +63,9 @@ export default ErrorBoundary.wrap(guildsBarProps => {
leave={{ width: 0 }}
config={{ duration: 200 }}
>
{(style, show) =>
{(animationStyle, show) =>
show && (
<Animations.animated.div style={{ ...style, display: "flex" }}>
<Animations.animated.div style={{ ...animationStyle, ...barStyle }}>
{Sidebar}
</Animations.animated.div>
)

View File

@ -18,13 +18,21 @@
import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import { proxyLazy } from "@utils/lazy";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy, findStoreLazy } from "@webpack";
import { findByProps, findByPropsLazy, findStoreLazy } from "@webpack";
import { FluxDispatcher, i18n } from "@webpack/common";
import FolderSideBar from "./FolderSideBar";
const GuildFolderStore = findStoreLazy("SortedGuildStore");
enum FolderIconDisplay {
Never,
Always,
MoreThanOneFolderExpanded
}
const GuildsTree = proxyLazy(() => findByProps("GuildsTree").GuildsTree);
const SortedGuildStore = findStoreLazy("SortedGuildStore");
export const ExpandedGuildFolderStore = findStoreLazy("ExpandedGuildFolderStore");
const FolderUtils = findByPropsLazy("move", "toggleGuildFolderExpand");
@ -32,7 +40,7 @@ let lastGuildId = null as string | null;
let dispatchingFoldersClose = false;
function getGuildFolder(id: string) {
return GuildFolderStore.getGuildFolders().find(folder => folder.guildIds.includes(id));
return SortedGuildStore.getGuildFolders().find(folder => folder.guildIds.includes(id));
}
function closeFolders() {
@ -50,7 +58,6 @@ export const settings = definePluginSettings({
sidebarAnim: {
type: OptionType.BOOLEAN,
description: "Animate opening the folder sidebar",
restartNeeded: true,
default: true
},
closeAllFolders: {
@ -79,6 +86,16 @@ export const settings = definePluginSettings({
description: "Keep showing guild icons in the primary guild bar folder when it's open in the BetterFolders sidebar",
restartNeeded: true,
default: false
},
showFolderIcon: {
type: OptionType.SELECT,
description: "Show the folder icon above the folder guilds in the BetterFolders sidebar",
options: [
{ label: "Never", value: FolderIconDisplay.Never },
{ label: "Always", value: FolderIconDisplay.Always, default: true },
{ label: "When more than one folder is expanded", value: FolderIconDisplay.MoreThanOneFolderExpanded }
],
restartNeeded: true
}
});
@ -99,25 +116,45 @@ export default definePlugin({
match: /(?<=let{disableAppDownload:\i=\i\.isPlatformEmbedded,isOverlay:.+?)(?=}=\i,)/,
replace: ",isBetterFolders"
},
// If we are rendering the Better Folders sidebar, we filter out guilds that are not in folders and unexpanded folders
{
match: /(useStateFromStoresArray\).{0,25}let \i)=(\i\.\i.getGuildsTree\(\))/,
replace: (_, rest, guildsTree) => `${rest}=$self.getGuildTree(!!arguments[0].isBetterFolders,${guildsTree},arguments[0].betterFoldersExpandedIds)`
},
// If we are rendering the Better Folders sidebar, we filter out everything but the servers and folders from the GuildsBar Guild List children
{
match: /lastTargetNode:\i\[\i\.length-1\].+?Fragment.+?\]}\)\]/,
replace: '$&.filter($self.makeGuildsBarGuildListFilter(typeof isBetterFolders!=="undefined"?isBetterFolders:false))'
replace: "$&.filter($self.makeGuildsBarGuildListFilter(!!arguments[0].isBetterFolders))"
},
// If we are rendering the Better Folders sidebar, we filter out everything but the scroller for the guild list from the GuildsBar Tree children
{
match: /unreadMentionsIndicatorBottom,barClassName.+?}\)\]/,
replace: '$&.filter($self.makeGuildsBarTreeFilter(typeof isBetterFolders!=="undefined"?isBetterFolders:false))'
replace: "$&.filter($self.makeGuildsBarTreeFilter(!!arguments[0].isBetterFolders))"
},
// Export the isBetterFolders variable to the folders component
{
match: /(?<=\.Messages\.SERVERS.+?switch\((\i)\.type\){case \i\.\i\.FOLDER:.+?folderNode:\i,)/,
replace: 'isBetterFolders:typeof isBetterFolders!=="undefined"?isBetterFolders:false,'
}
]
},
// Avoid rendering servers that are not in folders in the Better Folders sidebar
{
match: /(?<=\.Messages\.SERVERS.+?switch\((\i)\.type\){case \i\.\i\.FOLDER:.+?GUILD:)/,
replace: 'if((typeof isBetterFolders!=="undefined"?isBetterFolders:false)&&$1.parentId==null)return null;'
// This is the parent folder component
find: ".MAX_GUILD_FOLDER_NAME_LENGTH,",
predicate: () => settings.store.sidebar && settings.store.showFolderIcon !== FolderIconDisplay.Always,
replacement: [
{
// Modify the expanded state to instead return the list of expanded folders
match: /(useStateFromStores\).{0,20}=>)(\i\.\i)\.isFolderExpanded\(\i\)/,
replace: (_, rest, ExpandedGuildFolderStore) => `${rest}${ExpandedGuildFolderStore}.getExpandedFolders()`,
},
{
// Modify the expanded prop to use the boolean if the above patch fails, or check if the folder is expanded from the list if it succeeds
// Also export the list of expanded folders to the child folder component if the patch above succeeds, else export undefined
match: /(?<=folderNode:(\i),expanded:)\i(?=,)/,
replace: (isExpandedOrExpandedIds, folderNote) => ""
+ `typeof ${isExpandedOrExpandedIds}==="boolean"?${isExpandedOrExpandedIds}:${isExpandedOrExpandedIds}.has(${folderNote}.id),`
+ `betterFoldersExpandedIds:${isExpandedOrExpandedIds} instanceof Set?${isExpandedOrExpandedIds}:void 0`
}
]
},
@ -125,33 +162,37 @@ export default definePlugin({
find: ".FOLDER_ITEM_GUILD_ICON_MARGIN);",
predicate: () => settings.store.sidebar,
replacement: [
// Create the isBetterFolders variable in the nested folders component (the parent exports all the props so we don't have to patch it)
{
match: /(?<=let{folderNode:\i,setNodeRef:\i,)/,
replace: "isBetterFolders,"
},
// We use arguments[0] to access the isBetterFolders variable in this nested folder component (the parent exports all the props so we don't have to patch it)
// If we are rendering the normal GuildsBar sidebar, we make Discord think the folder is always collapsed to show better icons (the mini guild icons) and avoid transitions
{
predicate: () => settings.store.keepIcons,
match: /(?<=let{folderNode:\i,setNodeRef:\i,.+?expanded:(\i).+?;)(?=let)/,
replace: '$1=(typeof isBetterFolders!=="undefined"?isBetterFolders:false)?$1:false;'
},
// If we are rendering the Better Folders sidebar, we filter out folders that are not expanded
{
match: /(?=return\(0,\i.\i\)\("div")(?<=selected:\i,expanded:(\i),.+?)/,
replace: (_, expanded) => `if((typeof isBetterFolders!=="undefined"?isBetterFolders:false)&&!${expanded})return null;`
match: /(?<=let{folderNode:\i,setNodeRef:\i,.+?expanded:(\i),.+?;)(?=let)/,
replace: (_, isExpanded) => `${isExpanded}=!!arguments[0].isBetterFolders&&${isExpanded};`
},
// Disable expanding and collapsing folders transition in the normal GuildsBar sidebar
{
predicate: () => !settings.store.keepIcons,
match: /(?<=\.Messages\.SERVER_FOLDER_PLACEHOLDER.+?useTransition\)\()/,
replace: '(typeof isBetterFolders!=="undefined"?isBetterFolders:false)&&'
replace: "!!arguments[0].isBetterFolders&&"
},
// If we are rendering the normal GuildsBar sidebar, we avoid rendering guilds from folders that are expanded
{
predicate: () => !settings.store.keepIcons,
match: /expandedFolderBackground,.+?,(?=\i\(\(\i,\i,\i\)=>{let{key.{0,45}ul)(?<=selected:\i,expanded:(\i),.+?)/,
replace: (m, expanded) => `${m}((typeof isBetterFolders!=="undefined"?isBetterFolders:false)||!${expanded})&&`
replace: (m, isExpanded) => `${m}!arguments[0].isBetterFolders&&${isExpanded}?null:`
},
{
// Decide if we should render the expanded folder background if we are rendering the Better Folders sidebar
predicate: () => settings.store.showFolderIcon !== FolderIconDisplay.Always,
match: /(?<=\.wrapper,children:\[)/,
replace: "$self.shouldShowFolderIconAndBackground(!!arguments[0].isBetterFolders,arguments[0].betterFoldersExpandedIds)&&"
},
{
// Decide if we should render the expanded folder icon if we are rendering the Better Folders sidebar
predicate: () => settings.store.showFolderIcon !== FolderIconDisplay.Always,
match: /(?<=\.expandedFolderBackground.+?}\),)(?=\i,)/,
replace: "!$self.shouldShowFolderIconAndBackground(!!arguments[0].isBetterFolders,arguments[0].betterFoldersExpandedIds)?null:"
}
]
},
@ -212,6 +253,21 @@ export default definePlugin({
}
},
getGuildTree(isBetterFolders: boolean, oldTree: any, expandedFolderIds?: Set<any>) {
if (!isBetterFolders || expandedFolderIds == null) return oldTree;
const newTree = new GuildsTree();
// Children is every folder and guild which is not in a folder, this filters out only the expanded folders
newTree.root.children = oldTree.root.children.filter(guildOrFolder => expandedFolderIds.has(guildOrFolder.id));
// Nodes is every folder and guild, even if it's in a folder, this filters out only the expanded folders and guilds inside them
newTree.nodes = Object.fromEntries(
Object.entries(oldTree.nodes)
.filter(([_, guildOrFolder]: any[]) => expandedFolderIds.has(guildOrFolder.id) || expandedFolderIds.has(guildOrFolder.parentId))
);
return newTree;
},
makeGuildsBarGuildListFilter(isBetterFolders: boolean) {
return child => {
if (isBetterFolders) {
@ -230,6 +286,21 @@ export default definePlugin({
};
},
shouldShowFolderIconAndBackground(isBetterFolders: boolean, expandedFolderIds?: Set<any>) {
if (!isBetterFolders) return true;
switch (settings.store.showFolderIcon) {
case FolderIconDisplay.Never:
return false;
case FolderIconDisplay.Always:
return true;
case FolderIconDisplay.MoreThanOneFolderExpanded:
return (expandedFolderIds?.size ?? 0) > 1;
default:
return true;
}
},
FolderSideBar: guildsBarProps => <FolderSideBar {...guildsBarProps} />,
closeFolders

View File

@ -30,6 +30,7 @@ const ActivityClassName = findByPropsLazy("activity", "buttonColor");
const Colors = findByPropsLazy("profileColors");
async function getApplicationAsset(key: string): Promise<string> {
if (/https?:\/\/(cdn|media)\.discordapp\.(com|net)\/attachments\//.test(key)) return "mp:" + key.replace(/https?:\/\/(cdn|media)\.discordapp\.(com|net)\//, "");
return (await ApplicationAssetUtils.fetchAssetIds(settings.store.appID!, [key]))[0];
}

View File

@ -155,10 +155,15 @@ async function doClone(guildId: string, data: Sticker | Emoji) {
type: Toasts.Type.SUCCESS,
id: Toasts.genId()
});
} catch (e) {
} catch (e: any) {
let message = "Something went wrong (check console!)";
try {
message = JSON.parse(e.text).message;
} catch { }
new Logger("EmoteCloner").error("Failed to clone", data.name, "to", guildId, e);
Toasts.show({
message: "Oopsie something went wrong :( Check console!!!",
message: "Failed to clone: " + message,
type: Toasts.Type.FAILURE,
id: Toasts.genId()
});

View File

@ -201,7 +201,7 @@ export default definePlugin({
predicate: () => settings.store.enableEmojiBypass,
replacement: {
match: /((?:canUseEmojisEverywhere|canUseAnimatedEmojis):function\(\i)\){(.+?\))(?=})/g,
replace: (_, rest, premiumCheck) => `${rest},fakeNitroIntention){${premiumCheck}||fakeNitroIntention!=null||[${EmojiIntentions.CHAT},${EmojiIntentions.GUILD_STICKER_RELATED_EMOJI}].includes(fakeNitroIntention)`
replace: (_, rest, premiumCheck) => `${rest},fakeNitroIntention){${premiumCheck}||fakeNitroIntention==null||[${EmojiIntentions.CHAT},${EmojiIntentions.GUILD_STICKER_RELATED_EMOJI}].includes(fakeNitroIntention)`
}
},
// Allow stickers to be sent everywhere

View File

@ -60,7 +60,7 @@ interface Instance {
}
const containerClasses: { searchBar: string; } = findByPropsLazy("searchBar", "searchHeader", "searchInput");
const containerClasses: { searchBar: string; } = findByPropsLazy("searchBar", "searchBarFullRow");
export const settings = definePluginSettings({
searchOption: {
@ -182,7 +182,7 @@ function SearchBar({ instance, SearchBarComponent }: { instance: Instance; Searc
ref={ref}
autoFocus={true}
className={containerClasses.searchBar}
size={SearchBarComponent.Sizes.SMALL}
size={SearchBarComponent.Sizes.MEDIUM}
onChange={onChange}
onClear={() => {
setQuery("");

View File

@ -33,8 +33,8 @@ export default definePlugin({
patches: [{
find: ".handleSelectGIF=",
replacement: {
match: /\.handleSelectGIF=\i=>\{/,
replace: ".handleSelectGIF=function(gif){return $self.handleSelect(gif);"
match: /\.handleSelectGIF=(\i)=>\{/,
replace: ".handleSelectGIF=$1=>{if (!this.props.className) return $self.handleSelect($1);"
}
}],

View File

@ -186,6 +186,13 @@ export default definePlugin({
}
]
},
{
find: ".carouselModal",
replacement: {
match: /(?<=\.carouselModal.{0,100}onClick:)\i,/,
replace: "()=>{},"
}
}
],
settings,

View File

@ -15,19 +15,17 @@
border-radius: 0;
}
.vc-imgzoom-nearest-neighbor > img {
image-rendering: pixelated; /* https://googlechrome.github.io/samples/image-rendering-pixelated/index.html */
.vc-imgzoom-nearest-neighbor>img {
image-rendering: pixelated;
/* https://googlechrome.github.io/samples/image-rendering-pixelated/index.html */
}
/* make the carousel take up less space so we can click the backdrop and exit out of it */
[class|="carouselModal"] {
height: fit-content;
box-shadow: none;
[class*="modalCarouselWrapper_"] {
top: 0 !important;
}
[class|="wrapper"]:has(> #vc-imgzoom-magnify-modal) {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
[class*="carouselModal_"] {
height: 0 !important;
}

View File

@ -4,28 +4,58 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { definePluginSettings } from "@api/Settings";
import { disableStyle, enableStyle } from "@api/Styles";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import definePlugin, { OptionType } from "@utils/types";
import style from "./styles.css?managed";
const settings = definePluginSettings({
inlineVideo: {
description: "Play videos without carousel modal",
type: OptionType.BOOLEAN,
default: true,
restartNeeded: true
},
mediaLayoutType: {
description: "Choose media layout type",
type: OptionType.SELECT,
restartNeeded: true,
options: [
{ label: "STATIC, render loading image but image isn't resposive, no problem unless discord window width is too small", value: "STATIC", default: true },
{ label: "RESPONSIVE, image is responsive but not render loading image, cause messages shift when loaded", value: "RESPONSIVE" },
]
}
});
export default definePlugin({
name: "NoMosaic",
authors: [Devs.AutumnVN],
description: "Removes Discord new image mosaic",
tags: ["image", "mosaic", "media"],
settings,
patches: [
{
find: ".oneByTwoLayoutThreeGrid",
replacement: [{
match: /mediaLayoutType:\i\.\i\.MOSAIC/,
replace: 'mediaLayoutType:"RESPONSIVE"'
replace: "mediaLayoutType:$self.mediaLayoutType()",
},
{
match: /null!==\(\i=\i\.get\(\i\)\)&&void 0!==\i\?\i:"INVALID"/,
replace: '"INVALID"',
},]
}]
},
{
find: "renderAttachments(",
predicate: () => settings.store.inlineVideo,
replacement: {
match: /url:(\i)\.url\}\);return /,
replace: "$&$1.content_type?.startsWith('image/')&&"
}
},
{
find: "Messages.REMOVE_ATTACHMENT_TOOLTIP_TEXT",
@ -33,10 +63,17 @@ export default definePlugin({
match: /\i===\i\.\i\.MOSAIC/,
replace: "true"
}
}],
}
],
mediaLayoutType() {
return settings.store.mediaLayoutType;
},
start() {
enableStyle(style);
},
stop() {
disableStyle(style);
}

View File

@ -55,10 +55,8 @@ export default definePlugin({
}],
isPrivateChannelRead(message: MessageJSON) {
const channelType = ChannelStore.getChannel(message.channel_id)?.type;
if (channelType !== ChannelType.DM && channelType !== ChannelType.GROUP_DM) {
return false;
}
if (
(channelType !== ChannelType.DM && channelType !== ChannelType.GROUP_DM) ||
(channelType === ChannelType.DM && settings.store.channelToAffect === "group_dm") ||
(channelType === ChannelType.GROUP_DM && settings.store.channelToAffect === "user_dm") ||
(settings.store.allowMentions && message.mentions.some(m => m.id === UserStore.getCurrentUser().id)) ||

View File

@ -23,7 +23,7 @@ import { showToast, Toasts } from "@webpack/common";
import type { MouseEvent } from "react";
const ShortUrlMatcher = /^https:\/\/(spotify\.link|s\.team)\/.+$/;
const SpotifyMatcher = /^https:\/\/open\.spotify\.com\/(track|album|artist|playlist|user)\/(.+)(?:\?.+?)?$/;
const SpotifyMatcher = /^https:\/\/open\.spotify\.com\/(track|album|artist|playlist|user|episode)\/(.+)(?:\?.+?)?$/;
const SteamMatcher = /^https:\/\/(steamcommunity\.com|(?:help|store)\.steampowered\.com)\/.+$/;
const EpicMatcher = /^https:\/\/store\.epicgames\.com\/(.+)$/;
@ -55,8 +55,8 @@ export default definePlugin({
{
find: "trackAnnouncementMessageLinkClicked({",
replacement: {
match: /(?<=handleClick:function\(\)\{return (\i)\}.+?)async function \1\(.+?\)\{/,
replace: "$& if(await $self.handleLink(...arguments)) return;"
match: /(?<=handleClick:function\(\)\{return (\i)\}.+?)function \1\(.+?\)\{/,
replace: "async $& if(await $self.handleLink(...arguments)) return;"
}
},
// Make Spotify profile activity links open in app on web

View File

@ -4,6 +4,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import "./styles.css";
import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
@ -28,8 +30,8 @@ export default definePlugin({
{
find: ".nonMediaAttachment]",
replacement: {
match: /\.nonMediaAttachment\].{0,10}children:\[(\S)/,
replace: "$&,$1&&$self.renderPiPButton(),"
match: /\.nonMediaAttachment\]:!(\i).{0,10}children:\[(\S)/,
replace: "$&,$1&&$2&&$self.renderPiPButton(),"
},
},
],
@ -40,6 +42,7 @@ export default definePlugin({
{tooltipProps => (
<div
{...tooltipProps}
className="vc-pip-button"
role="button"
style={{
cursor: "pointer",
@ -70,7 +73,7 @@ export default definePlugin({
>
<svg width="24px" height="24px" viewBox="0 0 24 24">
<path
fill="var(--interactive-normal)"
fill="currentColor"
d="M21 3a1 1 0 0 1 1 1v7h-2V5H4v14h6v2H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h18zm0 10a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1h-8a1 1 0 0 1-1-1v-6a1 1 0 0 1 1-1h8zm-1 2h-6v4h6v-4z"
/>
</svg>

View File

@ -137,5 +137,5 @@ export default definePlugin({
},
],
previewIcon: ErrorBoundary.wrap(PreviewButton, { noop: true }),
chatBarIcon: ErrorBoundary.wrap(PreviewButton, { noop: true }),
});

View File

@ -47,7 +47,7 @@ export default definePlugin({
authors: [Devs.Rini, Devs.TheKodeToad],
patches: [
{
find: '"Message Username"',
find: ".useCanSeeRemixBadge)",
replacement: {
match: /(?<=onContextMenu:\i,children:).*?\}/,
replace: "$self.renderUsername(arguments[0])}"

View File

@ -112,7 +112,7 @@ export default definePlugin({
{
find: "getCooldownTextStyle",
replacement: {
match: /(?<=(\i)\.length\?\i.\i\.Messages.THREE_USERS_TYPING\.format\({\i:(\i),\i:(\i),\i:\i}\):)\i\.\i\.Messages\.SEVERAL_USERS_TYPING/,
match: /(?<=(\i)\.length\?\i.\i\.Messages.THREE_USERS_TYPING\.format\({\i:(\i),(?:\i:)?(\i),\i:\i}\):)\i\.\i\.Messages\.SEVERAL_USERS_TYPING/,
replace: (_, users, a, b) => `$self.buildSeveralUsers({ a: ${a}, b: ${b}, count: ${users}.length - 2 })`
},
predicate: () => settings.store.alternativeFormatting

View File

@ -173,7 +173,7 @@ export default definePlugin({
patches: [
// Make pfps clickable
{
find: "onAddFriend:function",
find: "User Profile Modal - Context Menu",
replacement: {
match: /\{src:(\i)(?=,avatarDecoration)/,
replace: "{src:$1,onClick:()=>$self.openImage($1)"

View File

@ -18,19 +18,14 @@
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findLazy, mapMangledModuleLazy } from "@webpack";
import { findByPropsLazy } from "@webpack";
import { ComponentDispatch, FluxDispatcher, NavigationRouter, SelectedGuildStore, SettingsRouter } from "@webpack/common";
const GuildNavBinds = mapMangledModuleLazy("mod+alt+down", {
CtrlTab: m => m.binds?.at(-1) === "ctrl+tab",
CtrlShiftTab: m => m.binds?.at(-1) === "ctrl+shift+tab",
});
const DigitBinds = findLazy(m => m.binds?.[0] === "mod+1");
const KeyBinds = findByPropsLazy("JUMP_TO_GUILD", "SERVER_NEXT");
export default definePlugin({
name: "WebKeybinds",
description: "Re-adds keybinds missing in the web version of Discord: ctrl+t, ctrl+shift+t, ctrl+tab, ctrl+shift+tab, ctrl+1-9, ctrl+,",
description: "Re-adds keybinds missing in the web version of Discord: ctrl+t, ctrl+shift+t, ctrl+tab, ctrl+shift+tab, ctrl+1-9, ctrl+,. Only works fully on Vesktop/ArmCord, not inside your browser",
authors: [Devs.Ven],
enabledByDefault: true,
@ -57,13 +52,13 @@ export default definePlugin({
SettingsRouter.open("My Account");
break;
case "Tab":
const handler = e.shiftKey ? GuildNavBinds.CtrlShiftTab : GuildNavBinds.CtrlTab;
const handler = e.shiftKey ? KeyBinds.SERVER_PREV : KeyBinds.SERVER_NEXT;
handler.action(e);
break;
default:
if (e.key >= "1" && e.key <= "9") {
e.preventDefault();
DigitBinds.action(e, `mod+${e.key}`);
KeyBinds.JUMP_TO_GUILD.action(e, `mod+${e.key}`);
}
break;
}