Compare commits
12 Commits
feat/telem
...
v1.6.2
Author | SHA1 | Date | |
---|---|---|---|
|
dd61b0c999 | ||
|
5dc0d06be1 | ||
|
9de6c2d4ff | ||
|
e37f62ac0a | ||
|
56a9d79f85 | ||
|
9d78233afa | ||
|
9af2ec65ae | ||
|
584885acf5 | ||
|
18fdc33ee7 | ||
|
522fdcd15d | ||
|
af135b9245 | ||
|
4b958d17fd |
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "vencord",
|
||||
"private": "true",
|
||||
"version": "1.6.1",
|
||||
"version": "1.6.2",
|
||||
"description": "The cutest Discord client mod",
|
||||
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
||||
"bugs": {
|
||||
|
@ -34,7 +34,6 @@ import { patches, PMLogger, startAllPlugins } from "./plugins";
|
||||
import { localStorage } from "./utils/localStorage";
|
||||
import { relaunch } from "./utils/native";
|
||||
import { getCloudSettings, putCloudSettings } from "./utils/settingsSync";
|
||||
import { sendTelemetry } from "./utils/telemetry";
|
||||
import { checkForUpdates, update, UpdateLogger } from "./utils/updater";
|
||||
import { onceReady } from "./webpack";
|
||||
import { SettingsRouter } from "./webpack/common";
|
||||
@ -84,8 +83,6 @@ async function init() {
|
||||
|
||||
syncSettings();
|
||||
|
||||
sendTelemetry();
|
||||
|
||||
if (!IS_WEB) {
|
||||
try {
|
||||
const isOutdated = await checkForUpdates();
|
||||
|
@ -61,8 +61,6 @@ export interface Settings {
|
||||
settingsSync: boolean;
|
||||
settingsSyncVersion: number;
|
||||
};
|
||||
|
||||
telemetry?: boolean; // tri-state, undefined = ask
|
||||
}
|
||||
|
||||
const DefaultSettings: Settings = {
|
||||
@ -93,9 +91,7 @@ const DefaultSettings: Settings = {
|
||||
url: "https://api.vencord.dev/",
|
||||
settingsSync: false,
|
||||
settingsSyncVersion: 0
|
||||
},
|
||||
|
||||
telemetry: undefined
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
|
@ -21,7 +21,6 @@ import { Settings, useSettings } from "@api/Settings";
|
||||
import { classNameFactory } from "@api/Styles";
|
||||
import DonateButton from "@components/DonateButton";
|
||||
import { ErrorCard } from "@components/ErrorCard";
|
||||
import { isMac, isWindows } from "@utils/constants";
|
||||
import { Margins } from "@utils/margins";
|
||||
import { identity } from "@utils/misc";
|
||||
import { relaunch, showItemInFolder } from "@utils/native";
|
||||
@ -47,6 +46,9 @@ function VencordSettings() {
|
||||
|
||||
const donateImage = React.useMemo(() => Math.random() > 0.5 ? DEFAULT_DONATE_IMAGE : SHIGGY_DONATE_IMAGE, []);
|
||||
|
||||
const isWindows = navigator.platform.toLowerCase().startsWith("win");
|
||||
const isMac = navigator.platform.toLowerCase().startsWith("mac");
|
||||
|
||||
const Switches: Array<false | {
|
||||
key: KeysOfType<typeof settings, boolean>;
|
||||
title: string;
|
||||
@ -91,11 +93,6 @@ function VencordSettings() {
|
||||
key: "macosTranslucency",
|
||||
title: "Enable translucent window",
|
||||
note: "Requires a full restart"
|
||||
},
|
||||
{
|
||||
key: "telemetry",
|
||||
title: "Enable Telemetry",
|
||||
note: "We only gather anonymous telemetry data. All data deleted after 3 days if you opt out."
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -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>
|
||||
)
|
||||
|
@ -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
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// This is the parent folder component
|
||||
find: ".MAX_GUILD_FOLDER_NAME_LENGTH,",
|
||||
predicate: () => settings.store.sidebar && settings.store.showFolderIcon !== FolderIconDisplay.Always,
|
||||
replacement: [
|
||||
{
|
||||
match: /(?<=\.Messages\.SERVERS.+?switch\((\i)\.type\){case \i\.\i\.FOLDER:.+?GUILD:)/,
|
||||
replace: 'if((typeof isBetterFolders!=="undefined"?isBetterFolders:false)&&$1.parentId==null)return null;'
|
||||
// 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
|
||||
|
@ -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()
|
||||
});
|
||||
|
@ -19,7 +19,7 @@
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { ErrorCard } from "@components/ErrorCard";
|
||||
import { Devs, isMac } from "@utils/constants";
|
||||
import { Devs } from "@utils/constants";
|
||||
import { Margins } from "@utils/margins";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
@ -96,8 +96,9 @@ export default definePlugin({
|
||||
],
|
||||
|
||||
settingsAboutComponent: () => {
|
||||
const modKey = isMac ? "cmd" : "ctrl";
|
||||
const altKey = isMac ? "opt" : "alt";
|
||||
const isMacOS = navigator.platform.includes("Mac");
|
||||
const modKey = isMacOS ? "cmd" : "ctrl";
|
||||
const altKey = isMacOS ? "opt" : "alt";
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Forms.FormTitle tag="h3">More Information</Forms.FormTitle>
|
||||
|
@ -186,6 +186,13 @@ export default definePlugin({
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
find: ".carouselModal",
|
||||
replacement: {
|
||||
match: /(?<=\.carouselModal.{0,100}onClick:)\i,/,
|
||||
replace: "()=>{},"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
settings,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)) ||
|
||||
|
@ -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>
|
||||
|
@ -137,5 +137,5 @@ export default definePlugin({
|
||||
},
|
||||
],
|
||||
|
||||
previewIcon: ErrorBoundary.wrap(PreviewButton, { noop: true }),
|
||||
chatBarIcon: ErrorBoundary.wrap(PreviewButton, { noop: true }),
|
||||
});
|
||||
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
import { definePluginSettings, Settings } from "@api/Settings";
|
||||
import { Devs, isMac } from "@utils/constants";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { ChannelStore, FluxDispatcher as Dispatcher, MessageStore, PermissionsBits, PermissionStore, SelectedChannelStore, UserStore } from "@webpack/common";
|
||||
@ -25,6 +25,7 @@ import { Message } from "discord-types/general";
|
||||
|
||||
const Kangaroo = findByPropsLazy("jumpToMessage");
|
||||
|
||||
const isMac = navigator.platform.includes("Mac"); // bruh
|
||||
let replyIdx = -1;
|
||||
let editIdx = -1;
|
||||
|
||||
|
@ -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;
|
||||
}
|
@ -389,10 +389,3 @@ export const DevsById = /* #__PURE__*/ (() =>
|
||||
.map(([_, v]) => [v.id, v] as const)
|
||||
))
|
||||
)() as Record<string, Dev>;
|
||||
|
||||
|
||||
const { platform } = navigator;
|
||||
|
||||
export const isWindows = platform.startsWith("Win");
|
||||
export const isMac = platform.startsWith("Mac");
|
||||
export const isLinux = platform.startsWith("Linux");
|
||||
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2023 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { Settings } from "@api/Settings";
|
||||
import { Alerts } from "@webpack/common";
|
||||
|
||||
import { isPluginEnabled } from "../plugins";
|
||||
import { Plugins } from "../Vencord";
|
||||
import { isLinux, isMac, isWindows } from "./constants";
|
||||
|
||||
export function sendTelemetry() {
|
||||
// TODO: READ THIS CHECK BEFORE RELEASING!!
|
||||
// if (IS_DEV) return; // don't send on devbuilds, usually contains incorrect data
|
||||
|
||||
// if we have not yet told the user about the telemetry's existence, or they haven't agreed at all, DON'T send a
|
||||
// probe now, but tell them and then let them decide if they want to opt in or not.
|
||||
if (Settings.telemetry === undefined) {
|
||||
Alerts.show({
|
||||
title: "Telemetry Notice",
|
||||
body: <>
|
||||
<p>
|
||||
Vencord has a telemetry feature that sends anonymous data to us, which we use to improve the mod. We
|
||||
gather your operating system, the version of Vencord you're using and a list of enabled plugins, and
|
||||
we can use this data to help improve it for yourself and everyone else.
|
||||
</p>
|
||||
<p>
|
||||
If you don't want this, that's okay! We haven't sent anything yet. Please decide if you want to allow
|
||||
us to gather a little bit of data. You can change this setting at any time in the future. If you
|
||||
grant consent, we will start sending the data above the next time you reload or restart Discord.
|
||||
</p>
|
||||
</>,
|
||||
confirmText: "Yes, that's fine",
|
||||
cancelText: "No, I don't want that",
|
||||
|
||||
onConfirm() {
|
||||
Settings.telemetry = true;
|
||||
},
|
||||
|
||||
onCancel() {
|
||||
Settings.telemetry = false;
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// if it's disabled in settings, obviously don't do anything
|
||||
if (!Settings.telemetry) return;
|
||||
|
||||
const activePluginsList = Object.keys(Plugins.plugins)
|
||||
.filter(p => isPluginEnabled(p));
|
||||
|
||||
let operatingSystem = "Unknown";
|
||||
|
||||
if (isWindows) operatingSystem = "Windows";
|
||||
else if (isMac) operatingSystem = "macOS";
|
||||
else if (isLinux) operatingSystem = "Linux";
|
||||
|
||||
const data = {
|
||||
version: VERSION,
|
||||
plugins: activePluginsList,
|
||||
operatingSystem
|
||||
};
|
||||
|
||||
navigator.sendBeacon("https://api.vencord.dev/v1/telemetry", JSON.stringify(data));
|
||||
}
|
Reference in New Issue
Block a user