diff --git a/client/components/Windows/Settings.vue b/client/components/Windows/Settings.vue
index d7b1788a..6420e88a 100644
--- a/client/components/Windows/Settings.vue
+++ b/client/components/Windows/Settings.vue
@@ -229,6 +229,29 @@
+
+
File uploads
+
+
+
+
+
Push Notifications
diff --git a/client/js/settings.js b/client/js/settings.js
index 2772abe5..fc2c1cc7 100644
--- a/client/js/settings.js
+++ b/client/js/settings.js
@@ -92,6 +92,9 @@ export const config = normalizeConfig({
media: {
default: true,
},
+ uploadCanvas: {
+ default: true,
+ },
userStyles: {
default: "",
apply(store, value) {
diff --git a/client/js/upload.js b/client/js/upload.js
index 85f7da3c..3b2e164c 100644
--- a/client/js/upload.js
+++ b/client/js/upload.js
@@ -130,6 +130,48 @@ class Uploader {
uploadNextFileInQueue(token) {
const file = this.fileQueue.shift();
+
+ if (
+ store.state.settings.uploadCanvas &&
+ file.type.startsWith("image/") &&
+ !file.type.includes("svg")
+ ) {
+ this.renderImage(file, (newFile) => this.performUpload(token, newFile));
+ } else {
+ this.performUpload(token, file);
+ }
+ }
+
+ renderImage(file, callback) {
+ const fileReader = new FileReader();
+
+ fileReader.onabort = () => callback(file);
+ fileReader.onerror = () => fileReader.abort();
+
+ fileReader.onload = () => {
+ const img = new Image();
+
+ img.onerror = () => callback(file);
+
+ img.onload = () => {
+ const canvas = document.createElement("canvas");
+ canvas.width = img.width;
+ canvas.height = img.height;
+ const ctx = canvas.getContext("2d");
+ ctx.drawImage(img, 0, 0);
+
+ canvas.toBlob((blob) => {
+ callback(new File([blob], file.name));
+ }, file.type);
+ };
+
+ img.src = fileReader.result;
+ };
+
+ fileReader.readAsDataURL(file);
+ }
+
+ performUpload(token, file) {
this.xhr = new XMLHttpRequest();
this.xhr.upload.addEventListener(