Merge branch 'dev' into immediate-finds-modules-proxy

This commit is contained in:
Nuckyz 2024-08-23 19:06:45 -03:00
commit fae5f9bfab
No known key found for this signature in database
GPG key ID: 440BF8296E1C4AD9
11 changed files with 110 additions and 33 deletions

View file

@ -5,9 +5,10 @@
*/
import { getCurrentChannel } from "@utils/discord";
import { isObjectEmpty } from "@utils/misc";
import { SelectedChannelStore, Tooltip, useEffect, useStateFromStores } from "@webpack/common";
import { ChannelMemberStore, cl, GuildMemberCountStore, numberFormat } from ".";
import { ChannelMemberStore, cl, GuildMemberCountStore, numberFormat, ThreadMemberListStore } from ".";
import { OnlineMemberCountStore } from "./OnlineMemberCountStore";
export function MemberCount({ isTooltip, tooltipGuildId }: { isTooltip?: true; tooltipGuildId?: string; }) {
@ -30,10 +31,19 @@ export function MemberCount({ isTooltip, tooltipGuildId }: { isTooltip?: true; t
() => ChannelMemberStore.getProps(guildId, currentChannel?.id)
);
const threadGroups = useStateFromStores(
[ThreadMemberListStore],
() => ThreadMemberListStore.getMemberListSections(currentChannel.id)
);
if (!isTooltip && (groups.length >= 1 || groups[0].id !== "unknown")) {
onlineCount = groups.reduce((total, curr) => total + (curr.id === "offline" ? 0 : curr.count), 0);
}
if (!isTooltip && threadGroups && !isObjectEmpty(threadGroups)) {
onlineCount = Object.values(threadGroups).reduce((total, curr) => total + (curr.sectionId === "offline" ? 0 : curr.userIds.length), 0);
}
useEffect(() => {
OnlineMemberCountStore.ensureCount(guildId);
}, [guildId]);

View file

@ -32,6 +32,10 @@ export const GuildMemberCountStore = findStore("GuildMemberCountStore") as FluxS
export const ChannelMemberStore = findStore("ChannelMemberStore") as FluxStore & {
getProps(guildId: string, channelId: string): { groups: { count: number; id: string; }[]; };
};
export const ThreadMemberListStore = findStore("ThreadMemberListStore") as FluxStore & {
getMemberListSections(channelId: string): { [sectionId: string]: { sectionId: string; userIds: string[]; }; };
};
const settings = definePluginSettings({
toolTip: {

View file

@ -0,0 +1,3 @@
# NoMaskedUrlPaste
Pasting a link while you have text selected will NOT paste your link as a masked link.

View file

@ -0,0 +1,23 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2023 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { Devs } from "@utils/constants.js";
import definePlugin from "@utils/types";
export default definePlugin({
name: "NoMaskedUrlPaste",
authors: [Devs.CatNoir],
description: "Pasting a link while having text selected will not paste as masked URL",
patches: [
{
find: ".selection,preventEmojiSurrogates:",
replacement: {
match: /if\(null!=\i.selection&&\i.\i.isExpanded\(\i.selection\)\)/,
replace: "if(false)"
}
}
],
});

View file

@ -19,7 +19,6 @@
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { UserStore } from "@webpack/common";
import virtualMerge from "virtual-merge";
export default definePlugin({
name: "NoProfileThemes",
@ -33,21 +32,7 @@ export default definePlugin({
replace: "$&$self.isCurrentUser(this.userId)&&"
}
},
{
find: "UserProfileStore",
replacement: {
match: /(?<=getUserProfile\(\i\){return )(.+?)(?=})/,
replace: "$self.removeProfileThemes($1)"
}
}
],
isCurrentUser: (userId: string) => userId === UserStore.getCurrentUser()?.id,
removeProfileThemes: (displayProfile: any) => {
if (displayProfile == null) return displayProfile;
return displayProfile.userId === UserStore.getCurrentUser()?.id
? displayProfile
: virtualMerge(displayProfile, { banner: undefined, profileEffectId: undefined });
}
});

View file

@ -26,11 +26,6 @@ import { CompactPronounsChatComponentWrapper, PronounsChatComponentWrapper } fro
import { useProfilePronouns } from "./pronoundbUtils";
import { settings } from "./settings";
const PRONOUN_TOOLTIP_PATCH = {
match: /text:(.{0,10}.Messages\.USER_PROFILE_PRONOUNS)(?=,)/,
replace: '$& + (typeof vcPronounSource !== "undefined" ? ` (${vcPronounSource})` : "")'
};
export default definePlugin({
name: "PronounDB",
authors: [Devs.Tyman, Devs.TheKodeToad, Devs.Ven, Devs.Elvyra],
@ -52,7 +47,24 @@ export default definePlugin({
]
},
// @TODO Patch discord pronoun hook in user profiles (useProfilePronouns)
{
find: ".Messages.USER_PROFILE_PRONOUNS",
group: true,
replacement: [
{
match: /\.PANEL},/,
replace: "$&[vcPronoun,vcPronounSource,vcHasPendingPronouns]=$self.useProfilePronouns(arguments[0].user?.id),"
},
{
match: /text:\i\.\i.Messages.USER_PROFILE_PRONOUNS/,
replace: '$&+vcHasPendingPronouns?"":` (${vcPronounSource})`'
},
{
match: /(\.pronounsText.+?children:)(\i)/,
replace: "$1vcHasPendingPronouns?$2:vcPronoun"
}
]
}
],
settings,

View file

@ -20,13 +20,16 @@ import { debounce } from "@shared/debounce";
import { VENCORD_USER_AGENT } from "@shared/vencordUserAgent";
import { getCurrentChannel } from "@utils/discord";
import { useAwaiter } from "@utils/react";
import { findStore } from "@webpack";
import { UserProfileStore, UserStore } from "@webpack/common";
import { settings } from "./settings";
import { CachePronouns, PronounCode, PronounMapping, PronounsResponse } from "./types";
type PronounsWithSource = [string | null, string];
const EmptyPronouns: PronounsWithSource = [null, ""];
const UserSettingsAccountStore = findStore("UserSettingsAccountStore");
type PronounsWithSource = [pronouns: string | null, source: string, hasPendingPronouns: boolean];
const EmptyPronouns: PronounsWithSource = [null, "", false];
export const enum PronounsFormat {
Lowercase = "LOWERCASE",
@ -74,13 +77,15 @@ export function useFormattedPronouns(id: string, useGlobalProfile: boolean = fal
onError: e => console.error("Fetching pronouns failed: ", e)
});
const hasPendingPronouns = UserSettingsAccountStore.getPendingPronouns() != null;
if (settings.store.pronounSource === PronounSource.PreferDiscord && discordPronouns)
return [discordPronouns, "Discord"];
return [discordPronouns, "Discord", hasPendingPronouns];
if (result && result !== PronounMapping.unspecified)
return [result, "PronounDB"];
return [result, "PronounDB", hasPendingPronouns];
return [discordPronouns, "Discord"];
return [discordPronouns, "Discord", hasPendingPronouns];
}
export function useProfilePronouns(id: string, useGlobalProfile: boolean = false): PronounsWithSource {

View file

@ -79,8 +79,22 @@ export default definePlugin({
{
find: ".BITE_SIZE,user:",
replacement: {
match: /(?<=\.BITE_SIZE,children:\[)\(0,\i\.jsx\)\(\i\.\i,\{user:(\i),/,
replace: "$self.BiteSizeReviewsButton({user:$1}),$&"
match: /{profileType:\i\.\i\.BITE_SIZE,children:\[/,
replace: "$&$self.BiteSizeReviewsButton({user:arguments[0].user}),"
}
},
{
find: ".FULL_SIZE,user:",
replacement: {
match: /{profileType:\i\.\i\.FULL_SIZE,children:\[/,
replace: "$&$self.BiteSizeReviewsButton({user:arguments[0].user}),"
}
},
{
find: ".PANEL,isInteractionSource:",
replacement: {
match: /{profileType:\i\.\i\.PANEL,children:\[/,
replace: "$&$self.BiteSizeReviewsButton({user:arguments[0].user}),"
}
}
],

View file

@ -168,7 +168,7 @@ export default definePlugin({
patches: [
{
find: '"BiteSizeProfileBody"',
find: ".hasAvatarForGuild(null==",
replacement: {
match: /currentUser:\i,guild:\i}\)(?<=user:(\i),bio:null==(\i)\?.+?)/,
replace: "$&,$self.profilePopoutComponent({ user: $1, displayProfile: $2 })"

View file

@ -239,9 +239,26 @@ export interface Constants {
FriendsSections: Record<string, string>;
}
export type ActiveView = LiteralUnion<"emoji" | "gif" | "sticker" | "soundboard", string>;
export interface ExpressionPickerStoreState extends Record<PropertyKey, any> {
activeView: ActiveView | null;
lastActiveView: ActiveView | null;
activeViewType: any | null;
searchQuery: string;
isSearchSuggestion: boolean,
pickerId: string;
}
export interface ExpressionPickerStore {
openExpressionPicker(activeView: ActiveView, activeViewType?: any): void;
closeExpressionPicker(activeViewType?: any): void;
openExpressionPicker(activeView: LiteralUnion<"emoji" | "gif" | "sticker", string>, activeViewType?: any): void;
toggleMultiExpressionPicker(activeViewType?: any): void;
toggleExpressionPicker(activeView: ActiveView, activeViewType?: any): void;
setExpressionPickerView(activeView: ActiveView): void;
setSearchQuery(searchQuery: string, isSearchSuggestion?: boolean): void;
useExpressionPickerStore(): ExpressionPickerStoreState;
useExpressionPickerStore<T>(selector: (state: ExpressionPickerStoreState) => T): T;
}
export interface BrowserWindowFeatures {

View file

@ -149,10 +149,14 @@ export const InviteActions = findByProps("resolveInvite");
export const IconUtils = findByProps<t.IconUtils>("getGuildBannerURL", "getUserAvatarURL");
// TODO: type
export const ExpressionPickerStore: t.ExpressionPickerStore = mapMangledModule("expression-picker-last-active-view", {
openExpressionPicker: filters.byCode(/setState\({activeView:(?:(?!null)\i),activeViewType:/),
closeExpressionPicker: filters.byCode("setState({activeView:null"),
openExpressionPicker: filters.byCode(/setState\({activeView:\i,activeViewType:/),
toggleMultiExpressionPicker: filters.byCode(".EMOJI,"),
toggleExpressionPicker: filters.byCode(/getState\(\)\.activeView===\i\?\i\(\):\i\(/),
setExpressionPickerView: filters.byCode(/setState\({activeView:\i,lastActiveView:/),
setSearchQuery: filters.byCode("searchQuery:"),
useExpressionPickerStore: filters.byCode("Object.is")
});
export const PopoutActions: t.PopoutActions = mapMangledModule('type:"POPOUT_WINDOW_OPEN"', {