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 "./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 "./fluxEvents";
|
||||
export * from "./menu";
|
||||
export * from "./modules";
|
||||
export * from "./stores";
|
||||
export * from "./utils";
|
||||
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 type { Channel, CustomEmoji, Message } from "@vencord/discord-types";
|
||||
import type { Channel, CloudUpload, CustomEmoji, Message } from "@vencord/discord-types";
|
||||
import { MessageStore } from "@webpack/common";
|
||||
import type { Promisable } from "type-fest";
|
||||
|
||||
|
|
@ -30,30 +30,6 @@ export interface MessageObject {
|
|||
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 {
|
||||
messageReference: Message["messageReference"];
|
||||
allowedMentions?: {
|
||||
|
|
@ -64,7 +40,7 @@ export interface MessageReplyOptions {
|
|||
|
||||
export interface MessageOptions {
|
||||
stickers?: string[];
|
||||
uploads?: Upload[];
|
||||
uploads?: CloudUpload[];
|
||||
replyOptions: MessageReplyOptions;
|
||||
content: string;
|
||||
channel: Channel;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,10 @@
|
|||
* 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 { ReactNode } from "react";
|
||||
|
||||
let NoticesModule: any;
|
||||
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) {
|
||||
noticesQueue.push(["GENERIC", message, buttonText, onOkClick]);
|
||||
export function showNotice(message: ReactNode, buttonText: string, onOkClick: () => void) {
|
||||
const notice = isPrimitiveReactNode(message)
|
||||
? message
|
||||
: <ErrorBoundary fallback={() => "Error Showing Notice"}>{message}</ErrorBoundary>;
|
||||
|
||||
noticesQueue.push(["GENERIC", notice, buttonText, onOkClick]);
|
||||
if (!currentNotice) nextNotice();
|
||||
}
|
||||
|
|
@ -16,11 +16,11 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Upload } from "@api/MessageEvents";
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { CloudUpload } from "@vencord/discord-types";
|
||||
import { findByCodeLazy } from "@webpack";
|
||||
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);
|
||||
|
||||
function onToggleAnonymise() {
|
||||
|
|
@ -110,7 +110,7 @@ export default definePlugin({
|
|||
);
|
||||
}, { noop: true }),
|
||||
|
||||
anonymise(upload: Upload) {
|
||||
anonymise(upload: CloudUpload) {
|
||||
if ((upload[ANONYMISE_UPLOAD_SYMBOL] ?? settings.store.anonymiseByDefault) === false) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import { ChatBarButton, ChatBarButtonFactory } from "@api/ChatButtons";
|
|||
import { generateId, sendBotMessage } from "@api/Commands";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin, { StartAt } from "@utils/types";
|
||||
import { MessageAttachment } from "@vencord/discord-types";
|
||||
import { CloudUpload, MessageAttachment } from "@vencord/discord-types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
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) =>
|
||||
await Promise.all(
|
||||
UploadStore.getUploads(channelId, DraftType.ChannelMessage)
|
||||
.map(async (upload: any) => {
|
||||
.map(async (upload: CloudUpload) => {
|
||||
const { isImage, filename, spoiler, item: { file } } = upload;
|
||||
const url = URL.createObjectURL(file);
|
||||
const attachment: MessageAttachment = {
|
||||
|
|
@ -53,7 +53,7 @@ const getAttachments = async (channelId: string) =>
|
|||
filename: spoiler ? "SPOILER_" + filename : filename,
|
||||
// weird eh? if i give it the normal content type the preview doenst work
|
||||
content_type: undefined,
|
||||
size: await upload.getSize(),
|
||||
size: upload.getSize(),
|
||||
spoiler,
|
||||
// discord adds query params to the url, so we need to add a hash to prevent that
|
||||
url: url + "#",
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModa
|
|||
import { useAwaiter } from "@utils/react";
|
||||
import definePlugin from "@utils/types";
|
||||
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 { Button, Card, Constants, FluxDispatcher, Forms, lodash, Menu, MessageActions, PermissionsBits, PermissionStore, RestAPI, SelectedChannelStore, showToast, SnowflakeUtils, Toasts, useEffect, useState } from "@webpack/common";
|
||||
import { ComponentType } from "react";
|
||||
|
|
@ -37,7 +39,7 @@ import { cl } from "./utils";
|
|||
import { VoicePreview } from "./VoicePreview";
|
||||
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 OptionClasses = findByPropsLazy("optionName", "optionIcon", "optionLabel");
|
||||
|
||||
|
|
@ -92,8 +94,8 @@ function sendAudio(blob: Blob, meta: AudioMetadata) {
|
|||
const upload = new CloudUpload({
|
||||
file: new File([blob], "voice-message.ogg", { type: "audio/ogg; codecs=opus" }),
|
||||
isThumbnail: false,
|
||||
platform: 1,
|
||||
}, channelId, false, 0);
|
||||
platform: CloudUploadPlatform.WEB,
|
||||
}, channelId);
|
||||
|
||||
upload.on("complete", () => {
|
||||
RestAPI.post({
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
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 { Except } from "type-fest";
|
||||
|
||||
|
|
@ -117,6 +117,20 @@ interface MessageOptions {
|
|||
replied_user: boolean;
|
||||
};
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
import { React, useEffect, useMemo, useReducer, useState } from "@webpack/common";
|
||||
import { ActionDispatch } from "react";
|
||||
import { ActionDispatch, ReactNode } from "react";
|
||||
|
||||
import { checkIntersecting } from "./misc";
|
||||
|
||||
|
|
@ -25,6 +25,14 @@ export * from "./lazyReact";
|
|||
|
||||
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
|
||||
* @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