FEATURE: Change all core to use uppy-image-uploader (#14428)

FEATURE: Change all core to use uppy-image-uploader (#14428)

Instead of using image-uploader, which relies on the old UploadMixin, we can now use the uppy-image-uploader which uses the new UppyUploadMixin which is stable enough and supports both regular XHR uploads and direct S3 uploads, controlled by a site setting (default to XHR).

At some point it may make sense to rename uppy-image-uploader back to image-uploader, once we have gone through plugins etc. and given a bit of deprecation time period.

This commit also fixes for_private_message, for_site_setting, and pasted flags not being sent via uppy uploads onto the UploadCreator, both via regular XHR uploads and also through external/multipart uploads.

The uploaders changed are:

  • site setting images
  • badge images
  • category logo
  • category background
  • group flair
  • profile background
  • profile card background
diff --git a/app/assets/javascripts/admin/addon/components/site-settings-image-uploader.js b/app/assets/javascripts/admin/addon/components/site-settings-image-uploader.js
deleted file mode 100644
index 3e19fa8..0000000
--- a/app/assets/javascripts/admin/addon/components/site-settings-image-uploader.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import ImageUploader from "discourse/components/image-uploader";
-
-export default ImageUploader.extend({
-  layoutName: "components/image-uploader",
-  uploadUrlParams: "&for_site_setting=true",
-});
diff --git a/app/assets/javascripts/admin/addon/templates/badges-show.hbs b/app/assets/javascripts/admin/addon/templates/badges-show.hbs
index 736d1b8..a1260d0 100644
--- a/app/assets/javascripts/admin/addon/templates/badges-show.hbs
+++ b/app/assets/javascripts/admin/addon/templates/badges-show.hbs
@@ -40,12 +40,14 @@
         </label>
       </div>
       {{#if imageUploaderSelected}}
-        {{image-uploader
+        {{uppy-image-uploader
+          id="badge-image-uploader"
           imageUrl=buffered.image_url
+          type="badge_image"
           onUploadDone=(action "setImage")
           onUploadDeleted=(action "removeImage")
-          type="badge_image"
-          class="no-repeat contain-image"}}
+          class="no-repeat contain-image"
+        }}
         <div class="control-instructions">
           <p class="help">{{i18n "admin.badges.image_help"}}</p>
         </div>
diff --git a/app/assets/javascripts/admin/addon/templates/components/site-settings/upload.hbs b/app/assets/javascripts/admin/addon/templates/components/site-settings/upload.hbs
index 652f773..78a64c2 100644
--- a/app/assets/javascripts/admin/addon/templates/components/site-settings/upload.hbs
+++ b/app/assets/javascripts/admin/addon/templates/components/site-settings/upload.hbs
@@ -1,2 +1,8 @@
-{{site-settings-image-uploader imageUrl=value placeholderUrl=setting.placeholder type="site_setting"}}
+{{uppy-image-uploader
+  imageUrl=value
+  placeholderUrl=setting.placeholder
+  additionalParams=(hash for_site_setting=true)
+  type="site_setting"
+  id=(concat "site-setting-image-uploader-" setting.setting)
+}}
 <div class="desc">{{html-safe setting.description}}</div>
diff --git a/app/assets/javascripts/discourse/app/components/image-uploader.js b/app/assets/javascripts/discourse/app/components/image-uploader.js
index 441ec4b..9852497 100644
--- a/app/assets/javascripts/discourse/app/components/image-uploader.js
+++ b/app/assets/javascripts/discourse/app/components/image-uploader.js
@@ -1,4 +1,5 @@
 import Component from "@ember/component";
+import deprecated from "discourse-common/lib/deprecated";
 import UploadMixin from "discourse/mixins/upload";
 import { ajax } from "discourse/lib/ajax";
 import discourseComputed from "discourse-common/utils/decorators";
@@ -14,6 +15,10 @@ export default Component.extend(UploadMixin, {
 
   init() {
     this._super(...arguments);
+    // TODO (martin) (2022-01-22) Remove this component.
+    deprecated(
+      "image-uploader will be removed in a future version, use uppy-image-uploader instead (the API is the same)"
+    );
     this._applyLightbox();
   },
 
diff --git a/app/assets/javascripts/discourse/app/components/uppy-image-uploader.js b/app/assets/javascripts/discourse/app/components/uppy-image-uploader.js
index 7b416ca..1d2175d 100644
--- a/app/assets/javascripts/discourse/app/components/uppy-image-uploader.js
+++ b/app/assets/javascripts/discourse/app/components/uppy-image-uploader.js
@@ -69,8 +69,6 @@ export default Component.extend(UppyUploadMixin, {
 
   uploadDone(upload) {
     this.setProperties({
-      imageUrl: upload.url,
-      imageId: upload.id,
       imageFilesize: upload.human_filesize,
       imageFilename: upload.original_filename,
       imageWidth: upload.width,
@@ -79,8 +77,13 @@ export default Component.extend(UppyUploadMixin, {
 
     this._applyLightbox();
 
+    // the value of the property used for imageUrl should be set
+    // in this callback. this should be done in cases where imageUrl
+    // is bound to a computed property of the parent component.
     if (this.onUploadDone) {
       this.onUploadDone(upload);
+    } else {
+      this.set("imageUrl", upload.url);
     }
   },
 
@@ -123,13 +126,16 @@ export default Component.extend(UppyUploadMixin, {
     },
 
     trash() {
-      this.setProperties({ imageUrl: null, imageId: null });
-
       // uppy needs to be reset to allow for more uploads
       this._reset();
 
+      // the value of the property used for imageUrl should be cleared
+      // in this callback. this should be done in cases where imageUrl
+      // is bound to a computed property of the parent component.
       if (this.onUploadDeleted) {
         this.onUploadDeleted();
+      } else {
+        this.setProperties({ imageUrl: null });
       }
     },
   },
diff --git a/app/assets/javascripts/discourse/app/controllers/preferences/profile.js b/app/assets/javascripts/discourse/app/controllers/preferences/profile.js
index 5356a8a..6e9403d 100644
--- a/app/assets/javascripts/discourse/app/controllers/preferences/profile.js
+++ b/app/assets/javascripts/discourse/app/controllers/preferences/profile.js
@@ -68,10 +68,6 @@ export default Controller.extend({
     "model.can_upload_user_card_background"
   ),
 
-  experimentalUserCardImageUpload: readOnly(
-    "siteSettings.enable_experimental_image_uploader"
-  ),
-
   actions: {
     showFeaturedTopicModal() {
       showModal("feature-topic-on-profile", {
diff --git a/app/assets/javascripts/discourse/app/mixins/composer-upload-uppy.js b/app/assets/javascripts/discourse/app/mixins/composer-upload-uppy.js
index 3089a39..c5f1e08 100644
--- a/app/assets/javascripts/discourse/app/mixins/composer-upload-uppy.js
+++ b/app/assets/javascripts/discourse/app/mixins/composer-upload-uppy.js
@@ -136,7 +136,6 @@ export default Mixin.create(ExtendableUploader, {
       this._instrumentUploadTimings();
     }
 
-    // hidden setting like enable_experimental_image_uploader
     if (this.siteSettings.enable_direct_s3_uploads) {
       this._useS3MultipartUploads();
     } else {
@@ -482,6 +481,8 @@ export default Mixin.create(ExtendableUploader, {
           data: JSON.stringify({
             parts,
             unique_identifier: file.meta.unique_identifier,
+            pasted: file.meta.pasted,
+            for_private_message: file.meta.for_private_message,
           }),
           // uppy is inconsistent, an error here fires the upload-error event
         }).then((responseData) => {
@@ -570,14 +571,14 @@ export default Mixin.create(ExtendableUploader, {
       }
 
       if (event && event.clipboardData && event.clipboardData.files) {
-        this._addFiles([...event.clipboardData.files]);
+        this._addFiles([...event.clipboardData.files], { pasted: true });
       }
     }.bind(this);
 
     this.element.addEventListener("paste", this.pasteEventListener);
   },
 
-  _addFiles(files) {
+  _addFiles(files, opts = {}) {
     files = Array.isArray(files) ? files : [files];
     try {
       this._uppyInstance.addFiles(
@@ -587,6 +588,7 @@ export default Mixin.create(ExtendableUploader, {
             name: file.name,
             type: file.type,
             data: file,
+            meta: { pasted: opts.pasted },
           };
         })
       );
diff --git a/app/assets/javascripts/discourse/app/mixins/uppy-upload.js b/app/assets/javascripts/discourse/app/mixins/uppy-upload.js
index ad8cd44..e6d282b 100644
--- a/app/assets/javascripts/discourse/app/mixins/uppy-upload.js
+++ b/app/assets/javascripts/discourse/app/mixins/uppy-upload.js
@@ -25,10 +25,6 @@ export default Mixin.create({
   autoStartUploads: true,
   id: null,
 
-  // TODO (martin): this is only used in one place, consider just using
-  // form data/meta instead uploadUrlParams: "&for_site_setting=true",
-  uploadUrlParams: "",
-
   // TODO (martin): currently used for backups to turn on auto upload and PUT/XML requests

[... diff too long, it was truncated ...]

GitHub sha: 2364626dedc82b0ff3086407f68705cff22c2849

This commit appears in #14428 which was approved by eviltrout and tgxworld. It was merged by martin.