Compare commits
11 Commits
v1.5.3
...
feat/permi
Author | SHA1 | Date | |
---|---|---|---|
|
64c7581286 | ||
|
30b2e88e77 | ||
|
1f38a8eeab | ||
|
6db9721c06 | ||
|
9891791fa7 | ||
|
8dd5eeead2 | ||
|
abf8667a5d | ||
|
e33ac900bc | ||
|
8a026060c7 | ||
|
c8b77bb187 | ||
|
88b06191b9 |
20
.github/ISSUE_TEMPLATE/blank.yml
vendored
20
.github/ISSUE_TEMPLATE/blank.yml
vendored
@ -2,9 +2,29 @@ name: Blank Issue
|
||||
description: Create a blank issue. ALWAYS FIRST USE OUR SUPPORT CHANNEL! ONLY USE THIS FORM IF YOU ARE A CONTRIBUTOR OR WERE TOLD TO DO SO IN THE SUPPORT CHANNEL.
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# READ THIS BEFORE OPENING AN ISSUE
|
||||
|
||||
This form is ONLY FOR DEVELOPERS. YOUR ISSUE WILL BE CLOSED AND YOU WILL POSSIBLY BE BLOCKED FROM THE REPOSITORY IF YOU IGNORE THIS.
|
||||
|
||||
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
|
||||
|
||||
- type: textarea
|
||||
id: content
|
||||
attributes:
|
||||
label: Content
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
id: agreement-check
|
||||
attributes:
|
||||
label: Request Agreement
|
||||
options:
|
||||
- label: I have read the requirements for opening an issue above
|
||||
required: true
|
||||
|
14
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
14
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -4,6 +4,18 @@ labels: [bug]
|
||||
title: "[Bug] <title>"
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# READ THIS BEFORE OPENING AN ISSUE
|
||||
|
||||
This form is ONLY FOR DEVELOPERS. YOUR ISSUE WILL BE CLOSED AND YOU WILL POSSIBLY BE BLOCKED FROM THE REPOSITORY IF YOU IGNORE THIS.
|
||||
|
||||
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
|
||||
|
||||
- type: input
|
||||
id: discord
|
||||
attributes:
|
||||
@ -64,3 +76,5 @@ body:
|
||||
options:
|
||||
- label: I am using Discord Stable or tried on Stable and this bug happens there as well
|
||||
required: true
|
||||
- label: I have read the requirements for opening an issue above
|
||||
required: true
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "vencord",
|
||||
"private": "true",
|
||||
"version": "1.5.3",
|
||||
"version": "1.5.4",
|
||||
"description": "The cutest Discord client mod",
|
||||
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
||||
"bugs": {
|
||||
|
7
src/plugins/onePingPerDM/README.md
Normal file
7
src/plugins/onePingPerDM/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# OnePingPerDM
|
||||
If unread messages are sent by a user in DMs multiple times, you'll only receive one audio ping. Read the messages to reset the limit
|
||||
|
||||
## Purpose
|
||||
- Prevents ping audio spam in DMs
|
||||
- Be able to distinguish more than one ping as multiple users
|
||||
- Be less annoyed while gaming
|
39
src/plugins/onePingPerDM/index.ts
Normal file
39
src/plugins/onePingPerDM/index.ts
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2023 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
import { ChannelStore, ReadStateStore } from "@webpack/common";
|
||||
import { Message } from "discord-types/general";
|
||||
|
||||
const enum ChannelType {
|
||||
DM = 1,
|
||||
GROUP_DM = 3
|
||||
}
|
||||
|
||||
export default definePlugin({
|
||||
name: "OnePingPerDM",
|
||||
description: "If unread messages are sent by a user in DMs multiple times, you'll only receive one audio ping. Read the messages to reset the limit",
|
||||
authors: [Devs.ProffDea],
|
||||
patches: [{
|
||||
find: ".getDesktopType()===",
|
||||
replacement: [{
|
||||
match: /if\((\i\.\i\.getDesktopType\(\)===\i\.\i\.NEVER)\){/,
|
||||
replace: "if($1){if(!$self.isPrivateChannelRead(arguments[0]?.message))return;"
|
||||
},
|
||||
{
|
||||
match: /sound:(\i\?\i:void 0,volume:\i,onClick:)/,
|
||||
replace: "sound:!$self.isPrivateChannelRead(arguments[0]?.message)?undefined:$1"
|
||||
}]
|
||||
}],
|
||||
isPrivateChannelRead(message: Message) {
|
||||
const channelType = ChannelStore.getChannel(message.channel_id)?.type;
|
||||
if (channelType !== ChannelType.DM && channelType !== ChannelType.GROUP_DM) {
|
||||
return false;
|
||||
}
|
||||
return ReadStateStore.getOldestUnreadMessageId(message.channel_id) === message.id;
|
||||
},
|
||||
});
|
@ -19,10 +19,7 @@
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { findStoreLazy } from "@webpack";
|
||||
import { GenericStore } from "@webpack/common";
|
||||
|
||||
const PoggerModeSettingsStore: GenericStore = findStoreLazy("PoggermodeSettingsStore");
|
||||
import { FluxDispatcher } from "@webpack/common";
|
||||
|
||||
const enum Intensity {
|
||||
Normal,
|
||||
@ -61,9 +58,12 @@ export default definePlugin({
|
||||
});
|
||||
|
||||
function setPoggerState(state: boolean) {
|
||||
Object.assign(PoggerModeSettingsStore.__getLocalVars().state, {
|
||||
enabled: state,
|
||||
settingsVisible: state
|
||||
FluxDispatcher.dispatch({
|
||||
type: "POGGERMODE_SETTINGS_UPDATE",
|
||||
settings: {
|
||||
enabled: state,
|
||||
settingsVisible: state
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -101,5 +101,8 @@ function setSettings(intensity: Intensity) {
|
||||
}
|
||||
}
|
||||
|
||||
Object.assign(PoggerModeSettingsStore.__getLocalVars().state, state);
|
||||
FluxDispatcher.dispatch({
|
||||
type: "POGGERMODE_SETTINGS_UPDATE",
|
||||
settings: state
|
||||
});
|
||||
}
|
||||
|
14
src/plugins/permissionFreeWill/README.md
Normal file
14
src/plugins/permissionFreeWill/README.md
Normal file
@ -0,0 +1,14 @@
|
||||
# PermissionFreeWill
|
||||
|
||||
Removes the client-side restrictions that prevent editing channel permissions, such as permission lockouts ("Pretty sure
|
||||
you don't want to do this") and onboarding requirements ("Making this change will make your server incompatible [...]")
|
||||
|
||||
## Warning
|
||||
|
||||
This plugin will let you create permissions in servers that **WILL** lock you out of channels until an administrator
|
||||
can resolve it for you. Please be careful with the overwrites you are making and check carefully.
|
||||
|
||||
## Community Server Channels
|
||||
|
||||
Community Server channels (i.e., `#rules` and `#moderator-only`) are actually mandatory and their existence is enforced
|
||||
by the API, therefore this plugin cannot remove the restrictions behind them.
|
67
src/plugins/permissionFreeWill/index.ts
Normal file
67
src/plugins/permissionFreeWill/index.ts
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2023 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
|
||||
const settings = definePluginSettings({
|
||||
lockout: {
|
||||
type: OptionType.BOOLEAN,
|
||||
default: true,
|
||||
description: 'Bypass the permission lockout prevention ("Pretty sure you don\'t want to do this")',
|
||||
restartNeeded: true
|
||||
},
|
||||
onboarding: {
|
||||
type: OptionType.BOOLEAN,
|
||||
default: true,
|
||||
description: 'Bypass the onboarding requirements ("Making this change will make your server incompatible [...]")',
|
||||
restartNeeded: true
|
||||
}
|
||||
});
|
||||
|
||||
export default definePlugin({
|
||||
name: "PermissionFreeWill",
|
||||
description: "Disables the client-side restrictions for channel permission management.",
|
||||
authors: [Devs.lewisakura],
|
||||
|
||||
patches: [
|
||||
// Permission lockout, just set the check to true
|
||||
{
|
||||
find: "Messages.SELF_DENY_PERMISSION_BODY",
|
||||
replacement: [
|
||||
{
|
||||
match: /case"DENY":.{0,50}if\((?=\i\.\i\.can)/,
|
||||
replace: "$&true||"
|
||||
}
|
||||
],
|
||||
predicate: () => settings.store.lockout
|
||||
},
|
||||
// Onboarding, same thing but we need to prevent the check
|
||||
{
|
||||
find: "Messages.ONBOARDING_CHANNEL_THRESHOLD_WARNING",
|
||||
replacement: [
|
||||
{
|
||||
match: /case 1:if\((?=!\i\.sent.{20,30}Messages\.CANNOT_CHANGE_CHANNEL_PERMS)/,
|
||||
replace: "$&false&&"
|
||||
}
|
||||
],
|
||||
predicate: () => settings.store.onboarding
|
||||
},
|
||||
// Onboarding deletion
|
||||
{
|
||||
find: "Messages.DELETE_DEFAULT_CHANNEL_BODY",
|
||||
replacement: [
|
||||
{
|
||||
match: /if\((?=null!=\i.{5,20}Messages.DELETE_DEFAULT_CHANNEL_BODY)/,
|
||||
replace: "$&false&&"
|
||||
}
|
||||
],
|
||||
predicate: () => settings.store.onboarding
|
||||
}
|
||||
],
|
||||
settings
|
||||
});
|
@ -43,7 +43,7 @@ export default LazyComponent(() => {
|
||||
p("container", "isHeader"),
|
||||
p("avatar", "zalgo"),
|
||||
p("button", "wrapper", "selected"),
|
||||
p("botTag")
|
||||
p("botTag", "botTagRegular")
|
||||
);
|
||||
|
||||
const dateFormat = new Intl.DateTimeFormat();
|
||||
@ -94,7 +94,7 @@ export default LazyComponent(() => {
|
||||
className={classes(avatar, clickable)}
|
||||
onClick={openModal}
|
||||
src={review.sender.profilePhoto || "/assets/1f0bfc0865d324c2587920a7d80c609b.png?size=128"}
|
||||
style={{ left: "0px" }}
|
||||
style={{ left: "0px", zIndex: 0 }}
|
||||
/>
|
||||
<div style={{ display: "inline-flex", justifyContent: "center", alignItems: "center" }}>
|
||||
<span
|
||||
|
5
src/plugins/whoReacted/README.md
Normal file
5
src/plugins/whoReacted/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# WhoReacted
|
||||
|
||||
Next to each reaction, display each user's avatar. Each avatar can be clicked and will open the profile.
|
||||
|
||||
![](https://github.com/Vendicated/Vencord/assets/57493648/97fec9e8-396f-4f5e-916e-1ec21445113d)
|
@ -24,14 +24,14 @@ import { LazyComponent, useForceUpdater } from "@utils/react";
|
||||
import definePlugin from "@utils/types";
|
||||
import { findByCode, findByPropsLazy } from "@webpack";
|
||||
import { ChannelStore, FluxDispatcher, React, RestAPI, Tooltip } from "@webpack/common";
|
||||
import { ReactionEmoji, User } from "discord-types/general";
|
||||
import { CustomEmoji } from "@webpack/types";
|
||||
import { Message, ReactionEmoji, User } from "discord-types/general";
|
||||
|
||||
const UserSummaryItem = LazyComponent(() => findByCode("defaultRenderUser", "showDefaultAvatarsForNullUsers"));
|
||||
const AvatarStyles = findByPropsLazy("moreUsers", "emptyUser", "avatarContainer", "clickableAvatar");
|
||||
|
||||
const ReactionStore = findByPropsLazy("getReactions");
|
||||
|
||||
const queue = new Queue();
|
||||
let reactions: Record<string, ReactionCacheEntry>;
|
||||
|
||||
function fetchReactions(msg: Message, emoji: ReactionEmoji, type: number) {
|
||||
const key = emoji.name + (emoji.id ? `:${emoji.id}` : "");
|
||||
@ -57,11 +57,9 @@ function fetchReactions(msg: Message, emoji: ReactionEmoji, type: number) {
|
||||
|
||||
function getReactionsWithQueue(msg: Message, e: ReactionEmoji, type: number) {
|
||||
const key = `${msg.id}:${e.name}:${e.id ?? ""}:${type}`;
|
||||
const cache = ReactionStore.__getLocalVars().reactions[key] ??= { fetched: false, users: {} };
|
||||
const cache = reactions[key] ??= { fetched: false, users: {} };
|
||||
if (!cache.fetched) {
|
||||
queue.unshift(() =>
|
||||
fetchReactions(msg, e, type)
|
||||
);
|
||||
queue.unshift(() => fetchReactions(msg, e, type));
|
||||
cache.fetched = true;
|
||||
}
|
||||
|
||||
@ -92,7 +90,7 @@ function handleClickAvatar(event: React.MouseEvent<HTMLElement, MouseEvent>) {
|
||||
|
||||
export default definePlugin({
|
||||
name: "WhoReacted",
|
||||
description: "Renders the Avatars of reactors",
|
||||
description: "Renders the avatars of users who reacted to a message",
|
||||
authors: [Devs.Ven, Devs.KannaDev],
|
||||
|
||||
patches: [{
|
||||
@ -101,6 +99,12 @@ export default definePlugin({
|
||||
match: /(?<=(\i)=(\i)\.hideCount,)(.+?reactionCount.+?\}\))/,
|
||||
replace: (_, hideCount, props, rest) => `whoReactedProps=${props},${rest},${hideCount}?null:$self.renderUsers(whoReactedProps)`
|
||||
}
|
||||
}, {
|
||||
find: '.displayName="MessageReactionsStore";',
|
||||
replacement: {
|
||||
match: /(?<=CONNECTION_OPEN:function\(\){)(\i)={}/,
|
||||
replace: "$&;$self.reactions=$1"
|
||||
}
|
||||
}],
|
||||
|
||||
renderUsers(props: RootObject) {
|
||||
@ -150,106 +154,25 @@ export default definePlugin({
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
set reactions(value: any) {
|
||||
reactions = value;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
export interface GuildMemberAvatar { }
|
||||
|
||||
export interface Author {
|
||||
id: string;
|
||||
username: string;
|
||||
discriminator: string;
|
||||
avatar: string;
|
||||
avatarDecoration?: any;
|
||||
email: string;
|
||||
verified: boolean;
|
||||
bot: boolean;
|
||||
system: boolean;
|
||||
mfaEnabled: boolean;
|
||||
mobile: boolean;
|
||||
desktop: boolean;
|
||||
premiumType: number;
|
||||
flags: number;
|
||||
publicFlags: number;
|
||||
purchasedFlags: number;
|
||||
premiumUsageFlags: number;
|
||||
phone: string;
|
||||
nsfwAllowed: boolean;
|
||||
guildMemberAvatars: GuildMemberAvatar;
|
||||
interface ReactionCacheEntry {
|
||||
fetched: boolean;
|
||||
users: Record<string, User>;
|
||||
}
|
||||
|
||||
export interface Emoji {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface Reaction {
|
||||
emoji: Emoji;
|
||||
count: number;
|
||||
burst_user_ids: any[];
|
||||
burst_count: number;
|
||||
burst_colors: any[];
|
||||
burst_me: boolean;
|
||||
me: boolean;
|
||||
}
|
||||
|
||||
export interface Message {
|
||||
id: string;
|
||||
type: number;
|
||||
channel_id: string;
|
||||
author: Author;
|
||||
content: string;
|
||||
deleted: boolean;
|
||||
editHistory: any[];
|
||||
attachments: any[];
|
||||
embeds: any[];
|
||||
mentions: any[];
|
||||
mentionRoles: any[];
|
||||
mentionChannels: any[];
|
||||
mentioned: boolean;
|
||||
pinned: boolean;
|
||||
mentionEveryone: boolean;
|
||||
tts: boolean;
|
||||
codedLinks: any[];
|
||||
giftCodes: any[];
|
||||
timestamp: string;
|
||||
editedTimestamp?: any;
|
||||
state: string;
|
||||
nonce?: any;
|
||||
blocked: boolean;
|
||||
call?: any;
|
||||
bot: boolean;
|
||||
webhookId?: any;
|
||||
reactions: Reaction[];
|
||||
applicationId?: any;
|
||||
application?: any;
|
||||
activity?: any;
|
||||
messageReference?: any;
|
||||
flags: number;
|
||||
isSearchHit: boolean;
|
||||
stickers: any[];
|
||||
stickerItems: any[];
|
||||
components: any[];
|
||||
loggingName?: any;
|
||||
interaction?: any;
|
||||
interactionData?: any;
|
||||
interactionError?: any;
|
||||
}
|
||||
|
||||
export interface Emoji {
|
||||
id: string;
|
||||
name: string;
|
||||
animated: boolean;
|
||||
}
|
||||
|
||||
export interface RootObject {
|
||||
interface RootObject {
|
||||
message: Message;
|
||||
readOnly: boolean;
|
||||
isLurking: boolean;
|
||||
isPendingMember: boolean;
|
||||
useChatFontScaling: boolean;
|
||||
emoji: Emoji;
|
||||
emoji: CustomEmoji;
|
||||
count: number;
|
||||
burst_user_ids: any[];
|
||||
burst_count: number;
|
||||
|
@ -374,7 +374,11 @@ export const Devs = /* #__PURE__*/ Object.freeze({
|
||||
archeruwu: {
|
||||
name: "archer_uwu",
|
||||
id: 160068695383736320n
|
||||
}
|
||||
},
|
||||
ProffDea: {
|
||||
name: "ProffDea",
|
||||
id: 609329952180928513n
|
||||
},
|
||||
} satisfies Record<string, Dev>);
|
||||
|
||||
// iife so #__PURE__ works correctly
|
||||
|
@ -20,5 +20,5 @@ import { findByPropsLazy } from "@webpack";
|
||||
|
||||
import * as t from "./types/classes";
|
||||
|
||||
export const ModalImageClasses: t.ImageModalClasses = findByPropsLazy("image", "modal");
|
||||
export const ModalImageClasses: t.ImageModalClasses = findByPropsLazy("image", "modal", "responsiveWidthMobile");
|
||||
export const ButtonWrapperClasses: t.ButtonWrapperClasses = findByPropsLazy("buttonWrapper", "buttonContent");
|
||||
|
Reference in New Issue
Block a user