From a2e0da16a7534d2cb6ed4ad2cf52eee1401039ca Mon Sep 17 00:00:00 2001 From: Andrei Prigorshnev Date: Wed, 30 Jun 2021 12:45:47 +0400 Subject: [PATCH] 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. --- .../app/components/composer-editor.js | 10 +-- .../app/controllers/upload-selector.js | 69 ------------------- .../discourse/app/routes/application.js | 7 +- .../templates/components/composer-editor.hbs | 4 +- .../discourse/app/templates/composer.hbs | 2 +- .../app/templates/modal/upload-selector.hbs | 45 ------------ .../stylesheets/common/base/compose.scss | 4 ++ app/assets/stylesheets/desktop/upload.scss | 46 ------------- app/assets/stylesheets/mobile/compose.scss | 4 -- app/assets/stylesheets/mobile/upload.scss | 34 --------- config/locales/client.en.yml | 11 --- test/smoke_test.js | 18 ----- 12 files changed, 14 insertions(+), 240 deletions(-) delete mode 100644 app/assets/javascripts/discourse/app/controllers/upload-selector.js delete mode 100644 app/assets/javascripts/discourse/app/templates/modal/upload-selector.hbs diff --git a/app/assets/javascripts/discourse/app/components/composer-editor.js b/app/assets/javascripts/discourse/app/components/composer-editor.js index 552e2a9beb..7ce199ce3a 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 6ccf7f4fbb..0000000000 --- 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 9099ffffb3..0f697564f7 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 ea68f8598e..7375710579 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}} - -{{/if}} + diff --git a/app/assets/javascripts/discourse/app/templates/composer.hbs b/app/assets/javascripts/discourse/app/templates/composer.hbs index fa362d7cce..6cca5bcf1e 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}} - + {{d-icon uploadIcon}} {{/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 4e90b90883..0000000000 --- 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"}} -
- {{radio-button name="upload" id="local" value="local" selection=selection}} - - {{#if local}} -
-
- {{tip}} - {{#if allowAdditionalFormats}} - {{hidden-details label="upload_selector.supported_formats" details=supportedFormats}} - {{/if}} -
- {{/if}} -
-
- {{radio-button name="upload" id="remote" value="remote" selection=selection}} - - {{#if remote}} -
- {{input value=imageUrl placeholder="http://example.com/image.png"}} - {{tip}} - {{#if allowAdditionalFormats}} - {{hidden-details label="upload_selector.supported_formats" details=supportedFormats}} - {{/if}} -
- {{/if}} -
-
-
-

- {{#if capabilities.canPasteImages}} - {{i18n "upload_selector.hint"}} - {{else}} - {{i18n "upload_selector.hint_for_supported_browsers"}} - {{/if}} -

-
-
-{{/d-modal-body}} - - diff --git a/app/assets/stylesheets/common/base/compose.scss b/app/assets/stylesheets/common/base/compose.scss index 67e7165b61..31ddf209d8 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 5efef681a1..082f4f9804 100644 --- a/app/assets/stylesheets/desktop/upload.scss +++ b/app/assets/stylesheets/desktop/upload.scss @@ -1,49 +1,3 @@ -.upload-selector { - label { - display: inline-block; - padding-left: 10px; - } - &.modal-body { - width: 460px; - } - .radios { - min-height: 60px; - display: flex; - align-items: flex-start; - label { - flex: 1 0 auto; - margin-right: 1em; - margin-top: 1px; - } - .inputs { - width: 100%; - input { - width: 90%; - margin: 0 0 5px 0; - } - input[type="file"] { - font-size: $font-0; - line-height: $line-height-medium; - } - .description, - .hint { - color: var(--primary-med-or-secondary-med); - display: block; - } - .hint { - font-style: italic; - margin: 5px 0 0 0; - } - .label { - margin: 0 0 5px 0; - } - } - } - .radios:last-child { - min-height: 20px; - } -} - .uploaded-image-preview { height: 270px; width: 400px; diff --git a/app/assets/stylesheets/mobile/compose.scss b/app/assets/stylesheets/mobile/compose.scss index e6d6dd4dc3..6211b8ea1d 100644 --- a/app/assets/stylesheets/mobile/compose.scss +++ b/app/assets/stylesheets/mobile/compose.scss @@ -171,10 +171,6 @@ } } - #mobile-uploader { - display: none; - } - .title-and-category, .user-selector { margin: 0; diff --git a/app/assets/stylesheets/mobile/upload.scss b/app/assets/stylesheets/mobile/upload.scss index 6900f8d1a2..ea28661b90 100644 --- a/app/assets/stylesheets/mobile/upload.scss +++ b/app/assets/stylesheets/mobile/upload.scss @@ -1,37 +1,3 @@ -.upload-selector { - input[type="text"] { - width: calc(100% - 20px); - } - input[type="file"] { - font-size: $font-0; - line-height: $line-height-medium; - } - .description { - color: var(--primary-medium); - } - .radios { - display: flex; - flex-wrap: wrap; - align-items: center; - &:first-of-type { - margin-bottom: 1em; - } - input, - label { - min-height: 20px; - line-height: $line-height-medium; - margin: 0; - } - .radio { - padding-left: 5px; - } - .inputs { - margin-top: 10px; - width: 100%; - } - } -} - .uploaded-image-preview { height: 150px; } diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 58e07eaa28..87a5cc185e 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -2236,21 +2236,10 @@ en: votes_released: "Vote was released" upload_selector: - title: "Add an image" - title_with_attachments: "Add an image or a file" - from_my_computer: "From my device" - from_the_web: "From the web" - remote_tip: "link to image" - remote_tip_with_attachments: "link to image or file" - local_tip: "select images from your device" - local_tip_with_attachments: "select images or files from your device" - hint: "(you can also drag & drop into the editor to upload)" - hint_for_supported_browsers: "you can also drag and drop or paste images into the editor" uploading: "Uploading" processing: "Processing Upload" select_file: "Select File" default_image_alt_text: image - supported_formats: "supported formats" search: sort_by: "Sort by" diff --git a/test/smoke_test.js b/test/smoke_test.js index 979d05d883..7efb5bfb3f 100644 --- a/test/smoke_test.js +++ b/test/smoke_test.js @@ -222,24 +222,6 @@ const path = require("path"); return page.waitForSelector(".d-editor-preview p", { visible: true }); }); - await exec("open upload modal", () => { - return page.click(".d-editor-button-bar .upload"); - }); - - await exec("upload modal is open", () => { - return page.waitForSelector("#filename-input", { visible: true }); - }); - - await exec("upload modal closes", () => { - let promise = page.click(".d-modal-cancel"); - - promise = promise.then(() => { - return page.waitForSelector("#filename-input", { hidden: true }); - }); - - return promise; - }); - await exec("submit the topic", () => { return page.click(".submit-panel .create"); });