Compare commits
10 commits
a9dc81e600
...
77084203c6
| Author | SHA1 | Date | |
|---|---|---|---|
| 77084203c6 | |||
|
|
0ce7772500 | ||
|
|
503c90c201 | ||
|
|
db0bcf7da3 | ||
|
|
0e90bda3c7 | ||
|
|
f0fcaf734e | ||
|
|
eafbc0d15a | ||
|
|
2a4314efc9 | ||
|
|
b706d53998 | ||
|
|
76b1fe9a87 |
13 changed files with 167 additions and 100 deletions
|
|
@ -27,7 +27,7 @@ import { openContributorModal } from "@components/PluginSettings/ContributorModa
|
|||
import { Devs } from "@utils/constants";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { Margins } from "@utils/margins";
|
||||
import { isPluginDev } from "@utils/misc";
|
||||
import { shouldShowContributorBadge } from "@utils/misc";
|
||||
import { closeModal, ModalContent, ModalFooter, ModalHeader, ModalRoot, openModal } from "@utils/modal";
|
||||
import definePlugin from "@utils/types";
|
||||
import { Forms, Toasts, UserStore } from "@webpack/common";
|
||||
|
|
@ -39,7 +39,7 @@ const ContributorBadge: ProfileBadge = {
|
|||
description: "Vencord Contributor",
|
||||
image: CONTRIBUTOR_BADGE,
|
||||
position: BadgePosition.START,
|
||||
shouldShow: ({ userId }) => isPluginDev(userId),
|
||||
shouldShow: ({ userId }) => shouldShowContributorBadge(userId),
|
||||
onClick: (_, { userId }) => openContributorModal(UserStore.getUser(userId))
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -72,18 +72,17 @@ export default definePlugin({
|
|||
|
||||
patches: [
|
||||
{
|
||||
find: 'type:"UPLOAD_START"',
|
||||
replacement: {
|
||||
match: /await \i\.uploadFiles\((\i),/,
|
||||
replace: "$1.forEach($self.anonymise),$&"
|
||||
},
|
||||
},
|
||||
{
|
||||
find: 'addFilesTo:"message.attachments"',
|
||||
replacement: {
|
||||
match: /\i.uploadFiles\((\i),/,
|
||||
replace: "$1.forEach($self.anonymise),$&"
|
||||
}
|
||||
find: "async uploadFiles(",
|
||||
replacement: [
|
||||
{
|
||||
match: /async uploadFiles\((\i),\i\){/,
|
||||
replace: "$&$1.forEach($self.anonymise);"
|
||||
},
|
||||
{
|
||||
match: /async uploadFilesSimple\((\i)\){/,
|
||||
replace: "$&$1.forEach($self.anonymise);"
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
find: "#{intl::ATTACHMENT_UTILITIES_SPOILER}",
|
||||
|
|
|
|||
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Vencord, a modification for Discord's desktop app
|
||||
* Copyright (c) 2022 Vendicated, Samu and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { ApplicationCommandInputType, findOption, OptionalMessageOption, RequiredMessageOption, sendBotMessage } from "@api/Commands";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
|
||||
|
||||
function mock(input: string): string {
|
||||
let output = "";
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
output += i % 2 ? input[i].toUpperCase() : input[i].toLowerCase();
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
export default definePlugin({
|
||||
name: "MoreCommands",
|
||||
description: "echo, lenny, mock",
|
||||
authors: [Devs.Arjix, Devs.echo, Devs.Samu],
|
||||
commands: [
|
||||
{
|
||||
name: "echo",
|
||||
description: "Sends a message as Clyde (locally)",
|
||||
options: [OptionalMessageOption],
|
||||
inputType: ApplicationCommandInputType.BOT,
|
||||
execute: (opts, ctx) => {
|
||||
const content = findOption(opts, "message", "");
|
||||
|
||||
sendBotMessage(ctx.channel.id, { content });
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "lenny",
|
||||
description: "Sends a lenny face",
|
||||
options: [OptionalMessageOption],
|
||||
execute: opts => ({
|
||||
content: findOption(opts, "message", "") + " ( ͡° ͜ʖ ͡°)"
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "mock",
|
||||
description: "mOcK PeOpLe",
|
||||
options: [RequiredMessageOption],
|
||||
execute: opts => ({
|
||||
content: mock(findOption(opts, "message", ""))
|
||||
}),
|
||||
},
|
||||
]
|
||||
});
|
||||
|
|
@ -121,14 +121,9 @@ export default definePlugin({
|
|||
},
|
||||
// Make the gap between each item smaller so our tab can fit.
|
||||
{
|
||||
match: /className:\i\.tabBar/,
|
||||
replace: '$& + " vc-mutual-gdms-modal-v2-tab-bar"'
|
||||
match: /type:"top",/,
|
||||
replace: '$&className:"vc-mutual-gdms-modal-v2-tab-bar",'
|
||||
},
|
||||
// Make the tab bar item text smaller so our tab can fit.
|
||||
{
|
||||
match: /(\.tabBarItem.+?variant:)"heading-md\/normal"/,
|
||||
replace: '$1"heading-sm/normal"'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,5 +3,5 @@
|
|||
}
|
||||
|
||||
.vc-mutual-gdms-modal-v2-tab-bar {
|
||||
gap: 12px;
|
||||
--space-xl: 16px;
|
||||
}
|
||||
|
|
|
|||
120
src/plugins/other-usrbg/index.tsx
Normal file
120
src/plugins/other-usrbg/index.tsx
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Vencord, a modification for Discord's desktop app
|
||||
* Copyright (c) 2023 Vendicated and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { Link } from "@components/Link";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
|
||||
const API_URL = "https://usrbg.dorkbutt.lol/users/users.json";
|
||||
|
||||
interface UsrbgApiReturn {
|
||||
endpoint: string;
|
||||
bucket: string;
|
||||
prefix: string;
|
||||
users: Record<string, string>;
|
||||
}
|
||||
|
||||
const settings = definePluginSettings({
|
||||
nitroFirst: {
|
||||
description: "Banner to use if both Nitro and USRBG banners are present",
|
||||
type: OptionType.SELECT,
|
||||
options: [
|
||||
{ label: "Nitro banner", value: true, default: true },
|
||||
{ label: "USRBG banner", value: false },
|
||||
]
|
||||
},
|
||||
voiceBackground: {
|
||||
description: "Use USRBG banners as voice chat backgrounds",
|
||||
type: OptionType.BOOLEAN,
|
||||
default: true,
|
||||
restartNeeded: true
|
||||
}
|
||||
});
|
||||
|
||||
export default definePlugin({
|
||||
name: "FORKED - USRBG",
|
||||
description: "Displays user banners from dorkbutt's USRBG server, allowing anyone to get a banner without Nitro",
|
||||
authors: [Devs.dorkbutt, Devs.AutumnVN, Devs.katlyn, Devs.pylix, Devs.TheKodeToad],
|
||||
settings,
|
||||
patches: [
|
||||
{
|
||||
find: '.banner)==null?"COMPLETE"',
|
||||
replacement: {
|
||||
match: /(?<=void 0:)\i.getPreviewBanner\(\i,\i,\i\)/,
|
||||
replace: "$self.patchBannerUrl(arguments[0])||$&"
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
find: "\"data-selenium-video-tile\":",
|
||||
predicate: () => settings.store.voiceBackground,
|
||||
replacement: [
|
||||
{
|
||||
match: /(?<=function\((\i),\i\)\{)(?=let.{20,40},style:)/,
|
||||
replace: "$1.style=$self.getVoiceBackgroundStyles($1);"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
data: null as UsrbgApiReturn | null,
|
||||
|
||||
settingsAboutComponent: () => {
|
||||
return (
|
||||
"Message @dorkbutt about getting your personal banner added!"
|
||||
);
|
||||
},
|
||||
|
||||
getVoiceBackgroundStyles({ className, participantUserId }: any) {
|
||||
if (className.includes("tile_")) {
|
||||
if (this.userHasBackground(participantUserId)) {
|
||||
return {
|
||||
backgroundImage: `url(${this.getImageUrl(participantUserId)})`,
|
||||
backgroundSize: "cover",
|
||||
backgroundPosition: "center",
|
||||
backgroundRepeat: "no-repeat"
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
patchBannerUrl({ displayProfile }: any) {
|
||||
if (displayProfile?.banner && settings.store.nitroFirst) return;
|
||||
if (this.userHasBackground(displayProfile?.userId)) return this.getImageUrl(displayProfile?.userId);
|
||||
},
|
||||
|
||||
userHasBackground(userId: string) {
|
||||
return !!this.data?.users[userId];
|
||||
},
|
||||
|
||||
getImageUrl(userId: string): string | null {
|
||||
if (!this.userHasBackground(userId)) return null;
|
||||
|
||||
// We can assert that data exists because userHasBackground returned true
|
||||
const { endpoint, bucket, prefix, users: { [userId]: etag } } = this.data!;
|
||||
return `${endpoint}/${bucket}/${prefix}${userId}?${etag}`;
|
||||
},
|
||||
|
||||
async start() {
|
||||
const res = await fetch(API_URL);
|
||||
if (res.ok) {
|
||||
this.data = await res.json();
|
||||
}
|
||||
}
|
||||
});
|
||||
6
src/plugins/other-usrbg/users.json
Normal file
6
src/plugins/other-usrbg/users.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{"endpoint":"https://usrbg.dorkbutt.lol","bucket":"usrbg","prefix":"v2/",
|
||||
"users":{
|
||||
"862105885660676146":"db1d",
|
||||
"578012873813524530":"315c"
|
||||
}
|
||||
}
|
||||
|
|
@ -267,7 +267,7 @@ export default definePlugin({
|
|||
{
|
||||
find: '"MessageManager"',
|
||||
replacement: {
|
||||
match: /"Skipping fetch because channelId is a static route"\);return}(?=.+?getChannel\((\i)\))/,
|
||||
match: /forceFetch:\i,isPreload:.+?}=\i;(?=.+?getChannel\((\i)\))/,
|
||||
replace: (m, channelId) => `${m}if($self.isHiddenChannel({channelId:${channelId}}))return;`
|
||||
}
|
||||
},
|
||||
|
|
@ -494,10 +494,11 @@ export default definePlugin({
|
|||
|
||||
isHiddenChannel(channel: Channel & { channelId?: string; }, checkConnect = false) {
|
||||
try {
|
||||
if (!channel) return false;
|
||||
if (channel == null || Object.hasOwn(channel, "channelId") && channel.channelId == null) return false;
|
||||
|
||||
if (channel.channelId) channel = ChannelStore.getChannel(channel.channelId);
|
||||
if (!channel || channel.isDM() || channel.isGroupDM() || channel.isMultiUserDM()) return false;
|
||||
if (channel.channelId != null) channel = ChannelStore.getChannel(channel.channelId);
|
||||
if (channel == null || channel.isDM() || channel.isGroupDM() || channel.isMultiUserDM()) return false;
|
||||
if (["browse", "customize", "guide"].includes(channel.id)) return false;
|
||||
|
||||
return !PermissionStore.can(PermissionsBits.VIEW_CHANNEL, channel) || checkConnect && !PermissionStore.can(PermissionsBits.CONNECT, channel);
|
||||
} catch (e) {
|
||||
|
|
|
|||
|
|
@ -122,10 +122,16 @@ export default definePlugin({
|
|||
|
||||
{
|
||||
find: "Copy image not supported",
|
||||
replacement: {
|
||||
match: /(?<=(?:canSaveImage|canCopyImage)\(\i?\)\{.{0,50})!\i\.isPlatformEmbedded/g,
|
||||
replace: "false"
|
||||
}
|
||||
replacement: [
|
||||
{
|
||||
match: /(?<=(?:canSaveImage|canCopyImage)\(.{0,120}?)!\i\.isPlatformEmbedded/g,
|
||||
replace: "false"
|
||||
},
|
||||
{
|
||||
match: /canCopyImage\(.+?(?=return"function"==typeof \i\.clipboard\.copyImage)/,
|
||||
replace: "$&return true;"
|
||||
}
|
||||
]
|
||||
},
|
||||
// Add back Copy & Save Image
|
||||
{
|
||||
|
|
@ -137,7 +143,7 @@ export default definePlugin({
|
|||
replace: "false"
|
||||
},
|
||||
{
|
||||
match: /return\s*?\[.{0,50}?(?=\?.{0,100}?id:"copy-image")/,
|
||||
match: /return\s*?\[.{0,50}?(?=\?\(0,\i\.jsxs?.{0,100}?id:"copy-image")/,
|
||||
replace: "return [true"
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ 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 = reactions[key] ??= { fetched: false, users: {} };
|
||||
const cache = reactions[key] ??= { fetched: false, users: new Map() };
|
||||
if (!cache.fetched) {
|
||||
queue.unshift(() => fetchReactions(msg, e, type));
|
||||
cache.fetched = true;
|
||||
|
|
@ -159,7 +159,7 @@ export default definePlugin({
|
|||
}, [message.id, forceUpdate]);
|
||||
|
||||
const reactions = getReactionsWithQueue(message, emoji, type);
|
||||
const users = Object.values(reactions).filter(Boolean) as User[];
|
||||
const users = [...reactions.values()].filter(Boolean);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
@ -187,7 +187,7 @@ export default definePlugin({
|
|||
|
||||
interface ReactionCacheEntry {
|
||||
fetched: boolean;
|
||||
users: Record<string, User>;
|
||||
users: Map<string, User>;
|
||||
}
|
||||
|
||||
interface RootObject {
|
||||
|
|
|
|||
|
|
@ -589,6 +589,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({
|
|||
name: "samsam",
|
||||
id: 836452332387565589n,
|
||||
},
|
||||
Cootshk: {
|
||||
name: "Cootshk",
|
||||
id: 921605971577548820n
|
||||
},
|
||||
} satisfies Record<string, Dev>);
|
||||
|
||||
// iife so #__PURE__ works correctly
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ export function identity<T>(value: T): T {
|
|||
export const isMobile = navigator.userAgent.includes("Mobi");
|
||||
|
||||
export const isPluginDev = (id: string) => Object.hasOwn(DevsById, id);
|
||||
export const shouldShowContributorBadge = (id: string) => isPluginDev(id) && DevsById[id].badge !== false;
|
||||
|
||||
export function pluralise(amount: number, singular: string, plural = singular + "s") {
|
||||
return amount === 1 ? `${amount} ${singular}` : `${amount} ${plural}`;
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ export const UserUtils = {
|
|||
|
||||
export const UploadManager = findByPropsLazy("clearAll", "addFile");
|
||||
export const UploadHandler = {
|
||||
promptToUpload: findByCodeLazy("#{intl::ATTACHMENT_TOO_MANY_ERROR_TITLE}") as (files: File[], channel: Channel, draftType: Number) => void
|
||||
promptToUpload: findByCodeLazy("=!0,showLargeMessageDialog:") as (files: File[], channel: Channel, draftType: Number) => void
|
||||
};
|
||||
|
||||
export const ApplicationAssetUtils = mapMangledModuleLazy("getAssetImage: size must === [", {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue