mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
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 <input type="file"> 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 - 3dda926cb2/app/assets/javascripts/discourse/tests/acceptance/composer-attachment-test.js (L89).
This commit is contained in:
committed by
GitHub
parent
b63c9febe8
commit
a2e0da16a7
@@ -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
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -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(``);
|
||||
} else {
|
||||
toolbarEvent.addText(imageUrl);
|
||||
}
|
||||
}
|
||||
this.send("closeModal");
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -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() {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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}}
|
||||
|
||||
@@ -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>
|
||||
@@ -362,6 +362,10 @@
|
||||
#file-uploading {
|
||||
color: var(--primary-high);
|
||||
}
|
||||
|
||||
#file-uploader {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.autocomplete {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -171,10 +171,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
#mobile-uploader {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.title-and-category,
|
||||
.user-selector {
|
||||
margin: 0;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user