FileUpload: add upload on paste (#1025)

* FileUpload: add upload on paste
- also change the wording of some settings

* FileUpload: bypass discord uploads on by default
This commit is contained in:
Key 2026-04-28 12:44:05 +01:00 • committed by GitHub
parent fbcb725428
commit e53f1221eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 45 additions and 12 deletions

View file

@ -22,6 +22,7 @@ import { cancelCurrentUpload, getUploadState, isConfigured, subscribeUploadState
const cl = classNameFactory("vc-file-upload-");
const { getUserMaxFileSize } = findByPropsLazy("getUserMaxFileSize");
let uploadAddFilesInterceptor: ((event: unknown) => void) | null = null;
let pasteEventListener: ((event: ClipboardEvent) => void) | null = null;
type UploadAddFilesEvent = {
type: string;
@ -37,7 +38,7 @@ type UploadAddFilesEvent = {
};
function shouldInterceptUploadFiles(files: readonly File[], payload: UploadAddFilesEvent): boolean {
if (!settings.store.interceptDiscordUploadOnlyOverLimit) return true;
if (!settings.store.bypassDiscordUploadOnlyOverLimit) return true;
const directLimit = [payload.maxFileSize, payload.fileSizeLimit, payload.limits?.fileSize].find(limit => Number.isFinite(limit)) as number | undefined;
const fallbackLimit = getUserMaxFileSize(UserStore.getCurrentUser());
@ -91,6 +92,18 @@ function interceptUploadAddFiles(event: unknown): void {
void uploadProvidedFiles(uniqueFiles);
}
function handlePaste(event: ClipboardEvent) {
const files = Array.from(event.clipboardData?.files || []);
if (files.length === 0) return;
if (!settings.store.autoUploadPastedFiles || !isConfigured()) return;
event.preventDefault();
event.stopPropagation();
void uploadProvidedFiles(files);
}
const ProgressBarInner = () => {
const [state, setState] = useState(getUploadState);
@ -248,6 +261,9 @@ export default definePlugin({
uploadAddFilesInterceptor = event => interceptUploadAddFiles(event);
FluxDispatcher.addInterceptor(uploadAddFilesInterceptor);
pasteEventListener = event => handlePaste(event);
document.addEventListener("paste", pasteEventListener, true);
},
stop() {
if (!uploadAddFilesInterceptor) {
@ -260,6 +276,11 @@ export default definePlugin({
}
uploadAddFilesInterceptor = null;
if (pasteEventListener) {
document.removeEventListener("paste", pasteEventListener, true);
pasteEventListener = null;
}
},
shouldBypassDiscordUploadSizeCheck(): boolean {
return Boolean((settings.store as { interceptDiscordUpload?: boolean; }).interceptDiscordUpload) && isConfigured();

View file

@ -172,15 +172,15 @@ export const settings = definePluginSettings({
default: false,
hidden: true
},
interceptDiscordUpload: {
bypassDiscordUpload: {
type: OptionType.BOOLEAN,
description: "Intercept Discord uploads and use FileUpload instead.",
default: false,
description: "Bypass Discord uploads and use FileUpload instead.",
default: true,
hidden: true
},
interceptDiscordUploadOnlyOverLimit: {
bypassDiscordUploadOnlyOverLimit: {
type: OptionType.BOOLEAN,
description: "Only intercept uploads that exceed Discord file size limit.",
description: "Only use FileUpload if the file(s) exceed the file size limit.",
default: true,
hidden: true
},
@ -239,6 +239,11 @@ export const settings = definePluginSettings({
default: true,
hidden: true
},
autoUploadPastedFiles: {
type: OptionType.BOOLEAN,
description: "Automatically upload files from clipboard to image host when pasting in chat input.",
default: false
},
settingsComponent: {
type: OptionType.COMPONENT,
description: "Settings",
@ -592,17 +597,24 @@ export function SettingsComponent() {
/>
</SettingsSection>
<SettingsSection tag="label" name="Intercept Discord Upload Button" description="Use FileUpload when uploading through Discord's file picker" inlineSetting>
<SettingsSection tag="label" name="Bypass Discord Upload Button" description="Use FileUpload when uploading through Discord's file picker" inlineSetting>
<Switch
checked={Boolean((store as { interceptDiscordUpload?: boolean; }).interceptDiscordUpload)}
onChange={v => (store as { interceptDiscordUpload?: boolean; }).interceptDiscordUpload = v}
checked={Boolean((store as { bypassDiscordUpload?: boolean; }).bypassDiscordUpload)}
onChange={v => (store as { bypassDiscordUpload?: boolean; }).bypassDiscordUpload = v}
/>
</SettingsSection>
<SettingsSection tag="label" name="Only Intercept Over Discord File Size Limit" description="Use FileUpload only for files larger than your current Discord upload limit" inlineSetting>
<SettingsSection tag="label" name="Auto Upload Pasted Files" description="Automatically upload files from clipboard to image host when pasting in chat input" inlineSetting>
<Switch
checked={store.interceptDiscordUploadOnlyOverLimit}
onChange={v => store.interceptDiscordUploadOnlyOverLimit = v}
checked={store.autoUploadPastedFiles}
onChange={v => store.autoUploadPastedFiles = v}
/>
</SettingsSection>
<SettingsSection tag="label" name="Respect Discord File Size Limit" description="Use FileUpload only for files larger than your current Discord upload limit" inlineSetting>
<Switch
checked={store.bypassDiscordUploadOnlyOverLimit}
onChange={v => store.bypassDiscordUploadOnlyOverLimit = v}
/>
</SettingsSection>