diff --git a/src/components/Icons.tsx b/src/components/Icons.tsx
index 008a7a893..d329e043d 100644
--- a/src/components/Icons.tsx
+++ b/src/components/Icons.tsx
@@ -640,6 +640,20 @@ export function RightArrow(props: IconProps) {
);
}
+export function UploadIcon(props: IconProps) {
+ return (
+
+
+
+ );
+}
+
export function TopRightArrow(props: IconProps) {
return (
{
+ try {
+ if (!input.files) return;
+ await addAttachments(channelId, messageId, existingAttachmentCount, input.files);
+ } finally {
+ input.remove();
+ }
+ });
+}
+
+async function addAttachments(channelId: string, messageId: string, existingAttachmentCount: number, files: FileList) {
+ if (!files) return;
+
+ if (files.length + existingAttachmentCount > 10) {
+ const remaining = 10 - existingAttachmentCount;
+ if (remaining <= 0) {
+ showToast("You cannot add more attachments to this message.", Toasts.Type.FAILURE);
+ return;
+ }
+
+ showToast(`You can only add ${pluralise(remaining, "more attachment")} to this message.`, Toasts.Type.FAILURE);
+ return;
+ }
+
+ showToast("Uploading, this can take a while...", Toasts.Type.CLOCK);
+
+ const { body: { attachments } } = await RestAPI.post({
+ url: `/channels/${channelId}/attachments`,
+ body: {
+ files: Array.from(files, file => ({
+ filename: file.name,
+ file_size: file.size,
+ id: uniqueId(),
+ is_clip: false
+ }))
+ }
+ }) as { body: { attachments: { id: string, upload_url: string, upload_filename: string; }[]; }; };
+
+ const newAttachments = await Promise.all(
+ attachments.map((file, i) =>
+ fetch(file.upload_url, {
+ method: "PUT",
+ body: files[i]
+ }).then(() => ({
+ id: file.id,
+ uploaded_filename: file.upload_filename,
+ filename: files[i].name
+ }))
+ )
+ );
+
+
+ const msg = MessageStore.getMessage(channelId, messageId);
+
+ await RestAPI.patch({
+ url: `/channels/${channelId}/messages/${messageId}`,
+ body: {
+ attachments: [
+ ...msg.attachments,
+ ...newAttachments
+ ]
+ }
+ });
+
+ showToast(`${files.length === 1 ? "Attachment" : "Attachments"} added successfully!`, Toasts.Type.SUCCESS);
+}
+
+function canAddAttachments(msg: Message) {
+ return (
+ [MessageType.DEFAULT, MessageType.REPLY].includes(msg.type) &&
+ !msg.hasFlag(MessageFlags.IS_VOICE_MESSAGE) &&
+ AuthenticationStore.getId() === msg.author.id &&
+ msg.attachments.length < 10
+ );
+}
+
+function handlePaste(e: ClipboardEvent) {
+ if (!e.clipboardData?.files.length) return;
+
+ const msg = EditMessageStore.getEditingMessage(SelectedChannelStore.getChannelId());
+ if (!msg) return;
+
+ e.preventDefault();
+ e.stopImmediatePropagation();
+
+ addAttachments(msg.channel_id, msg.id, msg.attachments.length, e.clipboardData.files);
+}
+
+export default definePlugin({
+ name: "AddAttachments",
+ description: "Allows you to add new attachments while editing messages",
+ authors: [Devs.Lumap],
+
+ start() {
+ document.addEventListener("paste", handlePaste, { capture: true });
+ },
+ stop() {
+ document.removeEventListener("paste", handlePaste, { capture: true });
+ },
+
+ messagePopoverButton: {
+ icon: UploadIcon,
+ render(msg) {
+ if (!canAddAttachments(msg)) return null;
+
+ const channel = ChannelStore.getChannel(msg.channel_id);
+ if (!channel.isPrivate() && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, channel)) return null;
+
+ return {
+ label: "Add Attachments",
+ icon: UploadIcon,
+ message: msg,
+ channel: ChannelStore.getChannel(msg.channel_id),
+ onClick: () => chooseAttachments(msg.channel_id, msg.id, msg.attachments.length)
+ };
+ },
+ },
+
+ chatBarButton: {
+ icon: UploadIcon,
+ render({ channel, type }) {
+ if (type.analyticsName !== "edit") return null;
+
+ const msg = EditMessageStore.getEditingMessage(channel.id);
+ if (!msg || !canAddAttachments(msg)) return null;
+
+ return (
+ chooseAttachments(msg.channel_id, msg.id, msg.attachments.length)}
+ >
+
+
+ );
+ }
+ }
+});