mirror of
https://github.com/Vendicated/Vencord.git
synced 2024-09-20 14:40:34 +00:00
feat: DisplayProfile
This commit is contained in:
parent
79da1d2d59
commit
057cd87114
9 changed files with 102 additions and 39 deletions
|
@ -67,6 +67,7 @@
|
||||||
"no-mixed-spaces-and-tabs": "error",
|
"no-mixed-spaces-and-tabs": "error",
|
||||||
"indent": ["error", 4, { "SwitchCase": 1 }],
|
"indent": ["error", 4, { "SwitchCase": 1 }],
|
||||||
"arrow-parens": ["error", "as-needed"],
|
"arrow-parens": ["error", "as-needed"],
|
||||||
|
"linebreak-style": ["error", "unix"],
|
||||||
"eol-last": ["error", "always"],
|
"eol-last": ["error", "always"],
|
||||||
"@typescript-eslint/func-call-spacing": ["error", "never"],
|
"@typescript-eslint/func-call-spacing": ["error", "never"],
|
||||||
"no-multi-spaces": "error",
|
"no-multi-spaces": "error",
|
||||||
|
|
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
|
@ -9,6 +9,8 @@
|
||||||
"[typescriptreact]": {
|
"[typescriptreact]": {
|
||||||
"editor.defaultFormatter": "vscode.typescript-language-features"
|
"editor.defaultFormatter": "vscode.typescript-language-features"
|
||||||
},
|
},
|
||||||
|
"files.eol": "\n",
|
||||||
|
"files.insertFinalNewline": true,
|
||||||
"javascript.format.semicolons": "insert",
|
"javascript.format.semicolons": "insert",
|
||||||
"typescript.format.semicolons": "insert",
|
"typescript.format.semicolons": "insert",
|
||||||
"typescript.preferences.quoteStyle": "double",
|
"typescript.preferences.quoteStyle": "double",
|
||||||
|
|
|
@ -448,6 +448,11 @@ export default {
|
||||||
type: "class",
|
type: "class",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"./general/DisplayProfile.ts": {
|
||||||
|
DisplayProfile: {
|
||||||
|
type: "class",
|
||||||
|
},
|
||||||
|
},
|
||||||
"./general/Draft.ts": {
|
"./general/Draft.ts": {
|
||||||
DraftType: {
|
DraftType: {
|
||||||
type: "enum",
|
type: "enum",
|
||||||
|
|
67
packages/discord-types/src/general/DisplayProfile.ts
Normal file
67
packages/discord-types/src/general/DisplayProfile.ts
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* discord-types
|
||||||
|
* Copyright (C) 2024 Vencord project contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { Nullish, OptionalTuple } from "../internal";
|
||||||
|
import type { GuildMemberProfile } from "./GuildMemberProfile";
|
||||||
|
import type { ProfileBadge, ProfileThemeColors, UserProfile } from "./UserProfile";
|
||||||
|
|
||||||
|
export declare class DisplayProfile<
|
||||||
|
FetchFailed extends boolean = boolean,
|
||||||
|
Guild extends boolean = boolean
|
||||||
|
> {
|
||||||
|
constructor(
|
||||||
|
userProfile: UserProfile<FetchFailed>,
|
||||||
|
...guildMemberProfile: Guild extends true
|
||||||
|
? [guildMemberProfile: GuildMemberProfile]
|
||||||
|
: [guildMemberProfile?: Nullish]
|
||||||
|
);
|
||||||
|
|
||||||
|
get application(): UserProfile["application"];
|
||||||
|
get canEditThemes(): boolean;
|
||||||
|
get canUsePremiumProfileCustomization(): boolean;
|
||||||
|
getBadges(): ProfileBadge[];
|
||||||
|
getBannerURL(options: {
|
||||||
|
canAnimate?: boolean | undefined /* = false */;
|
||||||
|
size: number;
|
||||||
|
}): string | undefined;
|
||||||
|
getLegacyUsername(): UserProfile<FetchFailed>["legacyUsername"];
|
||||||
|
getPreviewBanner(
|
||||||
|
previewBanner?: string | Nullish,
|
||||||
|
canAnimate?: boolean | undefined,
|
||||||
|
size?: number | undefined /* = 480 */
|
||||||
|
): string | Nullish;
|
||||||
|
getPreviewBio(previewBio?: string | Nullish): (true extends Guild ? boolean : false) extends infer GuildValue
|
||||||
|
? GuildValue extends true
|
||||||
|
? { isUsingGuildValue: true; value: string; }
|
||||||
|
: { isUsingGuildValue: false; value: string | undefined; }
|
||||||
|
: never;
|
||||||
|
getPreviewThemeColors(
|
||||||
|
previewThemeColors?: OptionalTuple<ProfileThemeColors, Nullish> | Nullish
|
||||||
|
): UserProfile["themeColors"];
|
||||||
|
hasFullProfile(): boolean;
|
||||||
|
hasPremiumCustomization(): boolean;
|
||||||
|
hasThemeColors(): boolean;
|
||||||
|
isUsingGuildMemberBanner(): true extends Guild ? boolean : false;
|
||||||
|
isUsingGuildMemberBio(): true extends Guild ? boolean : false;
|
||||||
|
isUsingGuildMemberPronouns(): true extends Guild ? boolean : false;
|
||||||
|
get premiumGuildSince(): UserProfile<FetchFailed>["premiumGuildSince"];
|
||||||
|
get premiumSince(): UserProfile<FetchFailed>["premiumSince"];
|
||||||
|
get premiumType(): UserProfile<FetchFailed>["premiumType"];
|
||||||
|
get primaryColor(): UserProfile["accentColor"];
|
||||||
|
|
||||||
|
_guildMemberProfile: Guild extends true ? GuildMemberProfile : Nullish;
|
||||||
|
_userProfile: UserProfile<FetchFailed>;
|
||||||
|
accentColor: UserProfile<FetchFailed>["accentColor"];
|
||||||
|
banner: UserProfile["banner"];
|
||||||
|
bio: UserProfile["bio"];
|
||||||
|
guildId: Guild extends true ? string : undefined;
|
||||||
|
/** @todo Does not seem to be implemented. */
|
||||||
|
popoutAnimationParticleType: UserProfile["popoutAnimationParticleType"];
|
||||||
|
profileEffectId: UserProfile<FetchFailed>["profileEffectId"];
|
||||||
|
pronouns: UserProfile<FetchFailed>["pronouns"];
|
||||||
|
themeColors: UserProfile["themeColors"];
|
||||||
|
userId: UserProfile<FetchFailed>["userId"];
|
||||||
|
}
|
|
@ -38,15 +38,25 @@ export interface UserProfileFetchFailed {
|
||||||
accentColor: null;
|
accentColor: null;
|
||||||
application: null;
|
application: null;
|
||||||
applicationRoleConnections: [];
|
applicationRoleConnections: [];
|
||||||
|
/** Never present if fetch failed. */
|
||||||
|
badges?: undefined;
|
||||||
banner: null;
|
banner: null;
|
||||||
bio: "";
|
bio: "";
|
||||||
connectedAccounts: [];
|
connectedAccounts: [];
|
||||||
lastFetched: number;
|
lastFetched: number;
|
||||||
legacyUsername: null;
|
legacyUsername: null;
|
||||||
|
/** Never present if fetch failed. */
|
||||||
|
popoutAnimationParticleType?: undefined;
|
||||||
premiumGuildSince: null;
|
premiumGuildSince: null;
|
||||||
premiumSince: null;
|
premiumSince: null;
|
||||||
|
/** Never present if fetch failed. */
|
||||||
|
premiumType?: undefined;
|
||||||
|
/** Never present if fetch failed. */
|
||||||
|
profileEffectId?: undefined;
|
||||||
profileFetchFailed: true;
|
profileFetchFailed: true;
|
||||||
pronouns: "";
|
pronouns: "";
|
||||||
|
/** Never present if fetch failed. */
|
||||||
|
themeColors?: undefined;
|
||||||
userId: string;
|
userId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ export * from "./ApplicationRecord";
|
||||||
export * from "./channels";
|
export * from "./channels";
|
||||||
export * from "./Clan";
|
export * from "./Clan";
|
||||||
export * from "./CompanyRecord";
|
export * from "./CompanyRecord";
|
||||||
|
export * from "./DisplayProfile";
|
||||||
export * from "./Draft";
|
export * from "./Draft";
|
||||||
export * from "./emojis";
|
export * from "./emojis";
|
||||||
export * from "./Frecency";
|
export * from "./Frecency";
|
||||||
|
|
|
@ -37,6 +37,10 @@ export type Optional<T, Value = undefined, Keys extends keyof T = keyof T, Exclu
|
||||||
? Pick<T, Keys> & { [Key in Exclude<keyof T, Keys>]?: T[Key] | Value; }
|
? Pick<T, Keys> & { [Key in Exclude<keyof T, Keys>]?: T[Key] | Value; }
|
||||||
: Omit<T, Keys> & { [Key in Keys]?: T[Key] | Value; };
|
: Omit<T, Keys> & { [Key in Keys]?: T[Key] | Value; };
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export type OptionalTuple<T extends unknown[], Value = undefined>
|
||||||
|
= { [Key in keyof T]?: T[Key] | Value; };
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export type PartialOnUndefined<T>
|
export type PartialOnUndefined<T>
|
||||||
= { [Key in keyof T as undefined extends T[Key] ? never : Key]: T[Key]; }
|
= { [Key in keyof T as undefined extends T[Key] ? never : Key]: T[Key]; }
|
||||||
|
|
48
src/webpack/common/types/utils.d.ts
vendored
48
src/webpack/common/types/utils.d.ts
vendored
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { GuildMember, GuildRecord, UserRecord } from "@vencord/discord-types";
|
import type { DisplayProfile, GuildMember, GuildRecord, UserProfileStore, UserRecord, UserStore } from "@vencord/discord-types";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import type { LiteralUnion } from "type-fest";
|
import type { LiteralUnion } from "type-fest";
|
||||||
|
|
||||||
|
@ -139,6 +139,7 @@ export interface Constants {
|
||||||
FriendsSections: Record<string, string>;
|
FriendsSections: Record<string, string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// zustand store
|
||||||
export interface ExpressionPickerStore {
|
export interface ExpressionPickerStore {
|
||||||
closeExpressionPicker(activeViewType?: any): void;
|
closeExpressionPicker(activeViewType?: any): void;
|
||||||
openExpressionPicker(activeView: LiteralUnion<"emoji" | "gif" | "sticker", string>, activeViewType?: any): void;
|
openExpressionPicker(activeView: LiteralUnion<"emoji" | "gif" | "sticker", string>, activeViewType?: any): void;
|
||||||
|
@ -197,41 +198,14 @@ export interface UserUtils {
|
||||||
humanizeStatus: any;
|
humanizeStatus: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DisplayProfile {
|
|
||||||
userId: string;
|
|
||||||
banner?: string;
|
|
||||||
bio?: string;
|
|
||||||
pronouns?: string;
|
|
||||||
accentColor?: number;
|
|
||||||
themeColors?: number[];
|
|
||||||
popoutAnimationParticleType?: any;
|
|
||||||
profileEffectId?: string;
|
|
||||||
_userProfile?: any;
|
|
||||||
_guildMemberProfile?: any;
|
|
||||||
canUsePremiumProfileCustomization: boolean;
|
|
||||||
canEditThemes: boolean;
|
|
||||||
premiumGuildSince: Date | null;
|
|
||||||
premiumSince: Date | null;
|
|
||||||
premiumType?: number;
|
|
||||||
primaryColor?: number;
|
|
||||||
|
|
||||||
getBadges(): {
|
|
||||||
id: string;
|
|
||||||
description: string;
|
|
||||||
icon: string;
|
|
||||||
link?: string;
|
|
||||||
}[];
|
|
||||||
getBannerURL(options: { canAnimate: boolean; size: number; }): string;
|
|
||||||
getLegacyUsername(): string | null;
|
|
||||||
hasFullProfile(): boolean;
|
|
||||||
hasPremiumCustomization(): boolean;
|
|
||||||
hasThemeColors(): boolean;
|
|
||||||
isUsingGuildMemberBanner(): boolean;
|
|
||||||
isUsingGuildMemberBio(): boolean;
|
|
||||||
isUsingGuildMemberPronouns(): boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DisplayProfileUtils {
|
export interface DisplayProfileUtils {
|
||||||
getDisplayProfile(userId: string, guildId?: string, customStores?: any): DisplayProfile | null;
|
getDisplayProfile(
|
||||||
useDisplayProfile(userId: string, guildId?: string, customStores?: any): DisplayProfile | null;
|
userId: string,
|
||||||
|
guildId?: string | null | undefined,
|
||||||
|
stores?: [
|
||||||
|
Pick<UserStore, "getUser">,
|
||||||
|
Pick<UserProfileStore, "getUserProfile" | "getGuildMemberProfile">
|
||||||
|
] | undefined /* = [UserStore, UserProfileStore] */
|
||||||
|
): DisplayProfile | null;
|
||||||
|
useDisplayProfile(userId: string, guildId?: string | null | undefined): DisplayProfile | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,9 +130,8 @@ export const DisplayProfileUtils: t.DisplayProfileUtils = mapMangledModuleLazy(/
|
||||||
|
|
||||||
const openExpressionPickerMatcher = canonicalizeMatch(/setState\({activeView:\i,activeViewType:/);
|
const openExpressionPickerMatcher = canonicalizeMatch(/setState\({activeView:\i,activeViewType:/);
|
||||||
|
|
||||||
// TODO: type
|
|
||||||
// zustand store
|
// zustand store
|
||||||
export const ExpressionPickerStore = mapMangledModuleLazy("expression-picker-last-active-view", {
|
export const ExpressionPickerStore: t.ExpressionPickerStore = mapMangledModuleLazy("expression-picker-last-active-view", {
|
||||||
closeExpressionPicker: filters.byCode("setState({activeView:null"),
|
closeExpressionPicker: filters.byCode("setState({activeView:null"),
|
||||||
openExpressionPicker: m => typeof m === "function" && openExpressionPickerMatcher.test(m.toString()),
|
openExpressionPicker: m => typeof m === "function" && openExpressionPickerMatcher.test(m.toString()),
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue