Compare commits
27 Commits
Author | SHA1 | Date | |
---|---|---|---|
30b2e88e77 | |||
1f38a8eeab | |||
6db9721c06 | |||
9891791fa7 | |||
8dd5eeead2 | |||
abf8667a5d | |||
e33ac900bc | |||
8a026060c7 | |||
c8b77bb187 | |||
88b06191b9 | |||
62277770a8 | |||
4facc3cad7 | |||
837d1fc083 | |||
608a67c9ae | |||
f32d25b641 | |||
4c7a2ba340 | |||
da7f0cfff6 | |||
ae6584da7c | |||
c6b1b9463c | |||
376aaf39ce | |||
5454a41243 | |||
044f64e446 | |||
0b7fca864a | |||
30ac256070 | |||
d0e2a32471 | |||
ec026ca34c | |||
4baaa9bd91 |
.github/ISSUE_TEMPLATE
browser
package.jsonsrc
VencordNative.ts
components
main
plugins
alwaysAnimate
alwaysTrust
anonymiseFileNames
arRPC.web
banger
betterGifAltText
betterNotes
betterRoleDot
betterUploadButton
blurNsfw
callTimer
colorSighted
consoleShortcuts
copyUserURLs
crashHandler
customRPC
devCompanion.dev
disableDMCallIdle
emoteCloner
experiments
f8break
fakeNitro
fakeProfileThemes
favEmojiFirst
favGifSearch
fixSpotifyEmbeds.desktop
forceOwnerCrown
friendInvites
gifPaste
greetStickerPicker
hideAttachments
iLoveSpam
ignoreActivities
imageZoom
keepCurrentChannel
lastfm
loadingQuotes
memberCount
messageClickActions
messageLinkEmbeds
messageTags
moreCommands
moreKaomoji
moreUserTags
moyai
muteNewGuild
mutualGroupDMs
noBlockedMessages
noDevtoolsWarning
noF1
noPendingCount
noProfileThemes
noRPC.discordDesktop
noReplyMention
noScreensharePreview
noSystemBadge.discordDesktop
noUnblockToJump
nsfwGateBypass
onePingPerDM
oneko
openInApp
partyMode
permissionFreeWill
permissionsViewer
petpet
pictureInPicture
plainFolderIcon
platformIndicators
previewMessage
quickMention
quickReply
reactErrorDecoder
readAllNotificationsButton
revealAllSpoilers
reverseImageSearch
reviewDB/components
roleColorEverywhere
searchReply
secretRingTone
serverListIndicators
showAllMessageButtons
showTimeouts
30
.github/ISSUE_TEMPLATE/blank.yml
vendored
Normal file
30
.github/ISSUE_TEMPLATE/blank.yml
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
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
|
16
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
16
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -1,9 +1,21 @@
|
||||
name: Bug/Crash Report
|
||||
description: Create a bug or crash report for Vencord
|
||||
description: Create a bug or crash report for Vencord. 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.
|
||||
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
|
||||
|
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,4 +1,4 @@
|
||||
blank_issues_enabled: true
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Vencord Support Server
|
||||
url: https://discord.gg/D9uwnFnqmd
|
||||
|
32
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
32
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@ -1,32 +0,0 @@
|
||||
name: Feature Request
|
||||
description: Create a feature request for Vencord. To request new plugins, please use the Discussions tab
|
||||
labels: [enhancement]
|
||||
title: "[Feature Request] <title>"
|
||||
|
||||
body:
|
||||
- type: input
|
||||
id: discord
|
||||
attributes:
|
||||
label: Discord Account
|
||||
description: Who on Discord is making this request? Not required but encouraged for easier follow-up
|
||||
placeholder: username#0000
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: feature-basic-description
|
||||
attributes:
|
||||
label: What is it that you'd like to see?
|
||||
description: Describe the feature you want added as detailed as possible
|
||||
placeholder: I think ... would be a cool feature to add. This would be awesome, thanks!
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
id: agreement-check
|
||||
attributes:
|
||||
label: Request Agreement
|
||||
description: DO NOT USE THIS TEMPLATE FOR PLUGIN REQUESTS!!! For plugin requests, **use discussions**
|
||||
options:
|
||||
- label: This is not a plugin request
|
||||
required: true
|
@ -48,7 +48,8 @@ window.VencordNative = {
|
||||
getThemesList: () => DataStore.entries(themeStore).then(entries =>
|
||||
entries.map(([name, css]) => getThemeInfo(css, name.toString()))
|
||||
),
|
||||
getThemeData: (fileName: string) => DataStore.get(fileName, themeStore)
|
||||
getThemeData: (fileName: string) => DataStore.get(fileName, themeStore),
|
||||
getSystemValues: async () => ({}),
|
||||
},
|
||||
|
||||
native: {
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "vencord",
|
||||
"private": "true",
|
||||
"version": "1.5.2",
|
||||
"version": "1.5.4",
|
||||
"description": "The cutest Discord client mod",
|
||||
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
||||
"bugs": {
|
||||
|
@ -23,7 +23,8 @@ export default {
|
||||
deleteTheme: (fileName: string) => invoke<void>(IpcEvents.DELETE_THEME, fileName),
|
||||
getThemesDir: () => invoke<string>(IpcEvents.GET_THEMES_DIR),
|
||||
getThemesList: () => invoke<Array<UserThemeHeader>>(IpcEvents.GET_THEMES_LIST),
|
||||
getThemeData: (fileName: string) => invoke<string | undefined>(IpcEvents.GET_THEME_DATA, fileName)
|
||||
getThemeData: (fileName: string) => invoke<string | undefined>(IpcEvents.GET_THEME_DATA, fileName),
|
||||
getSystemValues: () => invoke<Record<string, string>>(IpcEvents.GET_THEME_SYSTEM_VALUES),
|
||||
},
|
||||
|
||||
updater: {
|
||||
|
@ -221,3 +221,37 @@ export function CogWheel(props: IconProps) {
|
||||
</Icon>
|
||||
);
|
||||
}
|
||||
|
||||
export function ReplyIcon(props: IconProps) {
|
||||
return (
|
||||
<Icon
|
||||
{...props}
|
||||
className={classes(props.className, "vc-reply-icon")}
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M10 8.26667V4L3 11.4667L10 18.9333V14.56C15 14.56 18.5 16.2667 21 20C20 14.6667 17 9.33333 10 8.26667Z"
|
||||
/>
|
||||
</Icon>
|
||||
);
|
||||
}
|
||||
|
||||
export function DeleteIcon(props: IconProps) {
|
||||
return (
|
||||
<Icon
|
||||
{...props}
|
||||
className={classes(props.className, "vc-delete-icon")}
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M15 3.999V2H9V3.999H3V5.999H21V3.999H15Z"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M5 6.99902V18.999C5 20.101 5.897 20.999 7 20.999H17C18.103 20.999 19 20.101 19 18.999V6.99902H5ZM11 17H9V11H11V17ZM15 17H13V11H15V17Z"
|
||||
/>
|
||||
</Icon>
|
||||
);
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti
|
||||
<Button
|
||||
onClick={onClose}
|
||||
size={Button.Sizes.SMALL}
|
||||
color={Button.Colors.WHITE}
|
||||
color={Button.Colors.PRIMARY}
|
||||
look={Button.Looks.LINK}
|
||||
>
|
||||
Cancel
|
||||
|
@ -20,6 +20,7 @@ import { useSettings } from "@api/Settings";
|
||||
import { classNameFactory } from "@api/Styles";
|
||||
import { ErrorCard } from "@components/ErrorCard";
|
||||
import { Flex } from "@components/Flex";
|
||||
import { DeleteIcon } from "@components/Icons";
|
||||
import { Link } from "@components/Link";
|
||||
import { IsFirefox } from "@utils/constants";
|
||||
import { Margins } from "@utils/margins";
|
||||
@ -42,7 +43,6 @@ type FileInput = ComponentType<{
|
||||
}>;
|
||||
|
||||
const InviteActions = findByPropsLazy("resolveInvite");
|
||||
const TrashIcon = findByCodeLazy("M5 6.99902V18.999C5 20.101 5.897 20.999");
|
||||
const FileInput: FileInput = findByCodeLazy("activateUploadDialogue=");
|
||||
const TextAreaProps = findLazy(m => typeof m.textarea === "string");
|
||||
|
||||
@ -114,7 +114,7 @@ function ThemeCard({ theme, enabled, onChange, onDelete }: ThemeCardProps) {
|
||||
infoButton={
|
||||
IS_WEB && (
|
||||
<div style={{ cursor: "pointer", color: "var(--status-danger" }} onClick={onDelete}>
|
||||
<TrashIcon />
|
||||
<DeleteIcon />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import "./ipcPlugins";
|
||||
import { debounce } from "@utils/debounce";
|
||||
import { IpcEvents } from "@utils/IpcEvents";
|
||||
import { Queue } from "@utils/Queue";
|
||||
import { BrowserWindow, ipcMain, shell } from "electron";
|
||||
import { BrowserWindow, ipcMain, shell, systemPreferences } from "electron";
|
||||
import { mkdirSync, readFileSync, watch } from "fs";
|
||||
import { open, readdir, readFile, writeFile } from "fs/promises";
|
||||
import { join, normalize } from "path";
|
||||
@ -112,6 +112,10 @@ ipcMain.handle(IpcEvents.SET_QUICK_CSS, (_, css) =>
|
||||
ipcMain.handle(IpcEvents.GET_THEMES_DIR, () => THEMES_DIR);
|
||||
ipcMain.handle(IpcEvents.GET_THEMES_LIST, () => listThemes());
|
||||
ipcMain.handle(IpcEvents.GET_THEME_DATA, (_, fileName) => getThemeData(fileName));
|
||||
ipcMain.handle(IpcEvents.GET_THEME_SYSTEM_VALUES, () => ({
|
||||
// win & mac only
|
||||
"os-accent-color": `#${systemPreferences.getAccentColor?.() || ""}`
|
||||
}));
|
||||
|
||||
ipcMain.handle(IpcEvents.GET_SETTINGS_DIR, () => SETTINGS_DIR);
|
||||
ipcMain.on(IpcEvents.GET_SETTINGS, e => e.returnValue = readSettings());
|
||||
|
@ -24,11 +24,9 @@ import { Margins } from "@utils/margins";
|
||||
import { ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/modal";
|
||||
import definePlugin from "@utils/types";
|
||||
import { findByCodeLazy, findStoreLazy } from "@webpack";
|
||||
import { EmojiStore, FluxDispatcher, Forms, GuildStore, Menu, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common";
|
||||
import { EmojiStore, FluxDispatcher, Forms, GuildStore, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common";
|
||||
import { Promisable } from "type-fest";
|
||||
|
||||
const MANAGE_EMOJIS_AND_STICKERS = 1n << 30n;
|
||||
|
||||
const StickersStore = findStoreLazy("StickersStore");
|
||||
const uploadEmoji = findByCodeLazy('"EMOJI_UPLOAD_START"', "GUILD_EMOJIS(");
|
||||
|
||||
@ -120,7 +118,7 @@ function getGuildCandidates(data: Data) {
|
||||
|
||||
return Object.values(GuildStore.getGuilds()).filter(g => {
|
||||
const canCreate = g.ownerId === meId ||
|
||||
BigInt(PermissionStore.getGuildPermissions({ id: g.id }) & MANAGE_EMOJIS_AND_STICKERS) === MANAGE_EMOJIS_AND_STICKERS;
|
||||
(PermissionStore.getGuildPermissions({ id: g.id }) & PermissionsBits.CREATE_GUILD_EXPRESSIONS) === PermissionsBits.CREATE_GUILD_EXPRESSIONS;
|
||||
if (!canCreate) return false;
|
||||
|
||||
if (data.t === "Sticker") return true;
|
@ -2,5 +2,5 @@
|
||||
|
||||
Puts your favorite emoji first in the emoji autocomplete.
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
Adds a search bar to favorite gifs.
|
||||
|
||||

|
||||

|
||||
|
@ -2,5 +2,5 @@
|
||||
|
||||
Lets you zoom in to images and gifs. Use scroll wheel to zoom in and shift + scroll wheel to increase lens radius / size
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
5
src/plugins/messageClickActions/README.md
Normal file
5
src/plugins/messageClickActions/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# MessageClickActions
|
||||
|
||||
Allows you to double click to edit/reply to a message or delete it if you hold the backspace key
|
||||
|
||||

|
@ -21,18 +21,17 @@ import { definePluginSettings, Settings } from "@api/Settings";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { FluxDispatcher, PermissionStore, UserStore } from "@webpack/common";
|
||||
import { FluxDispatcher, PermissionsBits, PermissionStore, UserStore } from "@webpack/common";
|
||||
|
||||
let isDeletePressed = false;
|
||||
const keydown = (e: KeyboardEvent) => e.key === "Backspace" && (isDeletePressed = true);
|
||||
const keyup = (e: KeyboardEvent) => e.key === "Backspace" && (isDeletePressed = false);
|
||||
|
||||
const MANAGE_CHANNELS = 1n << 4n;
|
||||
|
||||
const settings = definePluginSettings({
|
||||
enableDeleteOnClick: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Enable delete on click",
|
||||
description: "Enable delete on click while holding backspace",
|
||||
default: true
|
||||
},
|
||||
enableDoubleClickToEdit: {
|
||||
@ -72,6 +71,7 @@ export default definePlugin({
|
||||
if (!isDeletePressed) {
|
||||
if (event.detail < 2) return;
|
||||
if (settings.store.requireModifier && !event.ctrlKey && !event.shiftKey) return;
|
||||
if (channel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, channel)) return;
|
||||
|
||||
if (isMe) {
|
||||
if (!settings.store.enableDoubleClickToEdit || EditStore.isEditing(channel.id, msg.id)) return;
|
||||
@ -89,7 +89,7 @@ export default definePlugin({
|
||||
showMentionToggle: channel.guild_id !== null
|
||||
});
|
||||
}
|
||||
} else if (settings.store.enableDeleteOnClick && (isMe || PermissionStore.can(MANAGE_CHANNELS, channel))) {
|
||||
} else if (settings.store.enableDeleteOnClick && (isMe || PermissionStore.can(PermissionsBits.MANAGE_MESSAGES, channel))) {
|
||||
if (msg.deleted) {
|
||||
FluxDispatcher.dispatch({
|
||||
type: "MESSAGE_DELETE",
|
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
|
||||
});
|
||||
}
|
9
src/plugins/permissionFreeWill/README.md
Normal file
9
src/plugins/permissionFreeWill/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# 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.
|
56
src/plugins/permissionFreeWill/index.ts
Normal file
56
src/plugins/permissionFreeWill/index.ts
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
],
|
||||
settings
|
||||
});
|
@ -126,7 +126,7 @@ function MenuItem(guildId: string, id?: string, type?: MenuItemParentType) {
|
||||
|
||||
function makeContextMenuPatch(childId: string | string[], type?: MenuItemParentType): NavContextMenuPatchCallback {
|
||||
return (children, props) => () => {
|
||||
if (!props) return children;
|
||||
if (!props || (type === MenuItemParentType.User && !props.user) || (type === MenuItemParentType.Guild && !props.guild)) return children;
|
||||
|
||||
const group = findGroupChildrenByChildId(childId, children);
|
||||
|
||||
|
@ -2,4 +2,5 @@
|
||||
|
||||
Lets you preview your message before sending it.
|
||||
|
||||

|
||||

|
||||
|
||||
|
5
src/plugins/quickMention/README.md
Normal file
5
src/plugins/quickMention/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# QuickMention
|
||||
|
||||
Adds a mention icon to the messages action bar
|
||||
|
||||

|
@ -20,7 +20,7 @@ import { addButton, removeButton } from "@api/MessagePopover";
|
||||
import { Devs } from "@utils/constants";
|
||||
import { insertTextIntoChatInputBox } from "@utils/discord";
|
||||
import definePlugin from "@utils/types";
|
||||
import { ChannelStore } from "@webpack/common";
|
||||
import { ChannelStore, PermissionsBits, PermissionStore } from "@webpack/common";
|
||||
|
||||
export default definePlugin({
|
||||
name: "QuickMention",
|
||||
@ -30,11 +30,14 @@ export default definePlugin({
|
||||
|
||||
start() {
|
||||
addButton("QuickMention", msg => {
|
||||
const channel = ChannelStore.getChannel(msg.channel_id);
|
||||
if (!PermissionStore.can(PermissionsBits.SEND_MESSAGES, channel)) return null;
|
||||
|
||||
return {
|
||||
label: "Quick Mention",
|
||||
icon: this.Icon,
|
||||
message: msg,
|
||||
channel: ChannelStore.getChannel(msg.channel_id),
|
||||
channel,
|
||||
onClick: () => insertTextIntoChatInputBox(`<@${msg.author.id}> `)
|
||||
};
|
||||
});
|
6
src/plugins/quickReply/README.md
Normal file
6
src/plugins/quickReply/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
# QuickReply
|
||||
|
||||
Reply to (ctrl + up/down) and edit (ctrl + shift + up/down) messages via keybinds
|
||||
|
||||

|
||||
|
@ -20,7 +20,7 @@ import { definePluginSettings, Settings } from "@api/Settings";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { ChannelStore, FluxDispatcher as Dispatcher, MessageStore, SelectedChannelStore, UserStore } from "@webpack/common";
|
||||
import { ChannelStore, FluxDispatcher as Dispatcher, MessageStore, PermissionsBits, PermissionStore, SelectedChannelStore, UserStore } from "@webpack/common";
|
||||
import { Message } from "discord-types/general";
|
||||
|
||||
const Kangaroo = findByPropsLazy("jumpToMessage");
|
||||
@ -172,6 +172,8 @@ function shouldMention(message) {
|
||||
|
||||
// handle next/prev reply
|
||||
function nextReply(isUp: boolean) {
|
||||
const currChannel = ChannelStore.getChannel(SelectedChannelStore.getChannelId());
|
||||
if (currChannel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, currChannel)) return;
|
||||
const message = getNextMessage(isUp, true);
|
||||
|
||||
if (!message)
|
||||
@ -179,7 +181,6 @@ function nextReply(isUp: boolean) {
|
||||
type: "DELETE_PENDING_REPLY",
|
||||
channelId: SelectedChannelStore.getChannelId(),
|
||||
});
|
||||
|
||||
const channel = ChannelStore.getChannel(message.channel_id);
|
||||
const meId = UserStore.getCurrentUser().id;
|
||||
|
||||
@ -196,21 +197,21 @@ function nextReply(isUp: boolean) {
|
||||
|
||||
// handle next/prev edit
|
||||
function nextEdit(isUp: boolean) {
|
||||
const currChannel = ChannelStore.getChannel(SelectedChannelStore.getChannelId());
|
||||
if (currChannel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, currChannel)) return;
|
||||
const message = getNextMessage(isUp, false);
|
||||
|
||||
if (!message)
|
||||
Dispatcher.dispatch({
|
||||
return Dispatcher.dispatch({
|
||||
type: "MESSAGE_END_EDIT",
|
||||
channelId: SelectedChannelStore.getChannelId()
|
||||
});
|
||||
else {
|
||||
Dispatcher.dispatch({
|
||||
type: "MESSAGE_START_EDIT",
|
||||
channelId: message.channel_id,
|
||||
messageId: message.id,
|
||||
content: message.content,
|
||||
_isQuickEdit: true
|
||||
});
|
||||
jumpIfOffScreen(message.channel_id, message.id);
|
||||
}
|
||||
Dispatcher.dispatch({
|
||||
type: "MESSAGE_START_EDIT",
|
||||
channelId: message.channel_id,
|
||||
messageId: message.id,
|
||||
content: message.content,
|
||||
_isQuickEdit: true
|
||||
});
|
||||
jumpIfOffScreen(message.channel_id, message.id);
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { DeleteIcon } from "@components/Icons";
|
||||
import { classes } from "@utils/misc";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { Tooltip } from "@webpack/common";
|
||||
@ -31,10 +32,7 @@ export function DeleteButton({ onClick }: { onClick(): void; }) {
|
||||
className={classes(iconClasses.button, iconClasses.dangerous)}
|
||||
onClick={onClick}
|
||||
>
|
||||
<svg width="16" height="16" viewBox="0 0 20 20">
|
||||
<path fill="currentColor" d="M15 3.999V2H9V3.999H3V5.999H21V3.999H15Z" />
|
||||
<path fill="currentColor" d="M5 6.99902V18.999C5 20.101 5.897 20.999 7 20.999H17C18.103 20.999 19 20.101 19 18.999V6.99902H5ZM11 17H9V11H11V17ZM15 17H13V11H15V17Z" />
|
||||
</svg>
|
||||
<DeleteIcon width="20" height="20" />
|
||||
</div>
|
||||
)}
|
||||
</Tooltip>
|
||||
@ -50,8 +48,11 @@ export function ReportButton({ onClick }: { onClick(): void; }) {
|
||||
className={iconClasses.button}
|
||||
onClick={onClick}
|
||||
>
|
||||
<svg width="16" height="16" viewBox="0 0 20 20">
|
||||
<path fill="currentColor" d="M20,6.002H14V3.002C14,2.45 13.553,2.002 13,2.002H4C3.447,2.002 3,2.45 3,3.002V22.002H5V14.002H10.586L8.293,16.295C8.007,16.581 7.922,17.011 8.076,17.385C8.23,17.759 8.596,18.002 9,18.002H20C20.553,18.002 21,17.554 21,17.002V7.002C21,6.45 20.553,6.002 20,6.002Z" />
|
||||
<svg width="20" height="20" viewBox="0 0 24 24">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M20,6.002H14V3.002C14,2.45 13.553,2.002 13,2.002H4C3.447,2.002 3,2.45 3,3.002V22.002H5V14.002H10.586L8.293,16.295C8.007,16.581 7.922,17.011 8.076,17.385C8.23,17.759 8.596,18.002 9,18.002H20C20.553,18.002 21,17.554 21,17.002V7.002C21,6.45 20.553,6.002 20,6.002Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
)}
|
||||
|
@ -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
|
||||
|
@ -2,4 +2,5 @@
|
||||
|
||||
Adds a reply button to search results.
|
||||
|
||||

|
||||

|
||||
|
||||
|
@ -17,23 +17,22 @@
|
||||
*/
|
||||
|
||||
import { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
|
||||
import { ReplyIcon } from "@components/Icons";
|
||||
import { Devs } from "@utils/constants";
|
||||
import { LazyComponent } from "@utils/react";
|
||||
import definePlugin from "@utils/types";
|
||||
import { findByCode, findByCodeLazy } from "@webpack";
|
||||
import { ChannelStore, i18n, Menu, SelectedChannelStore } from "@webpack/common";
|
||||
import { findByCodeLazy } from "@webpack";
|
||||
import { ChannelStore, i18n, Menu, PermissionsBits, PermissionStore, SelectedChannelStore } from "@webpack/common";
|
||||
import { Message } from "discord-types/general";
|
||||
|
||||
const ReplyIcon = LazyComponent(() => findByCode("M10 8.26667V4L3 11.4667L10 18.9333V14.56C15 14.56 18.5 16.2667 21 20C20 14.6667 17 9.33333 10 8.26667Z"));
|
||||
|
||||
const replyFn = findByCodeLazy("showMentionToggle", "TEXTAREA_FOCUS", "shiftKey");
|
||||
|
||||
const messageContextMenuPatch: NavContextMenuPatchCallback = (children, { message }: { message: Message; }) => () => {
|
||||
// make sure the message is in the selected channel
|
||||
if (SelectedChannelStore.getChannelId() !== message.channel_id) return;
|
||||
|
||||
const channel = ChannelStore.getChannel(message?.channel_id);
|
||||
if (!channel) return;
|
||||
if (channel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, channel)) return;
|
||||
|
||||
// dms and group chats
|
||||
const dmGroup = findGroupChildrenByChildId("pin", children);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user