diff --git a/src/equicordplugins/fileUpload/index.tsx b/src/equicordplugins/fileUpload/index.tsx
index 4a59451aa..0cd895db2 100644
--- a/src/equicordplugins/fileUpload/index.tsx
+++ b/src/equicordplugins/fileUpload/index.tsx
@@ -74,7 +74,7 @@ function interceptUploadAddFiles(event: unknown): void {
if (payload.draftType !== DraftType.ChannelMessage) return;
- if (!Boolean((settings.store as { interceptDiscordUpload?: boolean; }).interceptDiscordUpload) || !isConfigured()) return;
+ if (!settings.store.bypassDiscordUpload || !isConfigured()) return;
const files = [
...extractFilesFromValue(payload.files),
@@ -283,7 +283,7 @@ export default definePlugin({
}
},
shouldBypassDiscordUploadSizeCheck(): boolean {
- return Boolean((settings.store as { interceptDiscordUpload?: boolean; }).interceptDiscordUpload) && isConfigured();
+ return Boolean(settings.store.bypassDiscordUpload) && isConfigured();
},
renderUploadProgress() {
return ;
diff --git a/src/equicordplugins/fileUpload/native.ts b/src/equicordplugins/fileUpload/native.ts
index 1cd40c374..ad401217d 100644
--- a/src/equicordplugins/fileUpload/native.ts
+++ b/src/equicordplugins/fileUpload/native.ts
@@ -418,6 +418,46 @@ export async function uploadToPixelVault(
}
}
+export async function uploadToPixelDrain(
+ _: IpcMainInvokeEvent,
+ fileBuffer: ArrayBuffer,
+ filename: string,
+ apiKey?: string
+): Promise {
+ try {
+ const headers: Record = {};
+ if (apiKey?.trim()) {
+ headers.Authorization = `Basic ${Buffer.from(`:${apiKey.trim()}`).toString("base64")}`;
+ }
+
+ const response = await fetch(`https://pixeldrain.com/api/file/${encodeURIComponent(filename)}`, {
+ method: "PUT",
+ headers,
+ body: new Blob([fileBuffer])
+ });
+
+ const text = await response.text();
+ let data: { id?: string; message?: string; } | null = null;
+ try {
+ data = text ? JSON.parse(text) : null;
+ } catch {
+ data = null;
+ }
+
+ if (!response.ok) {
+ return { success: false, error: data?.message || `Upload failed: ${response.status} ${text}` };
+ }
+
+ if (!data?.id) {
+ return { success: false, error: data?.message || "No URL returned from upload" };
+ }
+
+ return { success: true, url: `https://pixeldrain.com/u/${data.id}` };
+ } catch (e) {
+ return { success: false, error: e instanceof Error ? e.message : "Unknown error" };
+ }
+}
+
export async function fetchFile(
_: IpcMainInvokeEvent,
diff --git a/src/equicordplugins/fileUpload/settings.tsx b/src/equicordplugins/fileUpload/settings.tsx
index 234b8d85c..896a3e7df 100644
--- a/src/equicordplugins/fileUpload/settings.tsx
+++ b/src/equicordplugins/fileUpload/settings.tsx
@@ -34,6 +34,7 @@ const serviceOptions = [
{ label: "temp.sh", value: ServiceType.TEMPSH },
{ label: "filebin.net", value: ServiceType.FILEBIN },
{ label: "PixelVault", value: ServiceType.PIXELVAULT },
+ { label: "PixelDrain", value: ServiceType.PIXELDRAIN },
{ label: "ShareX Custom Uploader", value: ServiceType.SHAREX }
];
@@ -207,6 +208,12 @@ export const settings = definePluginSettings({
default: "",
hidden: true
},
+ pixelDrainKey: {
+ type: OptionType.STRING,
+ description: "Optional PixelDrain API key",
+ default: "",
+ hidden: true
+ },
uploadTimeoutMs: {
type: OptionType.NUMBER,
description: "Upload timeout in milliseconds",
@@ -366,6 +373,7 @@ export function SettingsComponent() {
const isLitterbox = store.serviceType === ServiceType.LITTERBOX;
const isGofile = store.serviceType === ServiceType.GOFILE;
const isPixelVault = store.serviceType === ServiceType.PIXELVAULT;
+ const isPixelDrain = store.serviceType === ServiceType.PIXELDRAIN;
const isShareX = store.serviceType === ServiceType.SHAREX;
const validateShareXConfig = () => {
@@ -576,6 +584,16 @@ export function SettingsComponent() {
/>
)}
+ {isPixelDrain && (
+ store.pixelDrainKey = v}
+ placeholder="Your PixelDrain API key"
+ />
+ )}
+
{isShareX && (
<>
= {
@@ -35,7 +36,8 @@ export const serviceLabels: Record = {
[ServiceType.BUZZHEAVIER]: "buzzheavier.com",
[ServiceType.TEMPSH]: "temp.sh",
[ServiceType.FILEBIN]: "filebin.net",
- [ServiceType.PIXELVAULT]: "PixelVault"
+ [ServiceType.PIXELVAULT]: "PixelVault",
+ [ServiceType.PIXELDRAIN]: "PixelDrain"
};
export const fallbackServiceOrder: ServiceType[] = [
@@ -52,6 +54,7 @@ export const fallbackServiceOrder: ServiceType[] = [
ServiceType.TEMPSH,
ServiceType.FILEBIN,
ServiceType.PIXELVAULT,
+ ServiceType.PIXELDRAIN,
ServiceType.SHAREX
];
diff --git a/src/equicordplugins/fileUpload/utils/upload.ts b/src/equicordplugins/fileUpload/utils/upload.ts
index f70b9e188..78d3518b3 100644
--- a/src/equicordplugins/fileUpload/utils/upload.ts
+++ b/src/equicordplugins/fileUpload/utils/upload.ts
@@ -374,6 +374,7 @@ export function isConfigured(): boolean {
case ServiceType.BUZZHEAVIER:
case ServiceType.TEMPSH:
case ServiceType.FILEBIN:
+ case ServiceType.PIXELDRAIN:
return true;
case ServiceType.PIXELVAULT:
return Boolean((settings.store as { pixelVaultKey?: string; }).pixelVaultKey);
@@ -714,6 +715,45 @@ async function uploadToPixelVault(fileBlob: Blob, filename: string): Promise {
+ const { pixelDrainKey } = settings.store as { pixelDrainKey?: string; };
+
+ if (Native) {
+ const result = await Native.uploadToPixelDrain(await fileBlob.arrayBuffer(), filename, pixelDrainKey?.trim() || undefined);
+ if (!result.success || !result.url) throw new Error(result.error || "No URL returned from upload");
+ return result.url;
+ }
+
+ const headers: Record = {};
+ if (pixelDrainKey?.trim()) {
+ headers.Authorization = `Basic ${btoa(`:${pixelDrainKey.trim()}`)}`;
+ }
+
+ const response = await fetchWithTimeout(`https://pixeldrain.com/api/file/${encodeURIComponent(filename)}`, {
+ method: "PUT",
+ headers,
+ body: fileBlob
+ });
+
+ const text = await response.text();
+ let data: { id?: string; success?: boolean; message?: string; } | null = null;
+ try {
+ data = text ? JSON.parse(text) : null;
+ } catch {
+ data = null;
+ }
+
+ if (!response.ok) {
+ throw new Error(data?.message || `Upload failed: ${response.status} ${text}`);
+ }
+
+ if (!data?.id) {
+ throw new Error(data?.message || "No URL returned from upload");
+ }
+
+ return `https://pixeldrain.com/u/${data.id}`;
+}
+
async function uploadToService(serviceType: ServiceType, fileBlob: Blob, filename: string): Promise {
switch (serviceType) {
case ServiceType.ZIPLINE:
@@ -744,6 +784,8 @@ async function uploadToService(serviceType: ServiceType, fileBlob: Blob, filenam
return uploadToFilebin(fileBlob, filename);
case ServiceType.PIXELVAULT:
return uploadToPixelVault(fileBlob, filename);
+ case ServiceType.PIXELDRAIN:
+ return uploadToPixelDrain(fileBlob, filename);
default:
throw new Error("Unknown service type");
}