diff --git a/packages/discord-types/enums/misc.ts b/packages/discord-types/enums/misc.ts index 60b2298a0..81a6e41ca 100644 --- a/packages/discord-types/enums/misc.ts +++ b/packages/discord-types/enums/misc.ts @@ -12,6 +12,7 @@ export const enum DraftType { SlashCommand = 5, ForwardContextMessage = 6, InteractionModal = 7, + ScheduledMessage = 8, } export const enum EmojiIntention { diff --git a/packages/discord-types/src/stores/AccessibilityStore.d.ts b/packages/discord-types/src/stores/AccessibilityStore.d.ts index cf0248962..2de798992 100644 --- a/packages/discord-types/src/stores/AccessibilityStore.d.ts +++ b/packages/discord-types/src/stores/AccessibilityStore.d.ts @@ -5,6 +5,7 @@ export type ForcedColorsPreference = "none" | "active"; export type ContrastPreference = "no-preference" | "more" | "less" | "custom"; export type RoleStyle = "username" | "dot" | "hidden"; export type ContrastMode = "default" | "high"; +export type YouBarAnimationPreference = "animate-never" | "animate-always" | "respect-motion-settings"; export interface AccessibilityState { fontSize: number; @@ -32,6 +33,15 @@ export interface AccessibilityState { syncProfileThemeWithUserTheme: boolean; enableCustomCursor: boolean; switchIconsEnabled: boolean; + officialMessageStyle: string; + expressionPickerFormat: string; + condensePickerWhenNarrow: boolean; + appsButtonEnabled: boolean; + emojiButtonEnabled: boolean; + gifButtonEnabled: boolean; + stickerButtonEnabled: boolean; + youBarNameplateAnimation: YouBarAnimationPreference; + youBarAvatarDecoAnimation: YouBarAnimationPreference; } export class AccessibilityStore extends FluxStore { @@ -55,6 +65,17 @@ export class AccessibilityStore extends FluxStore { get isMessageGroupSpacingIncreased(): boolean; get isMessageGroupSpacingDecreased(): boolean; get isSubmitButtonEnabled(): boolean; + get isAppsButtonEnabled(): boolean; + get isEmojiButtonEnabled(): boolean; + get isGifButtonEnabled(): boolean; + get isStickerButtonEnabled(): boolean; + get officialMessageStyle(): string; + get expressionPickerFormat(): string; + get condensePickerWhenNarrow(): boolean; + get youBarNameplateAnimation(): YouBarAnimationPreference; + get youBarAvatarDecoAnimation(): YouBarAnimationPreference; + get animateYouBarNameplate(): boolean; + get animateYouBarAvatarDeco(): boolean; get syncProfileThemeWithUserTheme(): boolean; get systemPrefersReducedMotion(): ReducedMotionPreference; get rawPrefersReducedMotion(): ReducedMotionPreference; diff --git a/packages/discord-types/src/stores/ApplicationStore.d.ts b/packages/discord-types/src/stores/ApplicationStore.d.ts index 165f468b0..3bed89d2c 100644 --- a/packages/discord-types/src/stores/ApplicationStore.d.ts +++ b/packages/discord-types/src/stores/ApplicationStore.d.ts @@ -5,6 +5,11 @@ export interface ApplicationStoreState { botUserIdToAppUsage: Record; } +export interface GuildEmbeddedApplication { + applicationId: string; + status: unknown; +} + export interface ApplicationUsage { applicationId: string; lastUsedMs: number; @@ -13,13 +18,15 @@ export interface ApplicationUsage { export class ApplicationStore extends FluxStore { _getAllApplications(): Application[]; getState(): ApplicationStoreState; - getApplication(applicationId: string): Application; + getApplication(applicationId: string): Application | undefined; getApplicationByName(name: string): Application | undefined; getApplicationLastUpdated(applicationId: string): number | undefined; getGuildApplication(guildId: string, type: ApplicationType): Application | undefined; getGuildApplicationIds(guildId: string): string[]; + getGuildEmbeddedApplications(guildId: string, surface: string): GuildEmbeddedApplication[] | undefined; getAppIdForBotUserId(botUserId: string): string | undefined; getFetchingOrFailedFetchingIds(): string[]; isFetchingApplication(applicationId: string): boolean; + isHydrated(applicationId: string): boolean; didFetchingApplicationFail(applicationId: string): boolean; } diff --git a/packages/discord-types/src/stores/ApplicationStreamPreviewStore.d.ts b/packages/discord-types/src/stores/ApplicationStreamPreviewStore.d.ts index cddb63f9c..beb0da41b 100644 --- a/packages/discord-types/src/stores/ApplicationStreamPreviewStore.d.ts +++ b/packages/discord-types/src/stores/ApplicationStreamPreviewStore.d.ts @@ -2,6 +2,7 @@ import { FluxStore } from ".."; export interface ApplicationStreamPreviewStore extends FluxStore { getIsPreviewLoading: (guildId: string | bigint | null, channelId: string | bigint, ownerId: string | bigint) => boolean; - getPreviewURL: (guildId: string | bigint | null, channelId: string | bigint, ownerId: string | bigint) => Promise; + getPreviewURL: (guildId: string | bigint | null, channelId: string | bigint, ownerId: string | bigint) => string | undefined; getPreviewURLForStreamKey: (streamKey: string) => ReturnType; + shouldFetchPreview: (guildId: string | bigint | null, channelId: string | bigint, ownerId: string | bigint) => boolean; } diff --git a/packages/discord-types/src/stores/ApplicationStreamingStore.d.ts b/packages/discord-types/src/stores/ApplicationStreamingStore.d.ts index a764d1467..86da099c2 100644 --- a/packages/discord-types/src/stores/ApplicationStreamingStore.d.ts +++ b/packages/discord-types/src/stores/ApplicationStreamingStore.d.ts @@ -10,6 +10,9 @@ export interface StreamMetadata { id: string | null, pid: number | null, sourceName: string | null; + previewDisabled?: boolean; + sourceIcon?: string | null; + sourceId?: string | null; } export interface StreamingStoreState { @@ -28,12 +31,18 @@ export interface ApplicationStreamingStore extends FluxStore { getAllApplicationStreamsForChannel: (channelId: string | bigint) => ApplicationStream[]; getAllActiveStreamsForChannel: (channelId: string | bigint) => Stream[]; getAnyStreamForUser: (userId: string | bigint) => Stream | ApplicationStream | null; + getAnyDiscoverableStreamForUser: (userId: string | bigint) => ApplicationStream | null; getStreamForUser: (userId: string | bigint, guildId?: string | bigint | null) => Stream | null; getCurrentUserActiveStream: () => Stream | null; getLastActiveStream: () => Stream | null; getState: () => StreamingStoreState; getRTCStream: (streamKey: string) => RTCStream | null; - getStreamerActiveStreamMetadata: () => StreamMetadata; - getViewerIds: (stream: ApplicationStream) => string[]; + getStreamerActiveStreamMetadata: () => StreamMetadata | null; + getStreamerActiveStreamMetadataForStream: (streamKey: string) => StreamMetadata | null; + getIsActiveStreamPreviewDisabled: (streamKey: string) => boolean; + getCurrentAppIntent: () => unknown; + getStreamingState: () => Omit & { activeStreams: [string, Stream][]; }; + isStreamMarkedFull: (streamKey: string) => boolean; + getViewerIds: (stream: ApplicationStream | string) => string[]; isSelfStreamHidden: (channelId: string | bigint | null) => boolean; } diff --git a/packages/discord-types/src/stores/AuthorizedAppsStore.d.ts b/packages/discord-types/src/stores/AuthorizedAppsStore.d.ts new file mode 100644 index 000000000..f44711768 --- /dev/null +++ b/packages/discord-types/src/stores/AuthorizedAppsStore.d.ts @@ -0,0 +1,18 @@ +import { FluxStore } from ".."; + +export interface AuthorizedAppToken { + id: string; + application: { id: string; parent_id?: string | null;[key: string]: unknown; }; + scopes: string[]; +} + +export type AuthorizedAppsFetchState = "NOT_FETCHED" | "FETCHING" | "FETCHED"; + +export class AuthorizedAppsStore extends FluxStore { + getNewestTokenForApplication(applicationId: string): AuthorizedAppToken | null; + getNewestTokens(): AuthorizedAppToken[]; + getNewestTokensForNonChildrenApplications(): AuthorizedAppToken[]; + getFetchState(): AuthorizedAppsFetchState; + getFetchStateForApplication(applicationId: string): AuthorizedAppsFetchState; + getApplicationFetchStateVersion(): number; +} diff --git a/packages/discord-types/src/stores/ChannelMemberStore.d.ts b/packages/discord-types/src/stores/ChannelMemberStore.d.ts new file mode 100644 index 000000000..8d9a23959 --- /dev/null +++ b/packages/discord-types/src/stores/ChannelMemberStore.d.ts @@ -0,0 +1,18 @@ +import { FluxStore } from ".."; + +export interface ChannelMemberGroup { + count: number; + id: string; +} + +export interface ChannelMemberProps { + listId: string; + groups: ChannelMemberGroup[]; + rows: unknown[]; + version: number; +} + +export class ChannelMemberStore extends FluxStore { + getProps(guildId?: string, channelId?: string): ChannelMemberProps; + getRows(guildId?: string, channelId?: string): ChannelMemberProps["rows"]; +} diff --git a/packages/discord-types/src/stores/ChannelRTCStore.d.ts b/packages/discord-types/src/stores/ChannelRTCStore.d.ts index 0c8271581..fea3c0aee 100644 --- a/packages/discord-types/src/stores/ChannelRTCStore.d.ts +++ b/packages/discord-types/src/stores/ChannelRTCStore.d.ts @@ -78,15 +78,14 @@ export interface ChannelRTCState { export class ChannelRTCStore extends FluxStore { getActivityParticipants(channelId: string): ActivityParticipant[]; - getAllChatOpen(): Record; getChatOpen(channelId: string): boolean; getFilteredParticipants(channelId: string): Participant[]; getGuildRingingUsers(channelId: string): Set; getLayout(channelId: string, context?: RTCLayoutContext): RTCLayout; getMode(channelId: string): RTCMode; + getOpenChatChannelIds(): Set; getParticipant(channelId: string, participantId: string): Participant | null; getParticipants(channelId: string): Participant[]; - getParticipantsListOpen(channelId: string): boolean; getParticipantsOpen(channelId: string): boolean; getParticipantsVersion(channelId: string): number; getSelectedParticipant(channelId: string): Participant | null; diff --git a/packages/discord-types/src/stores/ChannelSectionStore.d.ts b/packages/discord-types/src/stores/ChannelSectionStore.d.ts new file mode 100644 index 000000000..2ce2996a3 --- /dev/null +++ b/packages/discord-types/src/stores/ChannelSectionStore.d.ts @@ -0,0 +1,13 @@ +import { FluxStore } from ".."; + +export type ChannelSection = "SEARCH" | "SIDEBAR_CHAT" | "FRIENDS" | "PROFILE" | "SUMMARIES" | "MEMBERS" | "CONVERSATIONS" | "NONE"; + +export class ChannelSectionStore extends FluxStore { + getSection(channelId: string, isProfile?: boolean): ChannelSection; + isFriendsSidebarAvailable(): boolean; + getCurrentSidebarChannelId(channelId: string): string | null; + getCurrentSidebarMessageId(channelId: string): string | null | undefined; + getCurrentSearchContextId(): string | null; + getGuildSidebarState(guildId?: string): unknown; + getSidebarState(channelId?: string): unknown; +} diff --git a/packages/discord-types/src/stores/ClientThemesBackgroundStore.d.ts b/packages/discord-types/src/stores/ClientThemesBackgroundStore.d.ts new file mode 100644 index 000000000..666f4c28b --- /dev/null +++ b/packages/discord-types/src/stores/ClientThemesBackgroundStore.d.ts @@ -0,0 +1,14 @@ +import { FluxStore } from ".."; + +export interface GradientPreset { + id: number; + [key: string]: unknown; +} + +export class ClientThemesBackgroundStore extends FluxStore { + get gradientPreset(): GradientPreset | undefined; + get isPreview(): boolean; + get isCoachmark(): boolean; + get mobilePendingThemeIndex(): number | undefined; + getLinearGradient(): string | null; +} diff --git a/packages/discord-types/src/stores/CollapsedVoiceChannelStore.d.ts b/packages/discord-types/src/stores/CollapsedVoiceChannelStore.d.ts new file mode 100644 index 000000000..086a74fc4 --- /dev/null +++ b/packages/discord-types/src/stores/CollapsedVoiceChannelStore.d.ts @@ -0,0 +1,6 @@ +import { FluxStore } from ".."; + +export class CollapsedVoiceChannelStore extends FluxStore { + getCollapsed(): Record; + isCollapsed(channelId: string): boolean; +} diff --git a/packages/discord-types/src/stores/ConnectedAccountsStore.d.ts b/packages/discord-types/src/stores/ConnectedAccountsStore.d.ts new file mode 100644 index 000000000..e5d5a6e13 --- /dev/null +++ b/packages/discord-types/src/stores/ConnectedAccountsStore.d.ts @@ -0,0 +1,15 @@ +import { ConnectedAccount, FluxStore } from ".."; + +export class ConnectedAccountsStore extends FluxStore { + getAccounts(): ConnectedAccount[]; + getLocalAccounts(): ConnectedAccount[]; + getAccount(accountId: string | null | undefined, type: string): ConnectedAccount | undefined; + getLocalAccount(type: string): ConnectedAccount | undefined; + isFetching(): boolean; + isJoining(integrationId: string): boolean; + joinErrorMessage(integrationId: string): string | undefined; + isSuggestedAccountType(type: string): boolean; + addPendingAuthorizedState(state: string): void; + deletePendingAuthorizedState(state: string): void; + hasPendingAuthorizedState(state: string): boolean; +} diff --git a/packages/discord-types/src/stores/DraftStore.d.ts b/packages/discord-types/src/stores/DraftStore.d.ts index 89d50c43c..199f2c9c9 100644 --- a/packages/discord-types/src/stores/DraftStore.d.ts +++ b/packages/discord-types/src/stores/DraftStore.d.ts @@ -1,9 +1,10 @@ -import { FluxStore } from ".."; +import { Command, FluxStore } from ".."; import { DraftType } from "../../enums"; export interface Draft { timestamp: number; draft: string; + command?: Command; } export interface ThreadSettingsDraft { @@ -15,10 +16,16 @@ export interface ThreadSettingsDraft { location?: string; } +export interface ScheduledMessageDraft { + timestamp: number; + [key: string]: unknown; +} + export type ChannelDrafts = { [DraftType.ThreadSettings]: ThreadSettingsDraft; + [DraftType.ScheduledMessage]: ScheduledMessageDraft; } & { - [key in Exclude]: Draft; + [key in Exclude]: Draft; }; export type UserDrafts = Partial>; @@ -28,6 +35,8 @@ export class DraftStore extends FluxStore { getState(): DraftState; getRecentlyEditedDrafts(type: DraftType): Array; getDraft(channelId: string, type: DraftType): string; + getDraftCommand(channelId: string, type: DraftType): Command | undefined; + getScheduledMessage(channelId: string): ScheduledMessageDraft | undefined; getThreadSettings(channelId: string): ThreadSettingsDraft | null | undefined; getThreadDraftWithParentMessageId(parentMessageId: string): ThreadSettingsDraft | null | undefined; diff --git a/packages/discord-types/src/stores/EmojiStore.d.ts b/packages/discord-types/src/stores/EmojiStore.d.ts index f22a70a13..851ee789f 100644 --- a/packages/discord-types/src/stores/EmojiStore.d.ts +++ b/packages/discord-types/src/stores/EmojiStore.d.ts @@ -412,6 +412,11 @@ export class EmojiStore extends FluxStore { * @returns Array of usable custom emojis. */ getUsableGuildEmoji(guildId?: string | null): CustomEmoji[]; + /** + * Gets ids of custom emojis hidden in a guild. + * @param guildId Guild id to get hidden emoji ids for. + */ + getHiddenEmojiIds(guildId?: string | null): Set; /** * Gets newly added emojis for a guild. * @param guildId Guild id to get emojis for. @@ -446,8 +451,15 @@ export class EmojiStore extends FluxStore { * @returns True if user has usable emojis. */ hasUsableEmojiInAnyGuild(): boolean; - /** Internal method for ordering search results. */ - getSearchResultsOrder(...args: any[]): any; + /** + * Orders emoji search results by match quality and frecency. + * @param emojis Emojis to order. + * @param query Search query. + * @param count Max results, 0 for no limit. + * @param intention Where the emoji will be used, picks reaction or chat frecency. + * @returns Ordered emojis. + */ + getSearchResultsOrder(emojis: T[], query: string, count: number, intention: EmojiIntention): T[]; /** * Gets the serializable state for persistence. * @returns Current store state. diff --git a/packages/discord-types/src/stores/ExperimentStore.d.ts b/packages/discord-types/src/stores/ExperimentStore.d.ts index 27152dc02..1a42c38e0 100644 --- a/packages/discord-types/src/stores/ExperimentStore.d.ts +++ b/packages/discord-types/src/stores/ExperimentStore.d.ts @@ -63,6 +63,25 @@ interface TrackedExposures { [key: GuildExposureKey]: ExperimentExposureEntry; } +interface ExperimentExposureDescriptor { + type: "user" | "guild"; + bucket: number; + revision: number; + guildId?: string; + triggerDebuggingEnabled?: boolean; +} + +interface TrackExposureOptions { + experimentId: string; + descriptor: (UserExperimentAssignment | GuildExperimentAssignment) & ExperimentExposureDescriptor; + location?: string; + location_stack?: string[]; + context?: { guildId?: string; }; + fingerprint?: string; + excluded?: boolean; + exposureType?: string; +} + interface ExperimentState { assignmentFingerprint: string | null; assignmentSessionId: string; @@ -94,8 +113,9 @@ export class ExperimentStore extends FluxStore { getUserExperimentDescriptor(experimentId: string): ExperimentAssignmentOverride; hasRegisteredExperiment(experimentId: string): boolean; - // has two args - getRecentExposures(): unknown; - // has four args - hasExperimentTrackedExposure(): unknown; + trackExposure: (options: TrackExposureOptions) => false | void; + getRecentExposures(type: "user" | "guild", experimentId: string): [string, number][]; + hasExperimentTrackedExposure(experimentId: string, descriptor: ExperimentExposureDescriptor, location?: string, triggerDebugging?: boolean): boolean; + loadCache(): void; + takeSnapshot(): { version: number; data: Record; }; } diff --git a/packages/discord-types/src/stores/FriendsStore.d.ts b/packages/discord-types/src/stores/FriendsStore.d.ts index 4a1d1c71e..d11c1f5a4 100644 --- a/packages/discord-types/src/stores/FriendsStore.d.ts +++ b/packages/discord-types/src/stores/FriendsStore.d.ts @@ -66,4 +66,5 @@ export interface FriendsState { export class FriendsStore extends FluxStore { getState(): FriendsState; + isInitialized(): boolean; } diff --git a/packages/discord-types/src/stores/GIFPickerViewStore.d.ts b/packages/discord-types/src/stores/GIFPickerViewStore.d.ts new file mode 100644 index 000000000..36adf6427 --- /dev/null +++ b/packages/discord-types/src/stores/GIFPickerViewStore.d.ts @@ -0,0 +1,32 @@ +import { FluxStore } from ".."; + +export type GIFMediaFormat = 1 | 2; +export type GIFSelectedFormat = "webm" | "tinywebp"; + +export interface GIFResultItem { + id: string; + url: string; + src: string; + gifSrc: string; + width: number; + height: number; + format: GIFMediaFormat; +} + +export interface GIFTrendingCategory { + type: "Trending" | "Category"; + name: string; + src: string; + format: GIFMediaFormat; +} + +export class GIFPickerViewStore extends FluxStore { + getAnalyticsID(): string | null; + getQuery(): string; + getResultItems(): GIFResultItem[]; + getResultQuery(): string; + getSelectedFormat(): GIFSelectedFormat; + getSuggestions(): string[]; + getTrendingCategories(): GIFTrendingCategory[]; + getTrendingSearchTerms(): string[]; +} diff --git a/packages/discord-types/src/stores/GuildReadStateStore.d.ts b/packages/discord-types/src/stores/GuildReadStateStore.d.ts new file mode 100644 index 000000000..ed557291e --- /dev/null +++ b/packages/discord-types/src/stores/GuildReadStateStore.d.ts @@ -0,0 +1,36 @@ +import { Channel, FluxStore } from ".."; +import { ReadStateType } from "../../enums"; + +export interface GuildChannelMentionCount { + count: number; + isMentionLowImportance: boolean; +} + +export interface GuildReadState { + unread: boolean; + unreadByType: Partial>; + unreadChannelId: string | null; + lowImportanceMentionCount: number; + highImportanceMentionCount: number; + mentionCounts: Record; + ncMentionCount: number; + sentinel: number; +} + +export class GuildReadStateStore extends FluxStore { + getGuildChangeSentinel(guildId: string | null): number; + getGuildHasUnreadIgnoreMuted(guildId: string): boolean; + getHighImportanceMentionCountForChannel(guildId: string | null, channelId: string): number; + getIsMentionLowImportance(guildId: string | null): boolean; + getMentionCount(guildId: string | null): number; + getMentionCountForPrivateChannel(channelId: string): GuildChannelMentionCount | number; + getMutableGuildStates(): Record; + getMutableUnreadGuilds(): Set; + getPrivateChannelMentionCount(): number; + getStoreChangeSentinel(): number; + getTotalMentionCount(excludePrivateChannels?: boolean): number; + getTotalNotificationsMentionCount(excludePrivateChannels?: boolean): number; + hasAnyUnread(): boolean; + hasUnread(guildId: string): boolean; + shouldCountChannelUnread(channel: Channel, mentionCount?: number): boolean; +} diff --git a/packages/discord-types/src/stores/InstantInviteStore.d.ts b/packages/discord-types/src/stores/InstantInviteStore.d.ts index bc4af185e..87990a541 100644 --- a/packages/discord-types/src/stores/InstantInviteStore.d.ts +++ b/packages/discord-types/src/stores/InstantInviteStore.d.ts @@ -9,9 +9,16 @@ export interface FriendInvite extends Invite { revoked?: boolean; } +export interface InstantInviteTarget { + targetType?: number; + targetUserId?: string; + targetApplicationId?: string; +} + export class InstantInviteStore extends FluxStore { - getInvite(channelId: string): Invite; + getInvite(channelId: string, target?: InstantInviteTarget): Invite | undefined; getFriendInvite(): FriendInvite | null; getFriendInvitesFetching(): boolean; canRevokeFriendInvite(): boolean; + getReceivedInstallationIdForInviteCode(inviteCode: string): string | undefined; } diff --git a/packages/discord-types/src/stores/JoinedThreadsStore.d.ts b/packages/discord-types/src/stores/JoinedThreadsStore.d.ts new file mode 100644 index 000000000..fcb519009 --- /dev/null +++ b/packages/discord-types/src/stores/JoinedThreadsStore.d.ts @@ -0,0 +1,20 @@ +import { FluxStore, MuteConfig } from ".."; + +export interface JoinedThread { + threadId: string; + guildId: string; + flags: number; + muted: boolean; + muteConfig: MuteConfig | null; + joinTimestamp: Date; +} + +export class JoinedThreadsStore extends FluxStore { + hasJoined(channelId: string): boolean; + joinTimestamp(channelId: string): Date | undefined; + flags(channelId: string): number | undefined; + getInitialOverlayState(): JoinedThread[]; + getMuteConfig(channelId: string): MuteConfig | null | undefined; + getMutedThreads(): Set; + isMuted(channelId: string): boolean; +} diff --git a/packages/discord-types/src/stores/MediaEngineStore.d.ts b/packages/discord-types/src/stores/MediaEngineStore.d.ts index 6f358164c..f39110184 100644 --- a/packages/discord-types/src/stores/MediaEngineStore.d.ts +++ b/packages/discord-types/src/stores/MediaEngineStore.d.ts @@ -404,10 +404,46 @@ export interface ClipMetadata { * Result of saving a clip. */ export interface SavedClip { - /** unique clip identifier. */ - id: string; - /** path where clip was saved. */ + /** clip duration in milliseconds. */ + duration: number; + /** parsed clip encoder stats. */ + clipStats: Record; + /** thumbnail data, if generated. */ + thumbnail?: string; + /** serialized clip metadata, if any. */ + metadata?: string; +} + +/** + * Options for saving a clip from the recording buffer. + */ +export interface SaveClipOptions { + /** path to write the clip to. */ filepath: string; + /** serialized clip metadata. */ + metadata: string; + /** timestamp to take the thumbnail from. */ + thumbnailMs: number; + /** buffer start timestamp. */ + startMs: number; + /** buffer end timestamp. */ + endMs: number; + /** trim start timestamp. */ + trimStartMs: number; + /** trim end timestamp. */ + trimEndMs: number; + /** current user id when streaming. */ + userId?: string; +} + +/** + * Result of exporting a clip to a file. + */ +export interface ExportedClip { + /** path of the exported file. */ + filepath: string; + /** whether the file is already formatted for upload. */ + formattedForUpload: boolean; } /** @@ -1423,6 +1459,18 @@ export interface MediaEngine { Video: React.ComponentType & { onContainerResized: () => void; }; /** set of active voice/video connections. */ connections: Set; + /** current audio input device id. */ + audioInputDeviceId: string; + /** current audio output device id. */ + audioOutputDeviceId: string; + /** current video input device id, or "disabled". */ + videoInputDeviceId: string; + /** active audio layer name. */ + audioLayer: string; + /** active audio subsystem. */ + audioSubsystem: AudioSubsystem; + /** cached codec survey JSON, set after the first getCodecSurvey call. */ + codecSurvey?: string; /** * Registers a listener for device changes. @@ -1579,6 +1627,8 @@ export interface MediaEngine { * @param settings filter settings to apply. */ applyMediaFilterSettings(settings: MediaFilterSettings): Promise; + /** cancels an in-progress batch audio processing run. */ + cancelBatchAudioProcessing(): void; /** * Creates a new voice connection. * @param userId user id for the connection. @@ -1613,12 +1663,13 @@ export interface MediaEngine { */ enable(): Promise; /** - * Exports a clip as a blob. - * @param clipId clip identifier. - * @param userId user who owns the clip. - * @returns promise resolving to the clip blob. + * Exports a clip to a file, applying edits. + * @param sourcePath path of the source clip. + * @param outputPath path to write the exported clip to. + * @param editMetadata trim, crop and track settings. + * @returns promise resolving to the exported file info, rejects with "unsupported" if unavailable. */ - exportClip(clipId: string, userId: string): Promise; + exportClipToFile(sourcePath: string, outputPath: string, editMetadata: Record): Promise; /** * Fetches async resources like DAVE keys. * @param options fetch options. @@ -1651,10 +1702,10 @@ export interface MediaEngine { */ getCodecCapabilities(callback: (capabilities: string) => void): void; /** - * Gets a survey of supported codecs. - * @returns promise resolving to codec info. + * Gets a survey of available video encoders and decoders. + * @returns promise resolving to JSON with available_video_encoders and available_video_decoders. */ - getCodecSurvey(): Promise<{ codecs: CodecInfo[]; }>; + getCodecSurvey(): Promise; /** * Gets whether debug logging is enabled. * @returns true if enabled. @@ -1665,6 +1716,24 @@ export interface MediaEngine { * @returns promise that rejects with NO_STREAM error if not streaming. */ getDesktopSource(): Promise; + /** + * Gets audio effects applied by the OS to a device, Windows only. + * @param deviceId device identifier. + * @returns promise resolving to effect info, rejects if unsupported. + */ + getDeviceAudioEffects(deviceId: string): Promise>; + /** + * Gets whether a device is muted at the OS level. + * @param deviceId device identifier. + * @returns promise resolving to muted state, undefined if unsupported. + */ + getDeviceOSMuted(deviceId: string): Promise; + /** + * Gets a device's OS volume. + * @param deviceId device identifier. + * @returns promise resolving to volume, undefined if unsupported. + */ + getDeviceOSVolume(deviceId: string): Promise; /** * Gets whether loopback is active. * @returns always false for native engine. @@ -1686,9 +1755,19 @@ export interface MediaEngine { * Gets screen preview thumbnails. * @param width thumbnail width. * @param height thumbnail height. + * @param useWgc whether to capture previews with Windows Graphics Capture. * @returns promise resolving to preview list. */ - getScreenPreviews(width: number, height: number): Promise; + getScreenPreviews(width: number, height: number, useWgc?: boolean): Promise; + /** + * Gets a preview thumbnail for a single window. + * @param windowId window source identifier. + * @param width thumbnail width. + * @param height thumbnail height. + * @param useWgc whether to capture previews with Windows Graphics Capture. + * @returns promise resolving to the preview, or null if unavailable. + */ + getSingleWindowPreview(windowId: string, width: number, height: number, useWgc?: boolean): Promise; /** * Gets supported bandwidth estimation experiments. * @param callback called with experiment list. @@ -1699,16 +1778,16 @@ export interface MediaEngine { * @returns protocol version number. */ getSupportedSecureFramesProtocolVersion(): number; - /** - * Gets supported video codecs. - * @param callback called with codec name list. - */ - getSupportedVideoCodecs(callback: (codecs: string[]) => void): void; /** * Gets system microphone mode. * @returns promise resolving to mode string. */ getSystemMicrophoneMode(): Promise; + /** + * Gets the native steady clock time. + * @returns time in milliseconds, or null if unsupported. + */ + getSystemSteadyClockNowMs(): number | null; /** * Gets current video input device id. * @returns device id or "disabled". @@ -1723,10 +1802,16 @@ export interface MediaEngine { * Gets window preview thumbnails. * @param width thumbnail width. * @param height thumbnail height. + * @param useWgc whether to capture previews with Windows Graphics Capture. * @returns promise resolving to preview list. */ - getWindowPreviews(width: number, height: number): Promise; + getWindowPreviews(width: number, height: number, useWgc?: boolean): Promise; + /** + * Checks if the native module supports clips v3. + * @returns true if supported. + */ + hasClipsV3Support(): boolean; /** signals user interaction to enable autoplay. */ interact(): void; /** @@ -1734,6 +1819,19 @@ export interface MediaEngine { * @param options picker options. */ presentNativeScreenSharePicker(options?: string): void; + /** + * Runs audio processing over every file in a directory. + * @param inputDir directory to read audio files from. + * @param outputDir directory to write processed files to. + * @param onProgress called after each file. + * @param onComplete called when finished or cancelled. + */ + processBatchAudioFiles( + inputDir: string, + outputDir: string, + onProgress: (filename: string, current: number, total: number, success: boolean) => void, + onComplete: (processed: number, failed: number) => void + ): void; /** * Queues an audio subsystem switch. * @param subsystem subsystem to switch to. @@ -1745,24 +1843,17 @@ export interface MediaEngine { * @returns promise resolving to sorted region ids. */ rankRtcRegions(regions: string[]): Promise; + /** registers the native clips recording event handler, once. */ + registerClipsRecordingEventHandler(): void; /** releases native desktop video source picker stream. */ releaseNativeDesktopVideoSourcePickerStream(): void; /** - * Saves a clip. - * @param clipId clip identifier. - * @param userId user who owns the clip. + * Saves a clip from the recording buffer. + * @param options clip save options. * @returns promise resolving to saved clip info. */ - saveClip(clipId: string, userId: string): Promise; - /** - * Saves a clip for another user. - * @param clipId clip identifier. - * @param userId user to save for. - * @param options clip metadata. - * @returns promise resolving to saved clip info. - */ - saveClipForUser(clipId: string, userId: string, options: ClipMetadata): Promise; + saveClipEx(options: SaveClipOptions): Promise; /** * Saves a screenshot. * @param channelId channel context. @@ -1780,15 +1871,10 @@ export interface MediaEngine { */ setAecDump(enabled: boolean): void; /** - * Sets callback for async clips source deinit. - * @param callback callback function. + * Sets whether video input devices initialize asynchronously. + * @param enabled whether to enable. */ - setAsyncClipsSourceDeinit(callback: () => void): void; - /** - * Sets callback for async video input device init. - * @param callback callback function. - */ - setAsyncVideoInputDeviceInit(callback: () => void): void; + setAsyncVideoInputDeviceInit(enabled: boolean): void; /** * Sets whether to bypass system audio input processing. * @param bypass whether to bypass. @@ -1799,6 +1885,11 @@ export interface MediaEngine { * @param deviceId device identifier. */ setAudioInputDevice(deviceId: string): void; + /** + * Sets spatial audio mixer options. + * @param options mixer options. + */ + setAudioMixerOptions(options: Record): void; /** * Sets the audio output device. * @param deviceId device identifier. @@ -1809,40 +1900,67 @@ export interface MediaEngine { * @param subsystem subsystem to use. */ setAudioSubsystem(subsystem: AudioSubsystem): void; - /** - * Enables or disables AV1 codec. - * @param enabled whether to enable. - */ - setAv1Enabled(enabled: boolean): void; /** * Sets clip buffer length in seconds. * @param seconds buffer duration. */ setClipBufferLength(seconds: number): void; /** - * Enables or disables clips ML pipeline. - * @param enabled whether to enable. + * Overrides the clips audio model. + * @param model model identifier. */ - setClipsMLPipelineEnabled(enabled: boolean): void; + setClipsAudioModelOverride(model: string): void; /** - * Enables or disables a clips ML pipeline type. - * @param type pipeline type. - * @param enabled whether to enable. + * Sets the clips data directory. + * @param path directory path. */ - setClipsMLPipelineTypeEnabled(type: string, enabled: boolean): void; + setClipsDataPath(path: string): void; + /** + * Sets the clips native module path and registers the recording event handler. + * @param path module path. + */ + setClipsModulePath(path: string): void; + /** + * Configures clips performance monitoring. + * @returns promise resolving to monitoring state, rejects with "unsupported" if unavailable. + */ + setClipsPerfMonitoring(...args: unknown[]): Promise<{ enabled: boolean; }>; /** * Sets clips quality settings. - * @param resolution resolution height. + * @param width resolution width. + * @param height resolution height. * @param frameRate frame rate. - * @param hdr whether HDR is enabled. + * @param bitratePercent bitrate percentage. * @returns true if settings were applied. */ - setClipsQualitySettings(resolution: number, frameRate: number, hdr: boolean): boolean; + setClipsQualitySettings(width: number, height: number, frameRate: number, bitratePercent: number): boolean; + /** + * Enables or disables clips recording. + * @param enabled whether to enable. + */ + setClipsRecordingEnabled(enabled: boolean): void; + /** + * Configures Sentry for the clips module. + * @param release release identifier. + * @param dir Sentry data directory. + * @param environment release channel. + */ + setClipsSentryConfig(release: string, dir: string, environment: string): void; /** * Sets or clears the clips source. * @param source source config or null to clear. */ setClipsSource(source: ClipsSource | null): void; + /** + * Sets whether the clips UI is active. + * @param active whether active. + */ + setClipsUIActive(active: boolean): void; + /** + * Enables or disables the clips v3 ML pipeline. + * @param enabled whether to enable. + */ + setClipsV3MLEnabled(enabled: boolean): void; /** * Enables or disables debug logging. * @param enabled whether to enable. @@ -1854,16 +1972,6 @@ export interface MediaEngine { * @param context context to apply to, defaults to "default". */ setGoLiveSource(source: GoLiveSource | null, context?: MediaEngineContextType): void; - /** - * Enables or disables H264 codec. - * @param enabled whether to enable. - */ - setH264Enabled(enabled: boolean): void; - /** - * Enables or disables H265 codec. - * @param enabled whether to enable. - */ - setH265Enabled(enabled: boolean): void; /** * Sets whether device has fullband performance. * @param has whether it has fullband performance. @@ -1885,16 +1993,16 @@ export interface MediaEngine { * @param delay delay in milliseconds. */ setMaxSyncDelayOverride(delay: number): void; - /** - * Sets maybe preprocess mute state. - * @param mute whether to mute. - */ - setMaybePreprocessMute(mute: boolean): void; /** * Sets native desktop video source picker active state. * @param active whether picker is active. */ setNativeDesktopVideoSourcePickerActive(active: boolean): void; + /** + * Sets noise cancellation models. + * @param models model config. + */ + setNcModels(models: unknown): void; /** * Enables or disables noise cancellation stats. * @param enabled whether to enable. @@ -1937,6 +2045,16 @@ export interface MediaEngine { * @param deviceId device identifier. */ setVideoInputDevice(deviceId: string): Promise; + /** + * Caps the voice channel count. + * @param count max channel count, 0 for no cap. + */ + setVoiceChannelCountCap(count: number): void; + /** + * Caps the voice sample rate. + * @param rate max sample rate in Hz, 0 for no cap. + */ + setVoiceSampleRateCap(rate: number): void; /** * Checks if a connection should broadcast video. @@ -1989,6 +2107,17 @@ export interface MediaEngine { * @param metadata new metadata. */ updateClipMetadata(clipId: string, metadata: ClipMetadata): Promise; + /** + * Updates a WebRTC field trial. + * @param name field trial name. + * @param value field trial value. + */ + updateFieldTrial(name: string, value: string): void; + /** + * Starts watching a device for hardware mute changes. + * @param deviceId device identifier. + */ + watchDeviceHardwareMutedChange(deviceId: string): void; /** ticks the watchdog timer. */ watchdogTick(): void; /** @@ -2122,6 +2251,28 @@ export interface Shortcut { shortcut: string[]; } +/** + * Spatial audio mixer settings. + */ +export interface AudioMixerSettings { + enabled: boolean; + spatialBlend: number; + reflectionsEnabled: boolean; + roomSize: number; + distanceAttenuationEnabled: boolean; + mode: string; + spread: number; + arcAngle: number; + gridColumns: number; + gridSpacing: number; + buckets: number; + listenerHeight: number; + distance: number; +} + +/** 0 unknown, 1 active, 2 mono output, 3 init failed, 4 HRTF failed. */ +export type SpatialAudioStatus = 0 | 1 | 2 | 3 | 4; + /** * Flux store managing audio/video settings, devices, and the media engine. * Handles voice activity detection, noise cancellation, device selection, @@ -2135,16 +2286,6 @@ export class MediaEngineStore extends FluxStore { * @returns current input profile. */ getActiveInputProfile(): InputProfile; - /** - * Gets the active voice filter id. - * @returns voice filter id or null if none active. - */ - getActiveVoiceFilter(): string | null; - /** - * Gets when the active voice filter was applied. - * @returns application date or null if none active. - */ - getActiveVoiceFilterAppliedAt(): Date | null; /** * Gets whether AEC dump is enabled. * @returns true if enabled. @@ -2165,6 +2306,11 @@ export class MediaEngineStore extends FluxStore { * @returns attenuation 0-100, default 0. */ getAttenuation(): number; + /** + * Gets spatial audio mixer settings. + * @returns mixer settings. + */ + getAudioMixerSettings(): AudioMixerSettings; /** * Gets the current audio subsystem. * @returns active audio subsystem. @@ -2200,11 +2346,6 @@ export class MediaEngineStore extends FluxStore { * @returns true if enabled. */ getEnableSilenceWarning(): boolean; - /** - * Gets whether user has ever spoken while muted. - * @returns true if has spoken while muted. - */ - getEverSpeakingWhileMuted(): boolean; /** * Gets whether experimental soundshare is enabled. * @returns true if enabled. @@ -2240,11 +2381,31 @@ export class MediaEngineStore extends FluxStore { * @returns true if detected, false if not, null if unknown. */ getInputDetected(): boolean | null; + /** + * Gets whether input was detected during the current connection. + * @returns true if detected. + */ + getInputDetectedThisConnection(): boolean; + /** + * Gets whether the input device is muted in hardware. + * @returns true if muted, undefined if unknown. + */ + getInputDeviceHardwareMuted(): boolean | undefined; /** * Gets the selected audio input device id. * @returns device id. */ getInputDeviceId(): string; + /** + * Gets whether the input device is muted by the OS. + * @returns true if muted, undefined if unknown. + */ + getInputDeviceOSMuted(): boolean | undefined; + /** + * Gets the OS volume of the input device. + * @returns volume, undefined if unknown. + */ + getInputDeviceOSVolume(): number | undefined; /** * Gets available audio input devices. * @returns devices keyed by device id. @@ -2285,6 +2446,11 @@ export class MediaEngineStore extends FluxStore { * @returns timestamp in milliseconds. */ getLastAudioInputDeviceChangeTimestamp(): number; + /** + * Gets when input detection state last changed. + * @returns timestamp in milliseconds. + */ + getLastInputDetectedUpdateTime(): number; /** * Gets the stereo pan for a user. * @param userId user to get pan for. @@ -2333,11 +2499,6 @@ export class MediaEngineStore extends FluxStore { * @returns current mode options. */ getModeOptions(context?: MediaEngineContextType): ModeOptions; - /** - * Gets the most recently requested voice filter. - * @returns voice filter id or null if none. - */ - getMostRecentlyRequestedVoiceFilter(): string | null; /** * Gets whether no input detected notice is shown. * @returns true if shown. @@ -2353,6 +2514,11 @@ export class MediaEngineStore extends FluxStore { * @returns true if enabled. */ getNoiseSuppression(): boolean; + /** + * Gets whether OpenH264 is enabled, only on Linux. + * @returns true if enabled. + */ + getOpenH264Enabled(): boolean; /** * Gets the selected audio output device id. * @returns device id. @@ -2373,16 +2539,6 @@ export class MediaEngineStore extends FluxStore { * @returns delay in milliseconds. */ getPacketDelay(): number; - /** - * Gets the previous voice filter. - * @returns voice filter id or null if none. - */ - getPreviousVoiceFilter(): string | null; - /** - * Gets when the previous voice filter was applied. - * @returns application date or null if none. - */ - getPreviousVoiceFilterAppliedAt(): Date | null; /** * Gets whether QoS is enabled. * @returns true if enabled. @@ -2409,6 +2565,11 @@ export class MediaEngineStore extends FluxStore { * @returns strength 0-100, default 50. */ getSidechainCompressionStrength(): number; + /** + * Gets the spatial audio status reported by the engine. + * @returns spatial audio status. + */ + getSpatialAudioStatus(): SpatialAudioStatus; /** * Gets whether currently speaking while muted. * @returns true if speaking while muted. @@ -2459,6 +2620,13 @@ export class MediaEngineStore extends FluxStore { * @returns devices keyed by device id. */ getVideoDevices(): { [deviceId: string]: VideoDevice; }; + /** + * Builds the video encoder experiment flags. + * @param context media engine context. + * @param role "streamer" when encoding own stream. + * @returns comma separated experiment flags. + */ + getVideoEncoderExperiments(context: MediaEngineContextType, role?: string): string; /** * Gets whether video hook is enabled. * @returns true if enabled. @@ -2477,18 +2645,6 @@ export class MediaEngineStore extends FluxStore { * @returns toggle state, NONE if not in map. */ getVideoToggleState(userId: string, context?: MediaEngineContextType): VideoToggleState; - /** - * Gets whether voice filter playback is enabled. - * @returns true if enabled. - */ - getVoiceFilterPlaybackEnabled(): boolean; - - /** - * Gets whether go live simulcast is enabled. - * @returns true if enabled. - */ - goLiveSimulcastEnabled(): boolean; - /** * Checks if there is an active CallKit call. * @returns true if active. @@ -2510,7 +2666,11 @@ export class MediaEngineStore extends FluxStore { * @returns true if available. */ hasH265HardwareDecode(): boolean; - + /** + * Checks if any video input device is available. + * @returns true if available. + */ + hasVideoDevice(): boolean; /** * Checks if advanced voice activity is supported. * @returns true if supported. @@ -2532,27 +2692,42 @@ export class MediaEngineStore extends FluxStore { * @returns true if supported. */ isAutomaticGainControlSupported(): boolean; + /** + * Checks if clips recording is ready. + * @returns true if ready. + */ + isClipsRecordingReady(): boolean; + /** + * Checks if the engine emits clips recording ready events. + * @returns true if supported. + */ + isClipsRecordingReadySignalSupported(): boolean; /** * Checks if self is deafened. * @returns true if deafened. */ isDeaf(): boolean; - /** - * Checks if hardware mute notice is enabled. - * @returns true if enabled. - */ - isEnableHardwareMuteNotice(): boolean; /** * Checks if media engine is enabled. * @returns true if enabled. */ isEnabled(): boolean; + /** + * Checks if Media Foundation H264 decoding is available. + * @returns true if available. + */ + isH264MfDecodeAvailable(): boolean; /** * Checks if hardware mute is active. * @param context settings context, defaults to "default". * @returns true if hardware muted. */ isHardwareMute(context?: MediaEngineContextType): boolean; + /** + * Checks if hardware mute notice is enabled. + * @returns true if enabled. + */ + isHardwareMuteNoticeEnabled(): boolean; /** * Checks if input profile is custom. * @returns true if custom. @@ -2638,6 +2813,16 @@ export class MediaEngineStore extends FluxStore { * @returns true if temporarily muted. */ isSelfMutedTemporarily(context?: MediaEngineContextType): boolean; + /** + * Checks if self is server deafened. + * @returns true if server deafened. + */ + isServerDeaf(): boolean; + /** + * Checks if self is server muted. + * @returns true if server muted. + */ + isServerMute(): boolean; /** * Checks if simulcast is supported. * @returns true if supported. @@ -2649,6 +2834,16 @@ export class MediaEngineStore extends FluxStore { * @returns true if sharing. */ isSoundSharing(context?: MediaEngineContextType): boolean; + /** + * Checks if spatial audio is enabled in mixer settings. + * @returns true if enabled. + */ + isSpatialAudioEnabled(): boolean; + /** + * Checks if spatial audio was requested. + * @returns true if requested. + */ + isSpatialAudioRequested(): boolean; /** * Checks if media engine is supported. * @returns true if supported. @@ -2664,7 +2859,6 @@ export class MediaEngineStore extends FluxStore { * @returns true if enabled. */ isVideoEnabled(): boolean; - /** notifies that mute/unmute sound was skipped. */ notifyMuteUnmuteSoundWasSkipped(): void; /** @@ -2693,10 +2887,8 @@ export class MediaEngineStore extends FluxStore { * @returns true if should show. */ showBypassSystemInputProcessing(): boolean; - /** starts preloading DAVE encryption. */ startDavePreload(): void; - /** * Checks if a feature is supported. * @param feature feature to check. diff --git a/packages/discord-types/src/stores/MessageRequestStore.d.ts b/packages/discord-types/src/stores/MessageRequestStore.d.ts new file mode 100644 index 000000000..471f9e18e --- /dev/null +++ b/packages/discord-types/src/stores/MessageRequestStore.d.ts @@ -0,0 +1,9 @@ +import { FluxStore } from ".."; + +export class MessageRequestStore extends FluxStore { + getMessageRequestChannelIds(): Set; + getMessageRequestsCount(): number; + isAcceptedOptimistic(channelId: string): boolean; + isMessageRequest(channelId: string): boolean; + isReady(): boolean; +} diff --git a/packages/discord-types/src/stores/MessageStore.d.ts b/packages/discord-types/src/stores/MessageStore.d.ts index faec2189e..4f1f8fbca 100644 --- a/packages/discord-types/src/stores/MessageStore.d.ts +++ b/packages/discord-types/src/stores/MessageStore.d.ts @@ -52,6 +52,8 @@ export class MessageStore extends FluxStore { getMessages(channelId: string): ChannelMessages; hasCurrentUserSentMessage(channelId: string): boolean; hasCurrentUserSentMessageSinceAppStart(channelId: string): boolean; + hasCurrentUserSentWaveBlockingMessage(channelId: string): boolean; + getAutomodRemovalNotice(messageId: string): unknown; hasPresent(channelId: string): boolean; isLoadingMessages(channelId: string): boolean; isReady(channelId: string): boolean; diff --git a/packages/discord-types/src/stores/NotificationSettingsStore.d.ts b/packages/discord-types/src/stores/NotificationSettingsStore.d.ts index e82596a7e..ea0ba3ef7 100644 --- a/packages/discord-types/src/stores/NotificationSettingsStore.d.ts +++ b/packages/discord-types/src/stores/NotificationSettingsStore.d.ts @@ -15,6 +15,7 @@ export interface NotificationSettingsState { export class NotificationSettingsStore extends FluxStore { get taskbarFlash(): boolean; + get screenDowntimeReminder(): boolean; getUserAgnosticState(): NotificationSettingsState; getDesktopType(): DesktopNotificationType; getTTSType(): TTSNotificationType; diff --git a/packages/discord-types/src/stores/OverridePremiumTypeStore.d.ts b/packages/discord-types/src/stores/OverridePremiumTypeStore.d.ts index b9c3adca4..931afb788 100644 --- a/packages/discord-types/src/stores/OverridePremiumTypeStore.d.ts +++ b/packages/discord-types/src/stores/OverridePremiumTypeStore.d.ts @@ -5,6 +5,7 @@ export interface OverridePremiumTypeState { createdAtOverride: Date | undefined; premiumTypeActual: PremiumType | null; premiumTypeOverride: PremiumType | undefined; + perksActual: Record | null; } export class OverridePremiumTypeStore extends FluxStore { @@ -12,5 +13,6 @@ export class OverridePremiumTypeStore extends FluxStore { getCreatedAtOverride(): Date | undefined; getPremiumTypeActual(): PremiumType | null; getPremiumTypeOverride(): PremiumType | undefined; + getPerksActual(): Record | null; get premiumType(): PremiumType | undefined; } diff --git a/packages/discord-types/src/stores/PresenceStore.d.ts b/packages/discord-types/src/stores/PresenceStore.d.ts index ff2fdf874..5e8540f23 100644 --- a/packages/discord-types/src/stores/PresenceStore.d.ts +++ b/packages/discord-types/src/stores/PresenceStore.d.ts @@ -29,7 +29,7 @@ export class PresenceStore extends FluxStore { getAllApplicationActivities(applicationId: string): UserAndActivity[]; getApplicationActivity(userId: string, applicationId: string, guildId?: string): Activity | null; getClientStatus(userId: string): ClientStatusMap; - getHiddenActivities(): Activity[]; + getHiddenActivities(userId: string, guildId?: string | null): Activity[]; /** literally just getActivities(...)[0] */ getPrimaryActivity(userId: string, guildId?: string): Activity | null; getState(): PresenceStoreState; @@ -37,4 +37,6 @@ export class PresenceStore extends FluxStore { getUnfilteredActivities(userId: string, guildId?: string): Activity[]; getUserIds(): string[]; isMobileOnline(userId: string): boolean; + isVROnline(userId: string): boolean; + setCurrentUserOnConnectionOpen(status: OnlineStatus, activities: Activity[]): void; } diff --git a/packages/discord-types/src/stores/PrivateChannelSortStore.d.ts b/packages/discord-types/src/stores/PrivateChannelSortStore.d.ts new file mode 100644 index 000000000..3358fe70c --- /dev/null +++ b/packages/discord-types/src/stores/PrivateChannelSortStore.d.ts @@ -0,0 +1,14 @@ +import { FluxStore } from ".."; + +export interface PrivateChannelSortEntry { + channelId: string; + lastMessageId: string; + isFavorite: boolean; + isRequest: boolean; +} + +export class PrivateChannelSortStore extends FluxStore { + getPrivateChannelIds(): string[]; + getSortedChannels(): [PrivateChannelSortEntry[], PrivateChannelSortEntry[]]; + serializeForOverlay(): Record; +} diff --git a/packages/discord-types/src/stores/RTCConnectionStore.d.ts b/packages/discord-types/src/stores/RTCConnectionStore.d.ts index 3dac744ae..6032d6ccf 100644 --- a/packages/discord-types/src/stores/RTCConnectionStore.d.ts +++ b/packages/discord-types/src/stores/RTCConnectionStore.d.ts @@ -66,7 +66,6 @@ export class RTCConnectionStore extends FluxStore { getRTCConnectionId(): string | undefined; getDuration(): number | undefined; getLastRTCConnectionState(): LastRTCConnectionState | null; - getVoiceFilterSpeakingDurationMs(): number | undefined; getPacketStats(): RTCConnectionPacketStats | undefined; getVoiceStateStats(): VoiceStateStats | undefined; // TODO: finish typing diff --git a/packages/discord-types/src/stores/ReadStateStore.d.ts b/packages/discord-types/src/stores/ReadStateStore.d.ts index 6dcde5f1a..89565bf17 100644 --- a/packages/discord-types/src/stores/ReadStateStore.d.ts +++ b/packages/discord-types/src/stores/ReadStateStore.d.ts @@ -59,6 +59,8 @@ export class ReadStateStore extends FluxStore { hasRecentlyVisitedAndRead(channelId: string): boolean; hasTrackedUnread(channelId: string): boolean; hasUnread(channelId: string, type?: ReadStateType): boolean; + hasLastMessage(channelId: string, type?: ReadStateType): boolean; + canBeUnread(channelId: string, type?: ReadStateType): boolean; hasUnreadOrMentions(channelId: string, type?: ReadStateType): boolean; hasUnreadPins(channelId: string): boolean; isEstimated(channelId: string, type?: ReadStateType): boolean; diff --git a/packages/discord-types/src/stores/ReferencedMessageStore.d.ts b/packages/discord-types/src/stores/ReferencedMessageStore.d.ts new file mode 100644 index 000000000..7e06e6cca --- /dev/null +++ b/packages/discord-types/src/stores/ReferencedMessageStore.d.ts @@ -0,0 +1,12 @@ +import { FluxStore, Message } from ".."; + +export interface ReferencedMessage { + state: number; + message?: Message; +} + +export class ReferencedMessageStore extends FluxStore { + getMessageByReference(reference: Message["messageReference"]): { message: Message; } | undefined; + getMessage(channelId: string, messageId: string): ReferencedMessage; + getReplyIdsForChannel(channelId: string | null | undefined): Set; +} diff --git a/packages/discord-types/src/stores/RelationshipStore.d.ts b/packages/discord-types/src/stores/RelationshipStore.d.ts index d63d094cc..4fca903b2 100644 --- a/packages/discord-types/src/stores/RelationshipStore.d.ts +++ b/packages/discord-types/src/stores/RelationshipStore.d.ts @@ -4,13 +4,14 @@ import { RelationshipType } from "../../enums"; export class RelationshipStore extends FluxStore { getBlockedIDs(): string[]; - getBlockedOrIgnoredIDs(): string[]; + getBlockedOrIgnoredIDs(): Set; getFriendCount(): number; getFriendIDs(): string[]; getIgnoredIDs(): string[]; getMutableRelationships(): Map; - getNickname(userId: string): string; + getNickname(userId: string): string | undefined; + getNote(userId: string): string | undefined; getOriginApplicationId(userId: string): string | undefined; getOutgoingCount(): number; getPendingCount(): number; @@ -38,6 +39,6 @@ export class RelationshipStore extends FluxStore { isIgnored(userId: string): boolean; isIgnoredForMessage(message: Message | MessageJSON): boolean; isSpam(userId: string): boolean; - isStranger(userId: string): boolean; + isStranger(userId: string): boolean | undefined; isUnfilteredPendingIncoming(userId: string): boolean; } diff --git a/packages/discord-types/src/stores/RunningGameStore.d.ts b/packages/discord-types/src/stores/RunningGameStore.d.ts index 569d2052d..f7fdcfbf5 100644 --- a/packages/discord-types/src/stores/RunningGameStore.d.ts +++ b/packages/discord-types/src/stores/RunningGameStore.d.ts @@ -34,6 +34,9 @@ export class RunningGameStore extends FluxStore { getCandidateGames(): RunningGame[]; getCurrentGameForAnalytics(): RunningGame | null; getCurrentNonGameForAnalytics(): RunningGame | null; + getDebugRunningGame(): RunningGame | null; + getDetectionDebug(): { timestamp: number; totalFromNative: number; entries: { game: RunningGame; outcome: { kind: string; }; }[]; } | null; + canCollectExecutableFingerprintsForRunningGames(): boolean; getGameForName(name: string): RunningGame | null; getGameForPID(pid: number): RunningGame | null; getGameOrTransformedSubgameForPID(pid: number): RunningGame | null; @@ -55,6 +58,7 @@ export class RunningGameStore extends FluxStore { getVisibleRunningGames(): RunningGame[]; isDetectionEnabled(game: RunningGame): boolean; isGamesSeenLoaded(): boolean; + isGameSeen(gameId: string): boolean; isObservedAppRunning(app: string): boolean; isSystemServiceInitialized(service: string): boolean; shouldContinueWithoutElevatedProcessForPID(pid: number): boolean; diff --git a/packages/discord-types/src/stores/SafetyHubStore.d.ts b/packages/discord-types/src/stores/SafetyHubStore.d.ts new file mode 100644 index 000000000..d1479b5f8 --- /dev/null +++ b/packages/discord-types/src/stores/SafetyHubStore.d.ts @@ -0,0 +1,46 @@ +import { FluxStore } from ".."; +import { StandingState } from "../../enums"; + +export interface AccountStanding { + state: StandingState; +} + +export interface SafetyHubClassification { + id: string; + [key: string]: unknown; +} + +export type ClassificationRequestState = 0 | 1 | 2; + +export type AgeCheckStatus = "loading" | "error" | "success" | "failure" | "none" | "verified" | "verified_other_violations_remain" | "underage" | "underage_manual_review"; + +export class SafetyHubStore extends FluxStore { + getAccountStanding(): AccountStanding; + isInitialized(): boolean; + isFetching(): boolean; + getFetchError(): unknown; + getClassifications(): SafetyHubClassification[]; + getClassification(classificationId: string): SafetyHubClassification | undefined; + getClassificationRequestState(classificationId: string): ClassificationRequestState | undefined; + + getAppealClassificationId(): string | null; + getIsDsaEligible(): boolean; + getIsAppealEligible(): boolean; + getAppealEligibility(): unknown[]; + getAppealSignal(): number; + getFreeTextAppealReason(): string; + getIsSubmitting(): boolean; + getSubmitError(): unknown; + getIsExpressiveModalV2Enabled(): boolean; + getShowExpressiveModalSubtitleAlt(): boolean; + getIsManualReviewFallbackEnabled(): boolean; + getIsManualReviewDecidedUnderage(): boolean; + getUsername(): string; + + getAgeVerificationWebviewUrl(): string; + getAgeVerificationError(): unknown; + getIsLoadingAgeVerification(): boolean; + getAgeCheckStatus(): AgeCheckStatus; + getAgeCheckError(): unknown; + getAgeCheckAttempts(): number; +} diff --git a/packages/discord-types/src/stores/SelfPresenceStore.d.ts b/packages/discord-types/src/stores/SelfPresenceStore.d.ts new file mode 100644 index 000000000..e2e26f7a9 --- /dev/null +++ b/packages/discord-types/src/stores/SelfPresenceStore.d.ts @@ -0,0 +1,19 @@ +import { Activity, FluxStore, OnlineStatus } from ".."; + +export interface LocalPresence { + status: OnlineStatus; + since: number; + activities: Activity[]; + afk: boolean; +} + +export class SelfPresenceStore extends FluxStore { + findActivity(predicate: (activity: Activity) => boolean, filtered?: boolean): Activity | undefined; + getActivities(filtered?: boolean): Activity[]; + getApplicationActivity(applicationId: string, filtered?: boolean): Activity | undefined; + getHiddenActivities(): Activity[]; + getLocalPresence(): LocalPresence; + getPrimaryActivity(filtered?: boolean): Activity | undefined; + getStatus(): OnlineStatus; + getUnfilteredActivities(filtered?: boolean): Activity[]; +} diff --git a/packages/discord-types/src/stores/SessionsStore.d.ts b/packages/discord-types/src/stores/SessionsStore.d.ts new file mode 100644 index 000000000..c47cfd054 --- /dev/null +++ b/packages/discord-types/src/stores/SessionsStore.d.ts @@ -0,0 +1,24 @@ +import { Activity, FluxStore } from ".."; + +export interface Session { + sessionId: string; + status: string; + active: boolean; + activities: Activity[]; + hiddenActivities?: Activity[]; + clientInfo: { + version: number; + os: string; + client: string; + }; +} + +export class SessionsStore extends FluxStore { + getSessions(): Record; + getSession(): Session | null | undefined; + getSessionById(sessionId: string): Session | undefined; + getActiveSession(): Session | undefined; + getRemoteActivities(): Activity[]; + getHiddenActivities(): Activity[]; + getRemoteApplicationActivity(applicationId: string | null | undefined): Activity | null | undefined; +} diff --git a/packages/discord-types/src/stores/SortedGuildStore.d.ts b/packages/discord-types/src/stores/SortedGuildStore.d.ts new file mode 100644 index 000000000..1a9ea6db1 --- /dev/null +++ b/packages/discord-types/src/stores/SortedGuildStore.d.ts @@ -0,0 +1,29 @@ +import { FluxStore, GuildFolder } from ".."; + +export interface GuildsTreeNode { + type: string; + id: string | number; + children: GuildsTreeNode[]; + name?: string; + color?: number; + expanded?: boolean; +} + +export interface GuildsTree { + root: GuildsTreeNode; + version: number; + getRoots(): GuildsTreeNode[]; + getNode(id: string | number): GuildsTreeNode | undefined; + allNodes(): GuildsTreeNode[]; + sortedGuildNodes(): GuildsTreeNode[]; +} + +export class SortedGuildStore extends FluxStore { + getGuildsTree(): GuildsTree; + getFlattenedGuildFolderList(): GuildsTreeNode[]; + getCompatibleGuildFolders(): GuildFolder[]; + getFastListGuildFolders(): GuildsTreeNode[]; + getFlattenedGuildIds(): string[]; + getGuildFolderById(folderId: number): GuildFolder; + getGuildFolders(): GuildFolder[]; +} diff --git a/packages/discord-types/src/stores/SoundboardStore.d.ts b/packages/discord-types/src/stores/SoundboardStore.d.ts index 22065c725..203619c0b 100644 --- a/packages/discord-types/src/stores/SoundboardStore.d.ts +++ b/packages/discord-types/src/stores/SoundboardStore.d.ts @@ -11,14 +11,15 @@ export interface SoundboardSound { userId?: string; } -export interface TopSoundForGuild { - soundId: string; - rank: number; +export interface TopSoundboardSoundsMetadata { + soundIds: string[]; + topSoundsTTL: number; } export interface SoundboardOverlayState { soundboardSounds: Record; favoritedSoundIds: string[]; + orderedFavoritedSoundIds: string[]; localSoundboardMutes: string[]; } @@ -37,11 +38,14 @@ export class SoundboardStore extends FluxStore { isPlayingSound(soundId: string): boolean; isFavoriteSound(soundId: string): boolean; getFavorites(): Set; - getAllTopSoundsForGuilds(): Map; + getFrequentlyUsedSoundIds(): string[]; + getTopSoundboardSoundsMetadata(guildId: string): TopSoundboardSoundsMetadata | undefined; + getTopSoundboardSoundIds(guildId: string | null | undefined): string[]; + hasPendingUsage(): boolean; + get playedSoundFrecencyWithoutFetchingLatest(): { frequently: string[]; }; isLocalSoundboardMuted(userId: string): boolean; + isSoundboardVolumeMuted(): boolean; hasHadOtherUserPlaySoundInSession(): boolean; - shouldFetchTopSoundsForGuilds(): boolean; - hasFetchedTopSoundsForGuilds(): boolean; hasFetchedAllSounds(): boolean; isFetchingAnySounds(): boolean; } diff --git a/packages/discord-types/src/stores/SpellCheckStore.d.ts b/packages/discord-types/src/stores/SpellCheckStore.d.ts index ff8ecaddc..1cb95d43e 100644 --- a/packages/discord-types/src/stores/SpellCheckStore.d.ts +++ b/packages/discord-types/src/stores/SpellCheckStore.d.ts @@ -2,5 +2,6 @@ import { FluxStore } from ".."; export class SpellCheckStore extends FluxStore { hasLearnedWord(word: string): boolean; + findLearnedWordIn(text: string): string | null; isEnabled(): boolean; } diff --git a/packages/discord-types/src/stores/SpotifyStore.d.ts b/packages/discord-types/src/stores/SpotifyStore.d.ts index 64cf08c5d..52574d9a5 100644 --- a/packages/discord-types/src/stores/SpotifyStore.d.ts +++ b/packages/discord-types/src/stores/SpotifyStore.d.ts @@ -32,6 +32,7 @@ export interface SpotifySocketAndDevice { export interface SpotifyArtist { id: string; name: string; + external_urls: { spotify: string; }; } export interface SpotifyImage { diff --git a/packages/discord-types/src/stores/StreamerModeStore.d.ts b/packages/discord-types/src/stores/StreamerModeStore.d.ts index 73e2eaea6..5d3aa0c1d 100644 --- a/packages/discord-types/src/stores/StreamerModeStore.d.ts +++ b/packages/discord-types/src/stores/StreamerModeStore.d.ts @@ -8,6 +8,7 @@ export interface StreamerModeSettings { disableSounds: boolean; disableNotifications: boolean; enableContentProtection: boolean; + disabledOverlayWidgets?: string[]; } export class StreamerModeStore extends FluxStore { @@ -21,4 +22,5 @@ export class StreamerModeStore extends FluxStore { getSettings(): StreamerModeSettings; getState(): Record; + isOverlayWidgetDisabled(widget: string): boolean; } diff --git a/packages/discord-types/src/stores/ThemeStore.d.ts b/packages/discord-types/src/stores/ThemeStore.d.ts index c0dbcf592..3b982326d 100644 --- a/packages/discord-types/src/stores/ThemeStore.d.ts +++ b/packages/discord-types/src/stores/ThemeStore.d.ts @@ -9,6 +9,13 @@ export interface ThemeState { /** 0 = not loaded, 1 = loaded */ status: 0 | 1; preferences: Record; + syncedClientThemes: Partial>; + syncedThemesEnabled: boolean; +} + +export interface SyncedClientTheme { + backgroundGradientPresetId?: number; + [key: string]: unknown; } export class ThemeStore extends FluxStore { get systemTheme(): SystemTheme; @@ -16,4 +23,6 @@ export class ThemeStore extends FluxStore { getState(): ThemeState; themePreferenceForSystemTheme(preference: ThemePreference): Theme; + getSyncedClientTheme(systemTheme: SystemTheme): SyncedClientTheme | undefined; + isSameAsDeviceThemeEnabled(): boolean; } diff --git a/packages/discord-types/src/stores/ThreadMemberListStore.d.ts b/packages/discord-types/src/stores/ThreadMemberListStore.d.ts new file mode 100644 index 000000000..47f7ba403 --- /dev/null +++ b/packages/discord-types/src/stores/ThreadMemberListStore.d.ts @@ -0,0 +1,12 @@ +import { FluxStore } from ".."; + +export interface ThreadMemberListSection { + sectionId: string; + userIds: string[]; +} + +export class ThreadMemberListStore extends FluxStore { + getMemberListSections(channelId?: string): Record; + getMemberListVersion(channelId: string): number | undefined; + canUserViewChannel(channelId: string, sectionId: string, userId: string): boolean; +} diff --git a/packages/discord-types/src/stores/TypingStore.d.ts b/packages/discord-types/src/stores/TypingStore.d.ts index 0ebe994f5..cb3657450 100644 --- a/packages/discord-types/src/stores/TypingStore.d.ts +++ b/packages/discord-types/src/stores/TypingStore.d.ts @@ -5,5 +5,10 @@ export class TypingStore extends FluxStore { * returns a map of user ids to timeout ids */ getTypingUsers(channelId: string): Record; + /** + * returns a map of channel ids to maps of user ids to timeout ids + */ + getTypingUsersByGuild(guildId: string): Record>; isTyping(channelId: string, userId: string): boolean; + getCustomTypingIndicatorConfig(userId: string): unknown; } diff --git a/packages/discord-types/src/stores/UserAffinitiesStore.d.ts b/packages/discord-types/src/stores/UserAffinitiesStore.d.ts index d81209bf2..f458172c5 100644 --- a/packages/discord-types/src/stores/UserAffinitiesStore.d.ts +++ b/packages/discord-types/src/stores/UserAffinitiesStore.d.ts @@ -26,7 +26,7 @@ export class UserAffinitiesStore extends FluxStore { getState(): UserAffinitiesResponse; getUserAffinities(): UserAffinity[]; getUserAffinitiesMap(): Map; - getUserAffinity(userId: string): UserAffinity; + getUserAffinity(userId: string): UserAffinity | undefined; isFetching(): boolean; isHighlyAffinedVCUser(userId: string): boolean; shouldFetch(): boolean; diff --git a/packages/discord-types/src/stores/UserGuildJoinRequestStore.d.ts b/packages/discord-types/src/stores/UserGuildJoinRequestStore.d.ts new file mode 100644 index 000000000..799dd59c8 --- /dev/null +++ b/packages/discord-types/src/stores/UserGuildJoinRequestStore.d.ts @@ -0,0 +1,14 @@ +import { FluxStore, Guild } from ".."; + +export interface UserGuildJoinRequest { + guildId: string; + [key: string]: unknown; +} + +export class UserGuildJoinRequestStore extends FluxStore { + get hasFetchedRequestToJoinGuilds(): boolean; + computeGuildIds(): string[]; + getRequest(guildId: string): UserGuildJoinRequest | undefined; + getJoinRequestGuild(guildId: string): Guild | null; + hasJoinRequestCoackmark(): boolean; +} diff --git a/packages/discord-types/src/stores/UserGuildSettingsStore.d.ts b/packages/discord-types/src/stores/UserGuildSettingsStore.d.ts index 9e5e03873..ea1f9d632 100644 --- a/packages/discord-types/src/stores/UserGuildSettingsStore.d.ts +++ b/packages/discord-types/src/stores/UserGuildSettingsStore.d.ts @@ -46,7 +46,6 @@ export class UserGuildSettingsStore extends FluxStore { allowAllMessages(channel: Channel): boolean; allowNoMessages(channel: Channel): boolean; - getAddedToMessages(): string[]; // TODO: finish typing getAllSettings(): { userGuildSettings: Record; }; getChannelFlags(channel: Channel): ChannelOverrideFlags; @@ -69,9 +68,8 @@ export class UserGuildSettingsStore extends FluxStore { getOptedInChannelsWithPendingUpdates(guildId: string): Record; getPendingChannelUpdates(guildId: string): Record; getState(): UserGuildSettingsState; - isAddedToMessages(channelId: string): boolean; isCategoryMuted(guildId: string, channelId: string): boolean; - isChannelMuted(guildId: string, channelId: string): boolean; + isChannelMuted(guildId: string | null, channelId: string): boolean; isChannelOptedIn(guildId: string, channelId: string, usePending?: boolean): boolean; isChannelOrParentOptedIn(guildId: string, channelId: string, usePending?: boolean): boolean; isChannelRecordOrParentOptedIn(channel: Channel, usePending?: boolean): boolean; diff --git a/packages/discord-types/src/stores/UserProfileSettingsStore.d.ts b/packages/discord-types/src/stores/UserProfileSettingsStore.d.ts new file mode 100644 index 000000000..39165102e --- /dev/null +++ b/packages/discord-types/src/stores/UserProfileSettingsStore.d.ts @@ -0,0 +1,13 @@ +import { FluxStore } from ".."; + +export class UserProfileSettingsStore extends FluxStore { + get selectedGuildId(): string | undefined; + getPendingChanges(guildId?: string): Record; + getFormState(): unknown; + getErrors(guildId?: string): Record; + getTryItOutChanges(): Record; + hasTryItOutChanges(): boolean; + hasUnsavedChanges(): boolean; + showNotice(): boolean; + canSubmit(): boolean; +} diff --git a/packages/discord-types/src/stores/UserProfileStore.d.ts b/packages/discord-types/src/stores/UserProfileStore.d.ts index 84929d60b..d34635ed1 100644 --- a/packages/discord-types/src/stores/UserProfileStore.d.ts +++ b/packages/discord-types/src/stores/UserProfileStore.d.ts @@ -103,20 +103,13 @@ export interface UserProfile extends UserProfileBase, Pick premiumSince: Date | null; } -export interface ApplicationWidgetConfig { - applicationId: string; - widgetType: number; -} - export interface WishlistSettings { privacy: number; } export class UserProfileStore extends FluxStore { - get applicationWidgetApplicationConfigs(): Record; get isSubmitting(): boolean; - getApplicationWidgetApplicationConfig(applicationId: string): ApplicationWidgetConfig | undefined; getFirstWishlistId(userId: string): string | null; getGuildMemberProfile(userId: string, guildId: string | undefined): UserProfileBase | null; /** @@ -147,7 +140,7 @@ export class UserProfileStore extends FluxStore { // TODO: finish typing getWidgets(userId: string): any[] | undefined; getWishlistIds(userId: string): string[]; - getWishlistSettings(userId: string): WishlistSettings | null; + getWishlistSettings(userId: string, wishlistId: string): WishlistSettings | null; /** * Check if mutual friends for {@link userId} are currently being fetched. * diff --git a/packages/discord-types/src/stores/UserSettingsProtoStore.d.ts b/packages/discord-types/src/stores/UserSettingsProtoStore.d.ts index 66b02352d..6815157a4 100644 --- a/packages/discord-types/src/stores/UserSettingsProtoStore.d.ts +++ b/packages/discord-types/src/stores/UserSettingsProtoStore.d.ts @@ -223,4 +223,7 @@ export class UserSettingsProtoStore extends FluxStore { // TODO: finish typing getGuildDismissedContentState(guildId: string): any; getGuildsProto(): Record; + getDefaultGuildThemePreference(): number; + getGuildThemeSourcePreferenceOverride(guildId: string | null | undefined): number; + resolveGuildThemeSourcePreference(guildId: string | null | undefined): number; } diff --git a/packages/discord-types/src/stores/index.d.ts b/packages/discord-types/src/stores/index.d.ts index 387a00c7c..17af4810a 100644 --- a/packages/discord-types/src/stores/index.d.ts +++ b/packages/discord-types/src/stores/index.d.ts @@ -6,25 +6,35 @@ export * from "./ApplicationStore"; export * from "./ApplicationStreamingStore"; export * from "./ApplicationStreamPreviewStore"; export * from "./AuthenticationStore"; +export * from "./AuthorizedAppsStore"; export * from "./CallStore"; +export * from "./ChannelMemberStore"; export * from "./ChannelRTCStore"; +export * from "./ChannelSectionStore"; export * from "./ChannelStore"; +export * from "./ClientThemesBackgroundStore"; +export * from "./CollapsedVoiceChannelStore"; +export * from "./ConnectedAccountsStore"; export * from "./DraftStore"; export * from "./EditMessageStore"; export * from "./EmojiStore"; export * from "./ExperimentStore"; export * from "./FluxStore"; export * from "./FriendsStore"; +export * from "./GIFPickerViewStore"; export * from "./GuildChannelStore"; export * from "./GuildMemberCountStore"; export * from "./GuildMemberStore"; +export * from "./GuildReadStateStore"; export * from "./GuildRoleStore"; export * from "./GuildScheduledEventStore"; export * from "./GuildStore"; export * from "./InstantInviteStore"; export * from "./InviteStore"; +export * from "./JoinedThreadsStore"; export * from "./LocaleStore"; export * from "./MediaEngineStore"; +export * from "./MessageRequestStore"; export * from "./MessageStore"; export * from "./NotificationSettingsStore"; export * from "./OverridePremiumTypeStore"; @@ -32,22 +42,31 @@ export * from "./PendingReplyStore"; export * from "./PermissionStore"; export * from "./PopoutWindowStore"; export * from "./PresenceStore"; +export * from "./PrivateChannelSortStore"; export * from "./ReadStateStore"; +export * from "./ReferencedMessageStore"; export * from "./RelationshipStore"; export * from "./RTCConnectionStore"; export * from "./RunningGameStore"; +export * from "./SafetyHubStore"; export * from "./SelectedChannelStore"; export * from "./SelectedGuildStore"; +export * from "./SelfPresenceStore"; +export * from "./SessionsStore"; +export * from "./SortedGuildStore"; export * from "./SoundboardStore"; export * from "./SpellCheckStore"; export * from "./SpotifyStore"; export * from "./StickersStore"; export * from "./StreamerModeStore"; export * from "./ThemeStore"; +export * from "./ThreadMemberListStore"; export * from "./TypingStore"; export * from "./UploadAttachmentStore"; export * from "./UserAffinitiesStore"; +export * from "./UserGuildJoinRequestStore"; export * from "./UserGuildSettingsStore"; +export * from "./UserProfileSettingsStore"; export * from "./UserProfileStore"; export * from "./UserSettingsProtoStore"; export * from "./UserStore"; diff --git a/src/plugins/noPendingCount/index.ts b/src/plugins/noPendingCount/index.ts index 5bede8b49..bca00ef73 100644 --- a/src/plugins/noPendingCount/index.ts +++ b/src/plugins/noPendingCount/index.ts @@ -19,9 +19,7 @@ import { definePluginSettings } from "@api/Settings"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; -import { findByPropsLazy } from "@webpack"; - -const MessageRequestStore = findByPropsLazy("getMessageRequestsCount"); +import { MessageRequestStore } from "@webpack/common"; const settings = definePluginSettings({ hideFriendRequestsCount: { diff --git a/src/plugins/spotifyShareCommands/index.ts b/src/plugins/spotifyShareCommands/index.ts index ec350a255..5f82613d6 100644 --- a/src/plugins/spotifyShareCommands/index.ts +++ b/src/plugins/spotifyShareCommands/index.ts @@ -20,50 +20,17 @@ import { ApplicationCommandInputType, findOption, OptionalMessageOption, sendBot import { Devs } from "@utils/constants"; import { sendMessage } from "@utils/discord"; import definePlugin from "@utils/types"; -import { Command } from "@vencord/discord-types"; -import { findByPropsLazy } from "@webpack"; -import { FluxDispatcher, MessageActions, PendingReplyStore } from "@webpack/common"; +import { Command, SpotifyTrack } from "@vencord/discord-types"; +import { FluxDispatcher, MessageActions, PendingReplyStore, SpotifyStore } from "@webpack/common"; -interface Album { - id: string; - image: { - height: number; - width: number; - url: string; - }; - name: string; -} - -interface Artist { - external_urls: { - spotify: string; - }; - href: string; - id: string; - name: string; - type: "artist" | string; - uri: string; -} - -interface Track { - id: string | null; - album: Album; - artists: Artist[]; - duration: number; - isLocal: boolean; - name: string; -} - -const Spotify = findByPropsLazy("getPlayerState"); - -function makeCommand(name: string, formatUrl: (track: Track) => string): Command { +function makeCommand(name: string, formatUrl: (track: SpotifyTrack) => string): Command { return { name, description: `Share your current Spotify ${name} in chat`, inputType: ApplicationCommandInputType.BUILT_IN, options: [OptionalMessageOption], execute(options, { channel }) { - const track: Track | null = Spotify.getTrack(); + const track = SpotifyStore.getTrack(); if (!track) { return sendBotMessage(channel.id, { content: "You're not listening to any music." diff --git a/src/plugins/tenorGifSearch/index.tsx b/src/plugins/tenorGifSearch/index.tsx index 2b6ea1a56..a6987af3c 100644 --- a/src/plugins/tenorGifSearch/index.tsx +++ b/src/plugins/tenorGifSearch/index.tsx @@ -7,14 +7,11 @@ import { Devs } from "@utils/constants"; import { isNonNullish } from "@utils/guards"; import definePlugin from "@utils/types"; -import { findStoreLazy } from "@webpack"; -import { FluxDispatcher, LocaleStore } from "@webpack/common"; +import { FluxDispatcher, GIFPickerViewStore, LocaleStore } from "@webpack/common"; // API key is taken from the GBoard app on iOS const TENOR_KEY = "3Z0688EVWYKH"; -const GIFPickerViewStore = findStoreLazy("GIFPickerViewStore"); - let cachedCategories: TrendingCategories | null = null; interface TenorMedia { diff --git a/src/plugins/webPWA.browser/index.tsx b/src/plugins/webPWA.browser/index.tsx index 452d2c6f4..3785c6deb 100644 --- a/src/plugins/webPWA.browser/index.tsx +++ b/src/plugins/webPWA.browser/index.tsx @@ -8,14 +8,10 @@ import { addThemeChangeListener, removeThemeChangeListener } from "@api/Themes"; import { Devs } from "@utils/constants"; import { sleep } from "@utils/misc"; import definePlugin from "@utils/types"; -import { FluxStore } from "@vencord/discord-types"; -import { findStoreLazy } from "@webpack"; -import { NotificationSettingsStore, RelationshipStore, ThemeStore } from "@webpack/common"; +import { GuildReadStateStore, NotificationSettingsStore, RelationshipStore, ThemeStore } from "@webpack/common"; import managedStyle from "./styles.css?managed"; -const GuildReadStateStore: FluxStore & { getTotalMentionCount: () => number; hasAnyUnread: () => boolean; } = findStoreLazy("GuildReadStateStore"); - let _keybinds: Record any; }>; function colorToHex(color: string) { diff --git a/src/webpack/common/stores.ts b/src/webpack/common/stores.ts index 6ce75acc0..1741d1799 100644 --- a/src/webpack/common/stores.ts +++ b/src/webpack/common/stores.ts @@ -86,6 +86,25 @@ export let ExperimentStore: t.ExperimentStore; export let UserAffinitiesStore: t.UserAffinitiesStore; export let ApplicationStreamingStore: t.ApplicationStreamingStore; export let ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore; +export let SortedGuildStore: t.SortedGuildStore; +export let JoinedThreadsStore: t.JoinedThreadsStore; +export let SafetyHubStore: t.SafetyHubStore; +export let PrivateChannelSortStore: t.PrivateChannelSortStore; +export let UserProfileSettingsStore: t.UserProfileSettingsStore; +export let AuthorizedAppsStore: t.AuthorizedAppsStore; +export let ChannelSectionStore: t.ChannelSectionStore; +export let ClientThemesBackgroundStore: t.ClientThemesBackgroundStore; +export let ConnectedAccountsStore: t.ConnectedAccountsStore; +export let ChannelMemberStore: t.ChannelMemberStore; +export let ThreadMemberListStore: t.ThreadMemberListStore; +export let CollapsedVoiceChannelStore: t.CollapsedVoiceChannelStore; +export let ReferencedMessageStore: t.ReferencedMessageStore; +export let SessionsStore: t.SessionsStore; +export let UserGuildJoinRequestStore: t.UserGuildJoinRequestStore; +export let SelfPresenceStore: t.SelfPresenceStore; +export let MessageRequestStore: t.MessageRequestStore; +export let GIFPickerViewStore: t.GIFPickerViewStore; +export let GuildReadStateStore: t.GuildReadStateStore; /** * @see jsdoc of {@link t.useStateFromStores} @@ -144,6 +163,25 @@ waitForStore("ExperimentStore", m => ExperimentStore = m); waitForStore("UserAffinitiesV2Store", m => UserAffinitiesStore = m); waitForStore("ApplicationStreamingStore", m => ApplicationStreamingStore = m); waitForStore("ApplicationStreamPreviewStore", m => ApplicationStreamPreviewStore = m); +waitForStore("SortedGuildStore", m => SortedGuildStore = m); +waitForStore("JoinedThreadsStore", m => JoinedThreadsStore = m); +waitForStore("SafetyHubStore", m => SafetyHubStore = m); +waitForStore("PrivateChannelSortStore", m => PrivateChannelSortStore = m); +waitForStore("UserProfileSettingsStore", m => UserProfileSettingsStore = m); +waitForStore("AuthorizedAppsStore", m => AuthorizedAppsStore = m); +waitForStore("ChannelSectionStore", m => ChannelSectionStore = m); +waitForStore("ClientThemesBackgroundStore", m => ClientThemesBackgroundStore = m); +waitForStore("ConnectedAccountsStore", m => ConnectedAccountsStore = m); +waitForStore("ChannelMemberStore", m => ChannelMemberStore = m); +waitForStore("ThreadMemberListStore", m => ThreadMemberListStore = m); +waitForStore("CollapsedVoiceChannelStore", m => CollapsedVoiceChannelStore = m); +waitForStore("ReferencedMessageStore", m => ReferencedMessageStore = m); +waitForStore("SessionsStore", m => SessionsStore = m); +waitForStore("UserGuildJoinRequestStore", m => UserGuildJoinRequestStore = m); +waitForStore("SelfPresenceStore", m => SelfPresenceStore = m); +waitForStore("MessageRequestStore", m => MessageRequestStore = m); +waitForStore("GIFPickerViewStore", m => GIFPickerViewStore = m); +waitForStore("GuildReadStateStore", m => GuildReadStateStore = m); waitForStore("ThemeStore", m => { ThemeStore = m; // Importing this directly causes all webpack commons to be imported, which can easily cause circular dependencies.