Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: addAttachments #3202

Open
wants to merge 12 commits into
base: dev
Choose a base branch
from
14 changes: 14 additions & 0 deletions src/components/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -434,3 +434,17 @@ export function WebsiteIcon(props: IconProps) {
</Icon>
);
}

export function UploadIcon(props: IconProps) {
return (
<Icon
{...props}
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M12 23a11 11 0 1 0 0-22 11 11 0 0 0 0 22Zm0-17a1 1 0 0 1 1 1v4h4a1 1 0 1 1 0 2h-4v4a1 1 0 1 1-2 0v-4H7a1 1 0 1 1 0-2h4V7a1 1 0 0 1 1-1Z"
/>
</Icon>
);
}
4 changes: 4 additions & 0 deletions src/plugins/addAttachments/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# AddAttachments

Add attachments to an existing message of yours.
![](https://github.com/user-attachments/assets/6a98da9d-40a5-4cdb-8dfd-146ec5c2dcb6)
96 changes: 96 additions & 0 deletions src/plugins/addAttachments/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2025 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/

import { UploadIcon } from "@components/Icons";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { ChannelStore, MessageStore, PermissionsBits, PermissionStore, SelectedChannelStore, showToast, Toasts, UserStore } from "@webpack/common";
import { Common, findByPropsLazy } from "webpack";

const uniqueIdProp = findByPropsLazy("uniqueId");

export default definePlugin({
name: "AddAttachments",
description: "Allows you to add attachments to a pre-existing message of yours",
authors: [Devs.Lumap],

renderMessagePopoverButton(msg) {
if (UserStore.getCurrentUser().id !== msg.author.id || msg.attachments.length === 10) return null;

const currChannel = ChannelStore.getChannel(SelectedChannelStore.getChannelId());
if (currChannel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, currChannel)) return null;

if (![0, 19].includes(msg.type) || msg.hasFlag(8192)) return null;

return {
label: "Add attachments",
icon: UploadIcon,
message: msg,
channel: ChannelStore.getChannel(msg.channel_id),
onClick: () => this.addAttachments(msg.channel_id, msg.id, msg.attachments.length)
};
},

addAttachments(channelId: string, messageId: string, messageAttachments: number) {
const input = document.createElement("input");
input.type = "file";
input.accept = "*/*";
input.multiple = true;
input.click();

input.addEventListener("change", async () => {
if (!input.files) return input.remove();

if ((10 - messageAttachments) < input.files.length) {
showToast(`You can only add ${10 - messageAttachments} more attachments to this message.`, Toasts.Type.FAILURE);
return input.remove();
}

showToast("Uploading, this can take a while...", Toasts.Type.CLOCK);

const files = Array.from(input.files).map(file => ({
filename: file.name,
file_size: file.size,
id: uniqueIdProp.uniqueId(),
is_clip: false
}));

const attachmentsReq = (await Common.RestAPI.post({
url: `/channels/${channelId}/attachments`,
body: { files }
})).body.attachments as { id: string, upload_url: string, upload_filename: string }[];

const uploadPromises = attachmentsReq.map((uploadedFile, index) =>
fetch(uploadedFile.upload_url, {
method: "PUT",
body: input.files![index]
}).then(() => ({
id: uploadedFile.id,
uploaded_filename: uploadedFile.upload_filename,
filename: input.files![index].name
}))
);

const newAttachments = await Promise.all(uploadPromises);

const msg = MessageStore.getMessage(channelId, messageId);

await Common.RestAPI.patch({
url: `/channels/${channelId}/messages/${messageId}`,
body: {
attachments: [
...msg.attachments,
...newAttachments
]
}
});

showToast("Attachments added successfully!", Toasts.Type.SUCCESS);

input.remove();
});
}
});