FEATURE: use native file picker in composer (#13552)

FEATURE: use native file picker in composer (#13552)

We want to remove completely our custom modal for uploading files in composer and directly trigger the system file picker.

This PR makes it happen. The fix is pretty simple since we already weren’t using our custom modal on mobile. We just need to start using the same hidden that we already use on mobile.

It seems to be pretty tricky to test opening a system modal so I haven’t added new tests. We already have other tests for file uploading though. We directly trigger jquery-File-Upload plugin hooks in those tests - https://github.com/discourse/discourse/blob/3dda926cb22751beced12b427dd14657b53b6dfe/app/assets/javascripts/discourse/tests/acceptance/composer-attachment-test.js#L89.

diff --git a/app/assets/javascripts/discourse/app/components/composer-editor.js b/app/assets/javascripts/discourse/app/components/composer-editor.js
index 552e2a9..7ce199c 100644
--- a/app/assets/javascripts/discourse/app/components/composer-editor.js
+++ b/app/assets/javascripts/discourse/app/components/composer-editor.js
@@ -831,10 +831,12 @@ export default Component.extend({
     });
 
     if (this.site.mobileView) {
-      $("#reply-control .mobile-file-upload").on("click.uploader", function () {
-        // redirect the click on the hidden file input
-        $("#mobile-uploader").click();
-      });
+      const uploadButton = document.getElementById("mobile-file-upload");
+      uploadButton.addEventListener(
+        "click",
+        () => document.getElementById("file-uploader").click(),
+        false
+      );
     }
   },
 
diff --git a/app/assets/javascripts/discourse/app/controllers/upload-selector.js b/app/assets/javascripts/discourse/app/controllers/upload-selector.js
deleted file mode 100644
index 6ccf7f4..0000000
--- a/app/assets/javascripts/discourse/app/controllers/upload-selector.js
+++ /dev/null
@@ -1,69 +0,0 @@
-import {
-  allowsAttachments,
-  authorizedExtensions,
-  uploadIcon,
-} from "discourse/lib/uploads";
-import Controller from "@ember/controller";
-import I18n from "I18n";
-import ModalFunctionality from "discourse/mixins/modal-functionality";
-import discourseComputed from "discourse-common/utils/decorators";
-import { equal } from "@ember/object/computed";
-
-export default Controller.extend(ModalFunctionality, {
-  imageUrl: null,
-  local: equal("selection", "local"),
-  remote: equal("selection", "remote"),
-  selection: "local",
-
-  @discourseComputed()
-  allowAdditionalFormats() {
-    return allowsAttachments(this.currentUser.staff, this.siteSettings);
-  },
-
-  @discourseComputed()
-  uploadIcon() {
-    return uploadIcon(this.currentUser.staff, this.siteSettings);
-  },
-
-  @discourseComputed("allowAdditionalFormats")
-  title(allowAdditionalFormats) {
-    const suffix = allowAdditionalFormats ? "_with_attachments" : "";
-    return `upload_selector.title${suffix}`;
-  },
-
-  @discourseComputed("selection", "allowAdditionalFormats")
-  tip(selection, allowAdditionalFormats) {
-    const suffix = allowAdditionalFormats ? "_with_attachments" : "";
-    return I18n.t(`upload_selector.${selection}_tip${suffix}`);
-  },
-
-  @discourseComputed()
-  supportedFormats() {
-    const extensions = authorizedExtensions(
-      this.currentUser.staff,
-      this.siteSettings
-    );
-
-    return `(${extensions})`;
-  },
-
-  actions: {
-    upload() {
-      if (this.local) {
-        $(".wmd-controls").fileupload("add", {
-          fileInput: $("#filename-input"),
-        });
-      } else {
-        const imageUrl = this.imageUrl || "";
-        const toolbarEvent = this.toolbarEvent;
-
-        if (imageUrl.match(/\.(jpg|jpeg|png|gif|heic|heif|webp)$/)) {
-          toolbarEvent.addText(`![](${imageUrl})`);
-        } else {
-          toolbarEvent.addText(imageUrl);
-        }
-      }
-      this.send("closeModal");
-    },
-  },
-});
diff --git a/app/assets/javascripts/discourse/app/routes/application.js b/app/assets/javascripts/discourse/app/routes/application.js
index 9099fff..0f69756 100644
--- a/app/assets/javascripts/discourse/app/routes/application.js
+++ b/app/assets/javascripts/discourse/app/routes/application.js
@@ -137,11 +137,8 @@ const ApplicationRoute = DiscourseRoute.extend(OpenComposer, {
       showModal("not-activated", { title: "log_in" }).setProperties(props);
     },
 
-    showUploadSelector(toolbarEvent) {
-      showModal("uploadSelector").setProperties({
-        toolbarEvent,
-        imageUrl: null,
-      });
+    showUploadSelector() {
+      document.getElementById("file-uploader").click();
     },
 
     showKeyboardShortcutsHelp() {
diff --git a/app/assets/javascripts/discourse/app/templates/components/composer-editor.hbs b/app/assets/javascripts/discourse/app/templates/components/composer-editor.hbs
index ea68f85..7375710 100644
--- a/app/assets/javascripts/discourse/app/templates/components/composer-editor.hbs
+++ b/app/assets/javascripts/discourse/app/templates/components/composer-editor.hbs
@@ -19,6 +19,4 @@
   disabled=disableTextarea
   outletArgs=(hash composer=composer editorType="composer")}}
 
-{{#if site.mobileView}}
-  <input type="file" id="mobile-uploader" multiple>
-{{/if}}
+<input type="file" id="file-uploader" multiple>
diff --git a/app/assets/javascripts/discourse/app/templates/composer.hbs b/app/assets/javascripts/discourse/app/templates/composer.hbs
index fa362d7..6cca5bc 100644
--- a/app/assets/javascripts/discourse/app/templates/composer.hbs
+++ b/app/assets/javascripts/discourse/app/templates/composer.hbs
@@ -200,7 +200,7 @@
             {{plugin-outlet name="composer-mobile-buttons-bottom" connectorTagName="" args=(hash model=model)}}
 
             {{#if allowUpload}}
-              <a class="btn btn-default no-text mobile-file-upload {{if isUploading "hidden"}}"  aria-label={{i18n "composer.upload_title"}}>
+              <a id="mobile-file-upload" class="btn btn-default no-text mobile-file-upload {{if isUploading "hidden"}}"  aria-label={{i18n "composer.upload_title"}}>
                 {{d-icon uploadIcon}}
               </a>
             {{/if}}
diff --git a/app/assets/javascripts/discourse/app/templates/modal/upload-selector.hbs b/app/assets/javascripts/discourse/app/templates/modal/upload-selector.hbs
deleted file mode 100644
index 4e90b90..0000000
--- a/app/assets/javascripts/discourse/app/templates/modal/upload-selector.hbs
+++ /dev/null
@@ -1,45 +0,0 @@
-{{#d-modal-body title=title class="upload-selector"}}
-  <div class="radios">
-    {{radio-button name="upload" id="local" value="local" selection=selection}}
-    <label class="radio" for="local">{{i18n "upload_selector.from_my_computer"}}</label>
-    {{#if local}}
-      <div class="inputs">
-        <input type="file" id="filename-input" multiple><br>
-        <span class="description">{{tip}}</span>
-        {{#if allowAdditionalFormats}}
-          {{hidden-details label="upload_selector.supported_formats" details=supportedFormats}}
-        {{/if}}
-      </div>
-    {{/if}}
-  </div>
-  <div class="radios">
-    {{radio-button name="upload" id="remote" value="remote" selection=selection}}
-    <label class="radio" for="remote">{{i18n "upload_selector.from_the_web"}}</label>
-    {{#if remote}}
-      <div class="inputs">
-        {{input value=imageUrl placeholder="http://example.com/image.png"}}
-        <span class="description">{{tip}}</span>
-        {{#if allowAdditionalFormats}}
-          {{hidden-details label="upload_selector.supported_formats" details=supportedFormats}}
-        {{/if}}
-      </div>
-    {{/if}}
-  </div>
-  <div class="radios">
-    <div class="inputs">
-      <p class="hint">
-        {{#if capabilities.canPasteImages}}
-          {{i18n "upload_selector.hint"}}
-        {{else}}
-          {{i18n "upload_selector.hint_for_supported_browsers"}}
-        {{/if}}
-      </p>
-    </div>
-  </div>
-{{/d-modal-body}}
-
-<div class="modal-footer">
-  {{d-button action=(action "upload") class="btn-primary" icon=uploadIcon label="upload"}}
-  {{plugin-outlet name="upload-actions"}}
-  {{d-modal-cancel close=(route-action "closeModal")}}
-</div>
diff --git a/app/assets/stylesheets/common/base/compose.scss b/app/assets/stylesheets/common/base/compose.scss
index 67e7165..31ddf20 100644
--- a/app/assets/stylesheets/common/base/compose.scss
+++ b/app/assets/stylesheets/common/base/compose.scss
@@ -362,6 +362,10 @@
   #file-uploading {
     color: var(--primary-high);
   }
+
+  #file-uploader {
+    display: none;
+  }
 }
 
 .autocomplete {
diff --git a/app/assets/stylesheets/desktop/upload.scss b/app/assets/stylesheets/desktop/upload.scss
index 5efef68..082f4f9 100644
--- a/app/assets/stylesheets/desktop/upload.scss

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

GitHub sha: a2e0da16a7534d2cb6ed4ad2cf52eee1401039ca

This commit appears in #13552 which was approved by pmusaraj and martin. It was merged by AndrewPrigorshnev.

This commit has been mentioned on Discourse Meta. There might be relevant details there:

This commit has been mentioned on Discourse Meta. There might be relevant details there: