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 552e2a9beba..7ce199ce3ad 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 6ccf7f4fbbb..00000000000 --- 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 9099ffffb38..0f697564f75 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 ea68f8598ee..73757105793 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 fa362d7ccee..6cca5bcf1e1 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 4e90b908837..00000000000 --- 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 67e7165b61b..31ddf209d8c 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 5efef681a15..082f4f9804f 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 e6d6dd4dc31..6211b8ea1d3 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 6900f8d1a26..ea28661b908 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 58e07eaa28e..87a5cc185ee 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 979d05d883f..7efb5bfb3fa 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"); });