improve various types (#3663)
Co-authored-by: V <vendicated@riseup.net> Co-authored-by: John Davis <70701251+gobuster@users.noreply.github.com> Co-authored-by: sadan4 <117494111+sadan4@users.noreply.github.com>
This commit is contained in:
parent
84957b0e88
commit
c38aac23fd
12 changed files with 128 additions and 40 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
|
export * from "./channel";
|
||||||
export * from "./commands";
|
export * from "./commands";
|
||||||
export * from "./messages";
|
export * from "./messages";
|
||||||
export * from "./channel";
|
export * from "./misc";
|
||||||
|
|
|
||||||
4
packages/discord-types/enums/misc.ts
Normal file
4
packages/discord-types/enums/misc.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
export const enum CloudUploadPlatform {
|
||||||
|
REACT_NATIVE = 0,
|
||||||
|
WEB = 1,
|
||||||
|
}
|
||||||
1
packages/discord-types/src/index.d.ts
vendored
1
packages/discord-types/src/index.d.ts
vendored
|
|
@ -4,6 +4,7 @@ export * from "./components";
|
||||||
export * from "./flux";
|
export * from "./flux";
|
||||||
export * from "./fluxEvents";
|
export * from "./fluxEvents";
|
||||||
export * from "./menu";
|
export * from "./menu";
|
||||||
|
export * from "./modules";
|
||||||
export * from "./stores";
|
export * from "./stores";
|
||||||
export * from "./utils";
|
export * from "./utils";
|
||||||
export * as Webpack from "../webpack";
|
export * as Webpack from "../webpack";
|
||||||
|
|
|
||||||
74
packages/discord-types/src/modules/CloudUpload.d.ts
vendored
Normal file
74
packages/discord-types/src/modules/CloudUpload.d.ts
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
import EventEmitter from "events";
|
||||||
|
import { CloudUploadPlatform } from "../../enums";
|
||||||
|
|
||||||
|
interface BaseUploadItem {
|
||||||
|
platform: CloudUploadPlatform;
|
||||||
|
id?: string;
|
||||||
|
origin?: string;
|
||||||
|
isThumbnail?: boolean;
|
||||||
|
clip?: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReactNativeUploadItem extends BaseUploadItem {
|
||||||
|
platform: CloudUploadPlatform.REACT_NATIVE;
|
||||||
|
uri: string;
|
||||||
|
filename?: string;
|
||||||
|
mimeType?: string;
|
||||||
|
durationSecs?: number;
|
||||||
|
waveform?: string;
|
||||||
|
isRemix?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WebUploadItem extends BaseUploadItem {
|
||||||
|
platform: CloudUploadPlatform.WEB;
|
||||||
|
file: File;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CloudUploadItem = ReactNativeUploadItem | WebUploadItem;
|
||||||
|
|
||||||
|
export class CloudUpload extends EventEmitter {
|
||||||
|
constructor(item: CloudUploadItem, channelId: string, showLargeMessageDialog?: boolean, reactNativeFileIndex?: number);
|
||||||
|
|
||||||
|
channelId: string;
|
||||||
|
classification: string;
|
||||||
|
clip: unknown;
|
||||||
|
contentHash: unknown;
|
||||||
|
currentSize: number;
|
||||||
|
description: string | null;
|
||||||
|
durationSecs: number | undefined;
|
||||||
|
etag: string | undefined;
|
||||||
|
error: unknown;
|
||||||
|
filename: string;
|
||||||
|
id: string;
|
||||||
|
isImage: boolean;
|
||||||
|
isRemix: boolean | undefined;
|
||||||
|
isThumbnail: boolean;
|
||||||
|
isVideo: boolean;
|
||||||
|
item: {
|
||||||
|
file: File;
|
||||||
|
platform: CloudUploadPlatform;
|
||||||
|
origin: string;
|
||||||
|
};
|
||||||
|
loaded: number;
|
||||||
|
mimeType: string;
|
||||||
|
origin: string;
|
||||||
|
postCompressionSize: number | undefined;
|
||||||
|
preCompressionSize: number;
|
||||||
|
responseUrl: string;
|
||||||
|
sensitive: boolean;
|
||||||
|
showLargeMessageDialog: boolean;
|
||||||
|
spoiler: boolean;
|
||||||
|
startTime: number;
|
||||||
|
status: "NOT_STARTED" | "STARTED" | "UPLOADING" | "ERROR" | "COMPLETED" | "CANCELLED" | "REMOVED_FROM_MSG_DRAFT";
|
||||||
|
uniqueId: string;
|
||||||
|
uploadedFilename: string;
|
||||||
|
waveform: string | undefined;
|
||||||
|
|
||||||
|
// there are many more methods than just these but I didn't find them particularly useful
|
||||||
|
upload(): Promise<void>;
|
||||||
|
cancel(): void;
|
||||||
|
delete(): Promise<void>;
|
||||||
|
getSize(): number;
|
||||||
|
maybeConvertToWebP(): Promise<void>;
|
||||||
|
removeFromMsgDraft(): void;
|
||||||
|
}
|
||||||
1
packages/discord-types/src/modules/index.d.ts
vendored
Normal file
1
packages/discord-types/src/modules/index.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "./CloudUpload";
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import type { Channel, CustomEmoji, Message } from "@vencord/discord-types";
|
import type { Channel, CloudUpload, CustomEmoji, Message } from "@vencord/discord-types";
|
||||||
import { MessageStore } from "@webpack/common";
|
import { MessageStore } from "@webpack/common";
|
||||||
import type { Promisable } from "type-fest";
|
import type { Promisable } from "type-fest";
|
||||||
|
|
||||||
|
|
@ -30,30 +30,6 @@ export interface MessageObject {
|
||||||
tts: boolean;
|
tts: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Upload {
|
|
||||||
classification: string;
|
|
||||||
currentSize: number;
|
|
||||||
description: string | null;
|
|
||||||
filename: string;
|
|
||||||
id: string;
|
|
||||||
isImage: boolean;
|
|
||||||
isVideo: boolean;
|
|
||||||
item: {
|
|
||||||
file: File;
|
|
||||||
platform: number;
|
|
||||||
};
|
|
||||||
loaded: number;
|
|
||||||
mimeType: string;
|
|
||||||
preCompressionSize: number;
|
|
||||||
responseUrl: string;
|
|
||||||
sensitive: boolean;
|
|
||||||
showLargeMessageDialog: boolean;
|
|
||||||
spoiler: boolean;
|
|
||||||
status: "NOT_STARTED" | "STARTED" | "UPLOADING" | "ERROR" | "COMPLETED" | "CANCELLED";
|
|
||||||
uniqueId: string;
|
|
||||||
uploadedFilename: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MessageReplyOptions {
|
export interface MessageReplyOptions {
|
||||||
messageReference: Message["messageReference"];
|
messageReference: Message["messageReference"];
|
||||||
allowedMentions?: {
|
allowedMentions?: {
|
||||||
|
|
@ -64,7 +40,7 @@ export interface MessageReplyOptions {
|
||||||
|
|
||||||
export interface MessageOptions {
|
export interface MessageOptions {
|
||||||
stickers?: string[];
|
stickers?: string[];
|
||||||
uploads?: Upload[];
|
uploads?: CloudUpload[];
|
||||||
replyOptions: MessageReplyOptions;
|
replyOptions: MessageReplyOptions;
|
||||||
content: string;
|
content: string;
|
||||||
channel: Channel;
|
channel: Channel;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,10 @@
|
||||||
* 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 ErrorBoundary from "@components/ErrorBoundary";
|
||||||
|
import { isPrimitiveReactNode } from "@utils/react";
|
||||||
import { waitFor } from "@webpack";
|
import { waitFor } from "@webpack";
|
||||||
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
let NoticesModule: any;
|
let NoticesModule: any;
|
||||||
waitFor(m => m.show && m.dismiss && !m.suppressAll, m => NoticesModule = m);
|
waitFor(m => m.show && m.dismiss && !m.suppressAll, m => NoticesModule = m);
|
||||||
|
|
@ -36,7 +39,11 @@ export function nextNotice() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showNotice(message: string, buttonText: string, onOkClick: () => void) {
|
export function showNotice(message: ReactNode, buttonText: string, onOkClick: () => void) {
|
||||||
noticesQueue.push(["GENERIC", message, buttonText, onOkClick]);
|
const notice = isPrimitiveReactNode(message)
|
||||||
|
? message
|
||||||
|
: <ErrorBoundary fallback={() => "Error Showing Notice"}>{message}</ErrorBoundary>;
|
||||||
|
|
||||||
|
noticesQueue.push(["GENERIC", notice, buttonText, onOkClick]);
|
||||||
if (!currentNotice) nextNotice();
|
if (!currentNotice) nextNotice();
|
||||||
}
|
}
|
||||||
|
|
@ -16,11 +16,11 @@
|
||||||
* 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 { Upload } from "@api/MessageEvents";
|
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
|
import { CloudUpload } from "@vencord/discord-types";
|
||||||
import { findByCodeLazy } from "@webpack";
|
import { findByCodeLazy } from "@webpack";
|
||||||
import { useState } from "@webpack/common";
|
import { useState } from "@webpack/common";
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
AnonymiseUploadButton: ErrorBoundary.wrap(({ upload }: { upload: Upload; }) => {
|
AnonymiseUploadButton: ErrorBoundary.wrap(({ upload }: { upload: CloudUpload; }) => {
|
||||||
const [anonymise, setAnonymise] = useState(upload[ANONYMISE_UPLOAD_SYMBOL] ?? settings.store.anonymiseByDefault);
|
const [anonymise, setAnonymise] = useState(upload[ANONYMISE_UPLOAD_SYMBOL] ?? settings.store.anonymiseByDefault);
|
||||||
|
|
||||||
function onToggleAnonymise() {
|
function onToggleAnonymise() {
|
||||||
|
|
@ -110,7 +110,7 @@ export default definePlugin({
|
||||||
);
|
);
|
||||||
}, { noop: true }),
|
}, { noop: true }),
|
||||||
|
|
||||||
anonymise(upload: Upload) {
|
anonymise(upload: CloudUpload) {
|
||||||
if ((upload[ANONYMISE_UPLOAD_SYMBOL] ?? settings.store.anonymiseByDefault) === false) {
|
if ((upload[ANONYMISE_UPLOAD_SYMBOL] ?? settings.store.anonymiseByDefault) === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import { ChatBarButton, ChatBarButtonFactory } from "@api/ChatButtons";
|
||||||
import { generateId, sendBotMessage } from "@api/Commands";
|
import { generateId, sendBotMessage } from "@api/Commands";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { StartAt } from "@utils/types";
|
import definePlugin, { StartAt } from "@utils/types";
|
||||||
import { MessageAttachment } from "@vencord/discord-types";
|
import { CloudUpload, MessageAttachment } from "@vencord/discord-types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByPropsLazy } from "@webpack";
|
||||||
import { DraftStore, DraftType, SelectedChannelStore, UserStore, useStateFromStores } from "@webpack/common";
|
import { DraftStore, DraftType, SelectedChannelStore, UserStore, useStateFromStores } from "@webpack/common";
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ const getImageBox = (url: string): Promise<{ width: number, height: number; } |
|
||||||
const getAttachments = async (channelId: string) =>
|
const getAttachments = async (channelId: string) =>
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
UploadStore.getUploads(channelId, DraftType.ChannelMessage)
|
UploadStore.getUploads(channelId, DraftType.ChannelMessage)
|
||||||
.map(async (upload: any) => {
|
.map(async (upload: CloudUpload) => {
|
||||||
const { isImage, filename, spoiler, item: { file } } = upload;
|
const { isImage, filename, spoiler, item: { file } } = upload;
|
||||||
const url = URL.createObjectURL(file);
|
const url = URL.createObjectURL(file);
|
||||||
const attachment: MessageAttachment = {
|
const attachment: MessageAttachment = {
|
||||||
|
|
@ -53,7 +53,7 @@ const getAttachments = async (channelId: string) =>
|
||||||
filename: spoiler ? "SPOILER_" + filename : filename,
|
filename: spoiler ? "SPOILER_" + filename : filename,
|
||||||
// weird eh? if i give it the normal content type the preview doenst work
|
// weird eh? if i give it the normal content type the preview doenst work
|
||||||
content_type: undefined,
|
content_type: undefined,
|
||||||
size: await upload.getSize(),
|
size: upload.getSize(),
|
||||||
spoiler,
|
spoiler,
|
||||||
// discord adds query params to the url, so we need to add a hash to prevent that
|
// discord adds query params to the url, so we need to add a hash to prevent that
|
||||||
url: url + "#",
|
url: url + "#",
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModa
|
||||||
import { useAwaiter } from "@utils/react";
|
import { useAwaiter } from "@utils/react";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { chooseFile } from "@utils/web";
|
import { chooseFile } from "@utils/web";
|
||||||
|
import { CloudUpload as TCloudUpload } from "@vencord/discord-types";
|
||||||
|
import { CloudUploadPlatform } from "@vencord/discord-types/enums";
|
||||||
import { findByPropsLazy, findLazy, findStoreLazy } from "@webpack";
|
import { findByPropsLazy, findLazy, findStoreLazy } from "@webpack";
|
||||||
import { Button, Card, Constants, FluxDispatcher, Forms, lodash, Menu, MessageActions, PermissionsBits, PermissionStore, RestAPI, SelectedChannelStore, showToast, SnowflakeUtils, Toasts, useEffect, useState } from "@webpack/common";
|
import { Button, Card, Constants, FluxDispatcher, Forms, lodash, Menu, MessageActions, PermissionsBits, PermissionStore, RestAPI, SelectedChannelStore, showToast, SnowflakeUtils, Toasts, useEffect, useState } from "@webpack/common";
|
||||||
import { ComponentType } from "react";
|
import { ComponentType } from "react";
|
||||||
|
|
@ -37,7 +39,7 @@ import { cl } from "./utils";
|
||||||
import { VoicePreview } from "./VoicePreview";
|
import { VoicePreview } from "./VoicePreview";
|
||||||
import { VoiceRecorderWeb } from "./WebRecorder";
|
import { VoiceRecorderWeb } from "./WebRecorder";
|
||||||
|
|
||||||
const CloudUpload = findLazy(m => m.prototype?.trackUploadFinished);
|
const CloudUpload: typeof TCloudUpload = findLazy(m => m.prototype?.trackUploadFinished);
|
||||||
const PendingReplyStore = findStoreLazy("PendingReplyStore");
|
const PendingReplyStore = findStoreLazy("PendingReplyStore");
|
||||||
const OptionClasses = findByPropsLazy("optionName", "optionIcon", "optionLabel");
|
const OptionClasses = findByPropsLazy("optionName", "optionIcon", "optionLabel");
|
||||||
|
|
||||||
|
|
@ -92,8 +94,8 @@ function sendAudio(blob: Blob, meta: AudioMetadata) {
|
||||||
const upload = new CloudUpload({
|
const upload = new CloudUpload({
|
||||||
file: new File([blob], "voice-message.ogg", { type: "audio/ogg; codecs=opus" }),
|
file: new File([blob], "voice-message.ogg", { type: "audio/ogg; codecs=opus" }),
|
||||||
isThumbnail: false,
|
isThumbnail: false,
|
||||||
platform: 1,
|
platform: CloudUploadPlatform.WEB,
|
||||||
}, channelId, false, 0);
|
}, channelId);
|
||||||
|
|
||||||
upload.on("complete", () => {
|
upload.on("complete", () => {
|
||||||
RestAPI.post({
|
RestAPI.post({
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { MessageObject } from "@api/MessageEvents";
|
import { MessageObject } from "@api/MessageEvents";
|
||||||
import { Channel, Guild, GuildFeatures, Message, User } from "@vencord/discord-types";
|
import { Channel, CloudUpload, Guild, GuildFeatures, Message, User } from "@vencord/discord-types";
|
||||||
import { ChannelActionCreators, ChannelStore, ComponentDispatch, Constants, FluxDispatcher, GuildStore, i18n, IconUtils, InviteActions, MessageActions, RestAPI, SelectedChannelStore, SelectedGuildStore, UserProfileActions, UserProfileStore, UserSettingsActionCreators, UserUtils } from "@webpack/common";
|
import { ChannelActionCreators, ChannelStore, ComponentDispatch, Constants, FluxDispatcher, GuildStore, i18n, IconUtils, InviteActions, MessageActions, RestAPI, SelectedChannelStore, SelectedGuildStore, UserProfileActions, UserProfileStore, UserSettingsActionCreators, UserUtils } from "@webpack/common";
|
||||||
import { Except } from "type-fest";
|
import { Except } from "type-fest";
|
||||||
|
|
||||||
|
|
@ -117,6 +117,20 @@ interface MessageOptions {
|
||||||
replied_user: boolean;
|
replied_user: boolean;
|
||||||
};
|
};
|
||||||
stickerIds: string[];
|
stickerIds: string[];
|
||||||
|
attachmentsToUpload: CloudUpload[];
|
||||||
|
poll: {
|
||||||
|
allow_multiselect: boolean;
|
||||||
|
answers: Array<{
|
||||||
|
poll_media: {
|
||||||
|
text: string;
|
||||||
|
attachment_ids?: unknown;
|
||||||
|
emoji?: { name: string; id?: string; };
|
||||||
|
};
|
||||||
|
}>;
|
||||||
|
duration: number;
|
||||||
|
layout_type: number;
|
||||||
|
question: { text: string; };
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sendMessage(
|
export function sendMessage(
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { React, useEffect, useMemo, useReducer, useState } from "@webpack/common";
|
import { React, useEffect, useMemo, useReducer, useState } from "@webpack/common";
|
||||||
import { ActionDispatch } from "react";
|
import { ActionDispatch, ReactNode } from "react";
|
||||||
|
|
||||||
import { checkIntersecting } from "./misc";
|
import { checkIntersecting } from "./misc";
|
||||||
|
|
||||||
|
|
@ -25,6 +25,14 @@ export * from "./lazyReact";
|
||||||
|
|
||||||
export const NoopComponent = () => null;
|
export const NoopComponent = () => null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a React node is a primitive (string, number, bigint, boolean, undefined)
|
||||||
|
*/
|
||||||
|
export function isPrimitiveReactNode(node: ReactNode): boolean {
|
||||||
|
const t = typeof node;
|
||||||
|
return t === "string" || t === "number" || t === "bigint" || t === "boolean" || t === "undefined";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if an element is on screen
|
* Check if an element is on screen
|
||||||
* @param intersectOnly If `true`, will only update the state when the element comes into view
|
* @param intersectOnly If `true`, will only update the state when the element comes into view
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue