FEATURE: Uppy image uploader with UppyUploadMixin (#13656)
This PR adds the first use of Uppy in our codebase, hidden behind a enable_experimental_image_uploader site setting. When the setting is enabled only the user card background uploader will use the new uppy-image-uploader component added in this PR. I've introduced an UppyUpload mixin that has feature parity with the existing Upload mixin, and improves it slightly to deal with multiple/single file distinctions and validations better. For now, this just supports the XHRUpload plugin for uppy, which keeps our existing POST to /uploads.json.
This commit is contained in:
parent
e2d04a8592
commit
7911124d3d
|
@ -45,10 +45,23 @@ define("@popperjs/core", ["exports"], function (__exports__) {
|
||||||
__exports__.popperGenerator = window.Popper.popperGenerator;
|
__exports__.popperGenerator = window.Popper.popperGenerator;
|
||||||
});
|
});
|
||||||
|
|
||||||
define("uppy", ["exports"], function (__exports__) {
|
define("@uppy/core", ["exports"], function (__exports__) {
|
||||||
__exports__.default = window.Uppy.Core;
|
__exports__.default = window.Uppy.Core;
|
||||||
__exports__.Plugin = window.Uppy.Plugin;
|
__exports__.Plugin = window.Uppy.Plugin;
|
||||||
__exports__.XHRUpload = window.Uppy.XHRUpload;
|
});
|
||||||
__exports__.AwsS3 = window.Uppy.AwsS3;
|
|
||||||
__exports__.AwsS3Multipart = window.Uppy.AwsS3Multipart;
|
define("@uppy/aws-s3", ["exports"], function (__exports__) {
|
||||||
|
__exports__.default = window.Uppy.AwsS3;
|
||||||
|
});
|
||||||
|
|
||||||
|
define("@uppy/aws-s3-multipart", ["exports"], function (__exports__) {
|
||||||
|
__exports__.default = window.Uppy.AwsS3Multipart;
|
||||||
|
});
|
||||||
|
|
||||||
|
define("@uppy/xhr-upload", ["exports"], function (__exports__) {
|
||||||
|
__exports__.default = window.Uppy.XHRUpload;
|
||||||
|
});
|
||||||
|
|
||||||
|
define("@uppy/drop-target", ["exports"], function (__exports__) {
|
||||||
|
__exports__.default = window.Uppy.DropTarget;
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
import Component from "@ember/component";
|
||||||
|
import UppyUploadMixin from "discourse/mixins/uppy-upload";
|
||||||
|
import { ajax } from "discourse/lib/ajax";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
import { getURLWithCDN } from "discourse-common/lib/get-url";
|
||||||
|
import { isEmpty } from "@ember/utils";
|
||||||
|
import lightbox from "discourse/lib/lightbox";
|
||||||
|
import { next } from "@ember/runloop";
|
||||||
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
|
|
||||||
|
export default Component.extend(UppyUploadMixin, {
|
||||||
|
classNames: ["image-uploader"],
|
||||||
|
loadingLightbox: false,
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this._super(...arguments);
|
||||||
|
this._applyLightbox();
|
||||||
|
},
|
||||||
|
|
||||||
|
willDestroyElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
const elem = $("a.lightbox");
|
||||||
|
if (elem && typeof elem.magnificPopup === "function") {
|
||||||
|
$("a.lightbox").magnificPopup("close");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("imageUrl", "placeholderUrl")
|
||||||
|
showingPlaceholder(imageUrl, placeholderUrl) {
|
||||||
|
return !imageUrl && placeholderUrl;
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("placeholderUrl")
|
||||||
|
placeholderStyle(url) {
|
||||||
|
if (isEmpty(url)) {
|
||||||
|
return "".htmlSafe();
|
||||||
|
}
|
||||||
|
return `background-image: url(${url})`.htmlSafe();
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("imageUrl")
|
||||||
|
imageCDNURL(url) {
|
||||||
|
if (isEmpty(url)) {
|
||||||
|
return "".htmlSafe();
|
||||||
|
}
|
||||||
|
|
||||||
|
return getURLWithCDN(url);
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("imageCDNURL")
|
||||||
|
backgroundStyle(url) {
|
||||||
|
return `background-image: url(${url})`.htmlSafe();
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("imageUrl")
|
||||||
|
imageBaseName(imageUrl) {
|
||||||
|
if (isEmpty(imageUrl)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return imageUrl.split("/").slice(-1)[0];
|
||||||
|
},
|
||||||
|
|
||||||
|
validateUploadedFilesOptions() {
|
||||||
|
return { imagesOnly: true };
|
||||||
|
},
|
||||||
|
|
||||||
|
uploadDone(upload) {
|
||||||
|
this.setProperties({
|
||||||
|
imageUrl: upload.url,
|
||||||
|
imageId: upload.id,
|
||||||
|
imageFilesize: upload.human_filesize,
|
||||||
|
imageFilename: upload.original_filename,
|
||||||
|
imageWidth: upload.width,
|
||||||
|
imageHeight: upload.height,
|
||||||
|
});
|
||||||
|
|
||||||
|
this._applyLightbox();
|
||||||
|
|
||||||
|
if (this.onUploadDone) {
|
||||||
|
this.onUploadDone(upload);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_openLightbox() {
|
||||||
|
next(() =>
|
||||||
|
$(this.element.querySelector("a.lightbox")).magnificPopup("open")
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
_applyLightbox() {
|
||||||
|
if (this.imageUrl) {
|
||||||
|
next(() => lightbox(this.element, this.siteSettings));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
toggleLightbox() {
|
||||||
|
if (this.imageFilename) {
|
||||||
|
this._openLightbox();
|
||||||
|
} else {
|
||||||
|
this.set("loadingLightbox", true);
|
||||||
|
|
||||||
|
ajax(`/uploads/lookup-metadata`, {
|
||||||
|
type: "POST",
|
||||||
|
data: { url: this.imageUrl },
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
this.setProperties({
|
||||||
|
imageFilename: json.original_filename,
|
||||||
|
imageFilesize: json.human_filesize,
|
||||||
|
imageWidth: json.width,
|
||||||
|
imageHeight: json.height,
|
||||||
|
});
|
||||||
|
|
||||||
|
this._openLightbox();
|
||||||
|
this.set("loadingLightbox", false);
|
||||||
|
})
|
||||||
|
.catch(popupAjaxError);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
trash() {
|
||||||
|
this.setProperties({ imageUrl: null, imageId: null });
|
||||||
|
|
||||||
|
// uppy needs to be reset to allow for more uploads
|
||||||
|
this._reset();
|
||||||
|
|
||||||
|
if (this.onUploadDeleted) {
|
||||||
|
this.onUploadDeleted();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
|
@ -57,6 +57,10 @@ export default Controller.extend({
|
||||||
"model.can_upload_user_card_background"
|
"model.can_upload_user_card_background"
|
||||||
),
|
),
|
||||||
|
|
||||||
|
experimentalUserCardImageUpload: readOnly(
|
||||||
|
"siteSettings.enable_experimental_image_uploader"
|
||||||
|
),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
showFeaturedTopicModal() {
|
showFeaturedTopicModal() {
|
||||||
showModal("feature-topic-on-profile", {
|
showModal("feature-topic-on-profile", {
|
||||||
|
|
|
@ -29,30 +29,28 @@ export function validateUploadedFiles(files, opts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const upload = files[0];
|
const upload = files[0];
|
||||||
|
return validateUploadedFile(upload, opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateUploadedFile(file, opts) {
|
||||||
// CHROME ONLY: if the image was pasted, sets its name to a default one
|
// CHROME ONLY: if the image was pasted, sets its name to a default one
|
||||||
if (typeof Blob !== "undefined" && typeof File !== "undefined") {
|
if (typeof Blob !== "undefined" && typeof File !== "undefined") {
|
||||||
if (
|
if (
|
||||||
upload instanceof Blob &&
|
file instanceof Blob &&
|
||||||
!(upload instanceof File) &&
|
!(file instanceof File) &&
|
||||||
upload.type === "image/png"
|
file.type === "image/png"
|
||||||
) {
|
) {
|
||||||
upload.name = "image.png";
|
file.name = "image.png";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
opts.type = uploadTypeFromFileName(upload.name);
|
opts.type = uploadTypeFromFileName(file.name);
|
||||||
|
|
||||||
return validateUploadedFile(upload, opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateUploadedFile(file, opts) {
|
|
||||||
if (opts.skipValidation) {
|
if (opts.skipValidation) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
opts = opts || {};
|
|
||||||
let user = opts.user;
|
let user = opts.user;
|
||||||
let staff = user && user.staff;
|
let staff = user && user.staff;
|
||||||
|
|
||||||
|
@ -283,27 +281,14 @@ export function getUploadMarkdown(upload) {
|
||||||
|
|
||||||
export function displayErrorForUpload(data, siteSettings) {
|
export function displayErrorForUpload(data, siteSettings) {
|
||||||
if (data.jqXHR) {
|
if (data.jqXHR) {
|
||||||
switch (data.jqXHR.status) {
|
const didError = displayErrorByResponseStatus(
|
||||||
// didn't get headers from server, or browser refuses to tell us
|
data.jqXHR.status,
|
||||||
case 0:
|
data.jqXHR.responseJSON,
|
||||||
bootbox.alert(I18n.t("post.errors.upload"));
|
data.files[0].name,
|
||||||
return;
|
siteSettings
|
||||||
|
);
|
||||||
// entity too large, usually returned from the web server
|
if (didError) {
|
||||||
case 413:
|
return;
|
||||||
const type = uploadTypeFromFileName(data.files[0].name);
|
|
||||||
const max_size_kb = siteSettings[`max_${type}_size_kb`];
|
|
||||||
bootbox.alert(I18n.t("post.errors.file_too_large", { max_size_kb }));
|
|
||||||
return;
|
|
||||||
|
|
||||||
// the error message is provided by the server
|
|
||||||
case 422:
|
|
||||||
if (data.jqXHR.responseJSON.message) {
|
|
||||||
bootbox.alert(data.jqXHR.responseJSON.message);
|
|
||||||
} else {
|
|
||||||
bootbox.alert(data.jqXHR.responseJSON.errors.join("\n"));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else if (data.errors && data.errors.length > 0) {
|
} else if (data.errors && data.errors.length > 0) {
|
||||||
bootbox.alert(data.errors.join("\n"));
|
bootbox.alert(data.errors.join("\n"));
|
||||||
|
@ -312,3 +297,49 @@ export function displayErrorForUpload(data, siteSettings) {
|
||||||
// otherwise, display a generic error message
|
// otherwise, display a generic error message
|
||||||
bootbox.alert(I18n.t("post.errors.upload"));
|
bootbox.alert(I18n.t("post.errors.upload"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function displayErrorForUppyUpload(response, fileName, siteSettings) {
|
||||||
|
if (response.body.errors && response.body.errors.length > 0) {
|
||||||
|
bootbox.alert(response.body.errors.join("\n"));
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
const didError = displayErrorByResponseStatus(
|
||||||
|
response.status,
|
||||||
|
response.body,
|
||||||
|
fileName,
|
||||||
|
siteSettings
|
||||||
|
);
|
||||||
|
if (didError) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// otherwise, display a generic error message
|
||||||
|
bootbox.alert(I18n.t("post.errors.upload"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayErrorByResponseStatus(status, body, fileName, siteSettings) {
|
||||||
|
switch (status) {
|
||||||
|
// didn't get headers from server, or browser refuses to tell us
|
||||||
|
case 0:
|
||||||
|
bootbox.alert(I18n.t("post.errors.upload"));
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// entity too large, usually returned from the web server
|
||||||
|
case 413:
|
||||||
|
const type = uploadTypeFromFileName(fileName);
|
||||||
|
const max_size_kb = siteSettings[`max_${type}_size_kb`];
|
||||||
|
bootbox.alert(I18n.t("post.errors.file_too_large", { max_size_kb }));
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// the error message is provided by the server
|
||||||
|
case 422:
|
||||||
|
if (body.message) {
|
||||||
|
bootbox.alert(body.message);
|
||||||
|
} else {
|
||||||
|
bootbox.alert(body.errors.join("\n"));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,179 @@
|
||||||
|
import Mixin from "@ember/object/mixin";
|
||||||
|
import {
|
||||||
|
displayErrorForUppyUpload,
|
||||||
|
validateUploadedFile,
|
||||||
|
} from "discourse/lib/uploads";
|
||||||
|
import { deepMerge } from "discourse-common/lib/object";
|
||||||
|
import getUrl from "discourse-common/lib/get-url";
|
||||||
|
import I18n from "I18n";
|
||||||
|
import Uppy from "@uppy/core";
|
||||||
|
import DropTarget from "@uppy/drop-target";
|
||||||
|
import XHRUpload from "@uppy/xhr-upload";
|
||||||
|
import { on } from "discourse-common/utils/decorators";
|
||||||
|
import { warn } from "@ember/debug";
|
||||||
|
|
||||||
|
export default Mixin.create({
|
||||||
|
uploading: false,
|
||||||
|
uploadProgress: 0,
|
||||||
|
uppyInstance: null,
|
||||||
|
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
|
||||||
|
// and for emojis to do sequential uploads, when we get to replacing those
|
||||||
|
// with uppy make sure this is used when initializing uppy
|
||||||
|
uploadOptions() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
|
||||||
|
uploadDone() {
|
||||||
|
warn("You should implement `uploadDone`", {
|
||||||
|
id: "discourse.upload.missing-upload-done",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
validateUploadedFilesOptions() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
|
||||||
|
@on("willDestroyElement")
|
||||||
|
_destroy() {
|
||||||
|
this.messageBus && this.messageBus.unsubscribe("/uploads/" + this.type);
|
||||||
|
this.uppyInstance && this.uppyInstance.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
@on("didInsertElement")
|
||||||
|
_initialize() {
|
||||||
|
this.set("fileInputEl", this.element.querySelector(".hidden-upload-field"));
|
||||||
|
this.set("allowMultipleFiles", this.fileInputEl.multiple);
|
||||||
|
|
||||||
|
this._bindFileInputChangeListener();
|
||||||
|
|
||||||
|
if (!this.id) {
|
||||||
|
warn(
|
||||||
|
"uppy needs a unique id, pass one in to the component implementing this mixin",
|
||||||
|
{
|
||||||
|
id: "discourse.upload.missing-id",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.set(
|
||||||
|
"uppyInstance",
|
||||||
|
new Uppy({
|
||||||
|
id: this.id,
|
||||||
|
autoProceed: this.autoStartUploads,
|
||||||
|
|
||||||
|
// need to use upload_type because uppy overrides type with the
|
||||||
|
// actual file type
|
||||||
|
meta: deepMerge({ upload_type: this.type }, this.data || {}),
|
||||||
|
|
||||||
|
onBeforeFileAdded: (currentFile) => {
|
||||||
|
const validationOpts = deepMerge(
|
||||||
|
{
|
||||||
|
bypassNewUserRestriction: true,
|
||||||
|
user: this.currentUser,
|
||||||
|
siteSettings: this.siteSettings,
|
||||||
|
},
|
||||||
|
this.validateUploadedFilesOptions()
|
||||||
|
);
|
||||||
|
const isValid = validateUploadedFile(currentFile, validationOpts);
|
||||||
|
this.setProperties({ uploadProgress: 0, uploading: isValid });
|
||||||
|
return isValid;
|
||||||
|
},
|
||||||
|
|
||||||
|
onBeforeUpload: (files) => {
|
||||||
|
let tooMany = false;
|
||||||
|
const fileCount = Object.keys(files).length;
|
||||||
|
const maxFiles = this.getWithDefault(
|
||||||
|
"maxFiles",
|
||||||
|
this.siteSettings.simultaneous_uploads
|
||||||
|
);
|
||||||
|
|
||||||
|
if (this.allowMultipleFiles) {
|
||||||
|
tooMany = maxFiles > 0 && fileCount > maxFiles;
|
||||||
|
} else {
|
||||||
|
tooMany = fileCount > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tooMany) {
|
||||||
|
bootbox.alert(
|
||||||
|
I18n.t("post.errors.too_many_dragged_and_dropped_files", {
|
||||||
|
count: this.allowMultipleFiles ? maxFiles : 1,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this._reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
this.uppyInstance.use(DropTarget, { target: this.element });
|
||||||
|
|
||||||
|
this.uppyInstance.on("progress", (progress) => {
|
||||||
|
this.set("uploadProgress", progress);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.uppyInstance.on("upload-success", (_file, response) => {
|
||||||
|
this.uploadDone(response.body);
|
||||||
|
this._reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.uppyInstance.on("upload-error", (file, error, response) => {
|
||||||
|
displayErrorForUppyUpload(response, file.name, this.siteSettings);
|
||||||
|
this._reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
// later we will use the uppy direct s3 uploader based on enable_s3_uploads,
|
||||||
|
// for now we always just use XHR uploads
|
||||||
|
this._useXHRUploads();
|
||||||
|
},
|
||||||
|
|
||||||
|
_useXHRUploads() {
|
||||||
|
this.uppyInstance.use(XHRUpload, {
|
||||||
|
endpoint: this._xhrUploadUrl(),
|
||||||
|
headers: {
|
||||||
|
"X-CSRF-Token": this.session.get("csrfToken"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_xhrUploadUrl() {
|
||||||
|
return (
|
||||||
|
getUrl(this.getWithDefault("uploadUrl", "/uploads")) +
|
||||||
|
".json?client_id=" +
|
||||||
|
(this.messageBus && this.messageBus.clientId) +
|
||||||
|
this.uploadUrlParams
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
_bindFileInputChangeListener() {
|
||||||
|
this.fileInputEl.addEventListener("change", (event) => {
|
||||||
|
const files = Array.from(event.target.files);
|
||||||
|
files.forEach((file) => {
|
||||||
|
try {
|
||||||
|
this.uppyInstance.addFile({
|
||||||
|
source: `${this.id} file input`,
|
||||||
|
name: file.name,
|
||||||
|
type: file.type,
|
||||||
|
data: file,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
warn(`error adding files to uppy: ${err}`, {
|
||||||
|
id: "discourse.upload.uppy-add-files-error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_reset() {
|
||||||
|
this.uppyInstance && this.uppyInstance.reset();
|
||||||
|
this.setProperties({ uploading: false, uploadProgress: 0 });
|
||||||
|
},
|
||||||
|
});
|
|
@ -0,0 +1,45 @@
|
||||||
|
<div class="uploaded-image-preview input-xxlarge" style={{backgroundStyle}}>
|
||||||
|
{{#if showingPlaceholder}}
|
||||||
|
<div class="placeholder-overlay" style={{placeholderStyle}}></div>
|
||||||
|
{{/if}}
|
||||||
|
<div class="image-upload-controls">
|
||||||
|
<label class="btn btn-default pad-left no-text {{if uploading "disabled"}}">
|
||||||
|
{{d-icon "far-image"}}
|
||||||
|
<input class="hidden-upload-field" disabled={{uploading}} type="file" accept="image/*">
|
||||||
|
</label>
|
||||||
|
|
||||||
|
{{#if imageUrl}}
|
||||||
|
{{d-button
|
||||||
|
action=(action "trash")
|
||||||
|
class="btn-danger pad-left no-text"
|
||||||
|
icon="far-trash-alt"
|
||||||
|
type="button"
|
||||||
|
}}
|
||||||
|
|
||||||
|
{{d-button
|
||||||
|
icon="discourse-expand"
|
||||||
|
title="expand"
|
||||||
|
type="button"
|
||||||
|
class="image-uploader-lightbox-btn no-text"
|
||||||
|
action=(action "toggleLightbox")
|
||||||
|
disabled=loadingLightbox
|
||||||
|
}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<span class="btn {{unless uploading "hidden"}}">{{i18n "upload_selector.uploading"}} {{uploadProgress}}%</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if imageUrl}}
|
||||||
|
<a class="lightbox"
|
||||||
|
href={{imageCDNURL}}
|
||||||
|
title={{imageFilename}}
|
||||||
|
rel="nofollow ugc noopener">
|
||||||
|
|
||||||
|
<div class="meta">
|
||||||
|
<span class="informations">
|
||||||
|
{{imageWidth}}x{{imageHeight}} {{imageFilesize}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
|
@ -59,8 +59,15 @@
|
||||||
<div class="control-group pref-profile-bg">
|
<div class="control-group pref-profile-bg">
|
||||||
<label class="control-label">{{i18n "user.change_card_background.title"}}</label>
|
<label class="control-label">{{i18n "user.change_card_background.title"}}</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
{{image-uploader imageUrl=model.card_background_upload_url
|
{{#if experimentalUserCardImageUpload}}
|
||||||
type="card_background"}}
|
{{uppy-image-uploader
|
||||||
|
imageUrl=model.card_background_upload_url
|
||||||
|
type="card_background"
|
||||||
|
id="profile-card-background"
|
||||||
|
}}
|
||||||
|
{{else}}
|
||||||
|
{{image-uploader imageUrl=model.card_background_upload_url type="card_background"}}
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<div class="instructions">
|
<div class="instructions">
|
||||||
{{i18n "user.change_card_background.instructions"}}
|
{{i18n "user.change_card_background.instructions"}}
|
||||||
|
|
|
@ -21,6 +21,11 @@
|
||||||
"@ember/test-helpers": "^2.2.0",
|
"@ember/test-helpers": "^2.2.0",
|
||||||
"@glimmer/component": "^1.0.0",
|
"@glimmer/component": "^1.0.0",
|
||||||
"@popperjs/core": "^2.4.4",
|
"@popperjs/core": "^2.4.4",
|
||||||
|
"@uppy/aws-s3": "^1.7.12",
|
||||||
|
"@uppy/aws-s3-multipart": "^1.8.18",
|
||||||
|
"@uppy/core": "^1.19.2",
|
||||||
|
"@uppy/drop-target": "^0.2.4",
|
||||||
|
"@uppy/xhr-upload": "^1.7.5",
|
||||||
"admin": "^1.0.0",
|
"admin": "^1.0.0",
|
||||||
"bent": "^7.3.12",
|
"bent": "^7.3.12",
|
||||||
"broccoli-asset-rev": "^3.0.0",
|
"broccoli-asset-rev": "^3.0.0",
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
import componentTest, {
|
||||||
|
setupRenderingTest,
|
||||||
|
} from "discourse/tests/helpers/component-test";
|
||||||
|
import {
|
||||||
|
count,
|
||||||
|
discourseModule,
|
||||||
|
exists,
|
||||||
|
} from "discourse/tests/helpers/qunit-helpers";
|
||||||
|
import { click } from "@ember/test-helpers";
|
||||||
|
import hbs from "htmlbars-inline-precompile";
|
||||||
|
|
||||||
|
discourseModule(
|
||||||
|
"Integration | Component | uppy-image-uploader",
|
||||||
|
function (hooks) {
|
||||||
|
setupRenderingTest(hooks);
|
||||||
|
|
||||||
|
componentTest("with image", {
|
||||||
|
template: hbs`
|
||||||
|
{{uppy-image-uploader imageUrl='/images/avatar.png' placeholderUrl='/not/used.png'}}
|
||||||
|
`,
|
||||||
|
|
||||||
|
async test(assert) {
|
||||||
|
assert.equal(
|
||||||
|
count(".d-icon-far-image"),
|
||||||
|
1,
|
||||||
|
"it displays the upload icon"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
count(".d-icon-far-trash-alt"),
|
||||||
|
1,
|
||||||
|
"it displays the trash icon"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
!exists(".placeholder-overlay"),
|
||||||
|
"it does not display the placeholder image"
|
||||||
|
);
|
||||||
|
|
||||||
|
await click(".image-uploader-lightbox-btn");
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
$(".mfp-container").length,
|
||||||
|
1,
|
||||||
|
"it displays the image lightbox"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
componentTest("without image", {
|
||||||
|
template: hbs`{{uppy-image-uploader}}`,
|
||||||
|
|
||||||
|
test(assert) {
|
||||||
|
assert.equal(
|
||||||
|
count(".d-icon-far-image"),
|
||||||
|
1,
|
||||||
|
"it displays the upload icon"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
!exists(".d-icon-far-trash-alt"),
|
||||||
|
"it does not display trash icon"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
!exists(".image-uploader-lightbox-btn"),
|
||||||
|
"it does not display the button to open image lightbox"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
componentTest("with placeholder", {
|
||||||
|
template: hbs`{{uppy-image-uploader placeholderUrl='/images/avatar.png'}}`,
|
||||||
|
|
||||||
|
test(assert) {
|
||||||
|
assert.equal(
|
||||||
|
count(".d-icon-far-image"),
|
||||||
|
1,
|
||||||
|
"it displays the upload icon"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
!exists(".d-icon-far-trash-alt"),
|
||||||
|
"it does not display trash icon"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
!exists(".image-uploader-lightbox-btn"),
|
||||||
|
"it does not display the button to open image lightbox"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
count(".placeholder-overlay"),
|
||||||
|
1,
|
||||||
|
"it displays the placeholder image"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
|
@ -1258,6 +1258,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5"
|
resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5"
|
||||||
integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==
|
integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==
|
||||||
|
|
||||||
|
"@transloadit/prettier-bytes@0.0.7":
|
||||||
|
version "0.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/@transloadit/prettier-bytes/-/prettier-bytes-0.0.7.tgz#cdb5399f445fdd606ed833872fa0cabdbc51686b"
|
||||||
|
integrity sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA==
|
||||||
|
|
||||||
"@types/body-parser@*":
|
"@types/body-parser@*":
|
||||||
version "1.19.0"
|
version "1.19.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f"
|
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f"
|
||||||
|
@ -1377,6 +1382,79 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/symlink-or-copy/-/symlink-or-copy-1.2.0.tgz#4151a81b4052c80bc2becbae09f3a9ec010a9c7a"
|
resolved "https://registry.yarnpkg.com/@types/symlink-or-copy/-/symlink-or-copy-1.2.0.tgz#4151a81b4052c80bc2becbae09f3a9ec010a9c7a"
|
||||||
integrity sha512-Lja2xYuuf2B3knEsga8ShbOdsfNOtzT73GyJmZyY7eGl2+ajOqrs8yM5ze0fsSoYwvA6bw7/Qr7OZ7PEEmYwWg==
|
integrity sha512-Lja2xYuuf2B3knEsga8ShbOdsfNOtzT73GyJmZyY7eGl2+ajOqrs8yM5ze0fsSoYwvA6bw7/Qr7OZ7PEEmYwWg==
|
||||||
|
|
||||||
|
"@uppy/aws-s3-multipart@^1.8.18":
|
||||||
|
version "1.8.18"
|
||||||
|
resolved "https://registry.yarnpkg.com/@uppy/aws-s3-multipart/-/aws-s3-multipart-1.8.18.tgz#d0b3ede025d06b615ad3df90c3771eed38f68d87"
|
||||||
|
integrity sha512-m+IJSsDF253igTlQb2vgCTetqd+qgNIBX48i8HGnLj4rBfRd4FjpBpcV7DgfAn7QVOfrQOgOJoz9cGtXdaZ3lA==
|
||||||
|
dependencies:
|
||||||
|
"@uppy/companion-client" "^1.10.2"
|
||||||
|
"@uppy/utils" "^3.6.2"
|
||||||
|
|
||||||
|
"@uppy/aws-s3@^1.7.12":
|
||||||
|
version "1.7.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/@uppy/aws-s3/-/aws-s3-1.7.12.tgz#5fd3259afc06feb745129ee224f93b618934be63"
|
||||||
|
integrity sha512-9Q8EMg1vQlDrmhaLs5UUQn4kAszLa8E2c1c4mD2urkpS/jHofdF4geRRtp4g4/xvBwwtnhzGqPX4dIylvoZICQ==
|
||||||
|
dependencies:
|
||||||
|
"@uppy/companion-client" "^1.10.2"
|
||||||
|
"@uppy/utils" "^3.6.2"
|
||||||
|
"@uppy/xhr-upload" "^1.7.5"
|
||||||
|
cuid "^2.1.1"
|
||||||
|
qs-stringify "^1.1.0"
|
||||||
|
url-parse "^1.4.7"
|
||||||
|
|
||||||
|
"@uppy/companion-client@^1.10.2":
|
||||||
|
version "1.10.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@uppy/companion-client/-/companion-client-1.10.2.tgz#a640b3ef90b91751c49bf4b6a7a63c2ebac294f6"
|
||||||
|
integrity sha512-5RmsNF9UBvUqmqQz48SoiLvkpGmvQTgwNM4bJX8xwVozv/6goRpFrsMJGLwqFcHS/9xj6STKOqrM582g8exVwQ==
|
||||||
|
dependencies:
|
||||||
|
"@uppy/utils" "^3.6.2"
|
||||||
|
namespace-emitter "^2.0.1"
|
||||||
|
qs-stringify "^1.1.0"
|
||||||
|
url-parse "^1.4.7"
|
||||||
|
|
||||||
|
"@uppy/core@^1.19.2":
|
||||||
|
version "1.19.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@uppy/core/-/core-1.19.2.tgz#0db125586bc663921066d9098a4c9b39355b8135"
|
||||||
|
integrity sha512-2aHvUMdH8fs2eFn30LzNZDHCKoUNAyC+MXwM2NQeO858o0gj2R4axZbrheXnpXrI9dB6RGELGIGkS+ZhnjQAmA==
|
||||||
|
dependencies:
|
||||||
|
"@transloadit/prettier-bytes" "0.0.7"
|
||||||
|
"@uppy/store-default" "^1.2.7"
|
||||||
|
"@uppy/utils" "^3.6.2"
|
||||||
|
cuid "^2.1.1"
|
||||||
|
lodash.throttle "^4.1.1"
|
||||||
|
mime-match "^1.0.2"
|
||||||
|
namespace-emitter "^2.0.1"
|
||||||
|
preact "8.2.9"
|
||||||
|
|
||||||
|
"@uppy/drop-target@^0.2.4":
|
||||||
|
version "0.2.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@uppy/drop-target/-/drop-target-0.2.4.tgz#92e4ffa0d34781a37760e98850262c14b8718c2d"
|
||||||
|
integrity sha512-aRACD7f5jznt7NhLAtw/Nyi94XVjgYnqO3LN2mIbBQrsoQ+mINMzIu4rdVBhpGvk7qNM6961d5jPmPYSUBNiUw==
|
||||||
|
dependencies:
|
||||||
|
"@uppy/utils" "^3.6.2"
|
||||||
|
|
||||||
|
"@uppy/store-default@^1.2.7":
|
||||||
|
version "1.2.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/@uppy/store-default/-/store-default-1.2.7.tgz#41a0b1579f4d5b86c236e7f5e52fdc01960bb011"
|
||||||
|
integrity sha512-58IG9yk/i/kYQ9uEwAwMFl1H2V3syOoODrYoFfVHlxaqv+9MkXBg2tHE2gk40iaAIxcCErcPxZkBOvkqzO1SQA==
|
||||||
|
|
||||||
|
"@uppy/utils@^3.6.2":
|
||||||
|
version "3.6.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@uppy/utils/-/utils-3.6.2.tgz#78b02455b9c469d927d22736be5b68cda2600826"
|
||||||
|
integrity sha512-wGTZma7eywIojfuE1vXlT0fxPSpmCRMkfgFWYc+6TL2FfGqWInmePoB+yal6/M2AnjeKHz6XYMhIpZkjOxFvcw==
|
||||||
|
dependencies:
|
||||||
|
abortcontroller-polyfill "^1.4.0"
|
||||||
|
lodash.throttle "^4.1.1"
|
||||||
|
|
||||||
|
"@uppy/xhr-upload@^1.7.5":
|
||||||
|
version "1.7.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@uppy/xhr-upload/-/xhr-upload-1.7.5.tgz#990ba3e698503bd51534a59fd426096e37ef942b"
|
||||||
|
integrity sha512-Itnc9j9k/PemcmT5KrZ1BEw3pTc6WJg0yyyOcE+hLO8Hjv60Fm7c/I2ZknarOroIjT1WiTSyuxTBPp+9UGkxNA==
|
||||||
|
dependencies:
|
||||||
|
"@uppy/companion-client" "^1.10.2"
|
||||||
|
"@uppy/utils" "^3.6.2"
|
||||||
|
cuid "^2.1.1"
|
||||||
|
|
||||||
"@webassemblyjs/ast@1.9.0":
|
"@webassemblyjs/ast@1.9.0":
|
||||||
version "1.9.0"
|
version "1.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964"
|
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964"
|
||||||
|
@ -1542,6 +1620,11 @@ abbrev@1:
|
||||||
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
|
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
|
||||||
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
|
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
|
||||||
|
|
||||||
|
abortcontroller-polyfill@^1.4.0:
|
||||||
|
version "1.7.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz#1b5b487bd6436b5b764fd52a612509702c3144b5"
|
||||||
|
integrity sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q==
|
||||||
|
|
||||||
accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
|
accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
|
||||||
version "1.3.7"
|
version "1.3.7"
|
||||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
|
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
|
||||||
|
@ -4279,6 +4362,11 @@ cssstyle@^2.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
cssom "~0.3.6"
|
cssom "~0.3.6"
|
||||||
|
|
||||||
|
cuid@^2.1.1:
|
||||||
|
version "2.1.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/cuid/-/cuid-2.1.8.tgz#cbb88f954171e0d5747606c0139fb65c5101eac0"
|
||||||
|
integrity sha512-xiEMER6E7TlTPnDxrM4eRiC6TRgjNX9xzEZ5U/Se2YJKr7Mq4pJn/2XEHjl3STcSh96GmkHPcBXLES8M29wyyg==
|
||||||
|
|
||||||
cyclist@^1.0.1:
|
cyclist@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
|
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
|
||||||
|
@ -8038,6 +8126,11 @@ lodash.templatesettings@^4.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
lodash._reinterpolate "^3.0.0"
|
lodash._reinterpolate "^3.0.0"
|
||||||
|
|
||||||
|
lodash.throttle@^4.1.1:
|
||||||
|
version "4.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
|
||||||
|
integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=
|
||||||
|
|
||||||
lodash.truncate@^4.4.2:
|
lodash.truncate@^4.4.2:
|
||||||
version "4.4.2"
|
version "4.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
|
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
|
||||||
|
@ -8331,6 +8424,13 @@ mime-db@1.47.0, "mime-db@>= 1.43.0 < 2":
|
||||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c"
|
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c"
|
||||||
integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==
|
integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==
|
||||||
|
|
||||||
|
mime-match@^1.0.2:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/mime-match/-/mime-match-1.0.2.tgz#3f87c31e9af1a5fd485fb9db134428b23bbb7ba8"
|
||||||
|
integrity sha1-P4fDHprxpf1IX7nbE0Qosju7e6g=
|
||||||
|
dependencies:
|
||||||
|
wildcard "^1.1.0"
|
||||||
|
|
||||||
mime-types@^2.1.12, mime-types@^2.1.18, mime-types@^2.1.26, mime-types@~2.1.19, mime-types@~2.1.24:
|
mime-types@^2.1.12, mime-types@^2.1.18, mime-types@^2.1.26, mime-types@~2.1.19, mime-types@~2.1.24:
|
||||||
version "2.1.30"
|
version "2.1.30"
|
||||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d"
|
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d"
|
||||||
|
@ -8509,6 +8609,11 @@ mute-stream@0.0.8:
|
||||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
|
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
|
||||||
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
|
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
|
||||||
|
|
||||||
|
namespace-emitter@^2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/namespace-emitter/-/namespace-emitter-2.0.1.tgz#978d51361c61313b4e6b8cf6f3853d08dfa2b17c"
|
||||||
|
integrity sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==
|
||||||
|
|
||||||
nan@^2.12.1:
|
nan@^2.12.1:
|
||||||
version "2.14.2"
|
version "2.14.2"
|
||||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
|
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
|
||||||
|
@ -9217,6 +9322,11 @@ posix-character-classes@^0.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
|
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
|
||||||
integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
|
integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
|
||||||
|
|
||||||
|
preact@8.2.9:
|
||||||
|
version "8.2.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/preact/-/preact-8.2.9.tgz#813ba9dd45e5d97c5ea0d6c86d375b3be711cc40"
|
||||||
|
integrity sha512-ThuGXBmJS3VsT+jIP+eQufD3L8pRw/PY3FoCys6O9Pu6aF12Pn9zAJDX99TfwRAFOCEKm/P0lwiPTbqKMJp0fA==
|
||||||
|
|
||||||
prelude-ls@^1.2.1:
|
prelude-ls@^1.2.1:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
||||||
|
@ -9369,6 +9479,11 @@ punycode@^2.1.0, punycode@^2.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||||
|
|
||||||
|
qs-stringify@^1.1.0:
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/qs-stringify/-/qs-stringify-1.2.1.tgz#9b39ef6b816bd83309628fc9dad435fc0eccc28b"
|
||||||
|
integrity sha512-2N5xGLGZUxpgAYq1fD1LmBSCbxQVsXYt5JU0nU3FuPWO8PlCnKNFQwXkZgyB6mrTdg7IbexX4wxIR403dJw9pw==
|
||||||
|
|
||||||
qs@6.7.0:
|
qs@6.7.0:
|
||||||
version "6.7.0"
|
version "6.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
|
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
|
||||||
|
@ -9405,6 +9520,11 @@ querystring@0.2.0:
|
||||||
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
|
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
|
||||||
integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
|
integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
|
||||||
|
|
||||||
|
querystringify@^2.1.1:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
|
||||||
|
integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
|
||||||
|
|
||||||
queue-microtask@^1.2.2:
|
queue-microtask@^1.2.2:
|
||||||
version "1.2.3"
|
version "1.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||||
|
@ -11296,6 +11416,14 @@ url-parse-lax@^3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
prepend-http "^2.0.0"
|
prepend-http "^2.0.0"
|
||||||
|
|
||||||
|
url-parse@^1.4.7:
|
||||||
|
version "1.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b"
|
||||||
|
integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==
|
||||||
|
dependencies:
|
||||||
|
querystringify "^2.1.1"
|
||||||
|
requires-port "^1.0.0"
|
||||||
|
|
||||||
url-to-options@^1.0.1:
|
url-to-options@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"
|
resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"
|
||||||
|
@ -11622,6 +11750,11 @@ wide-align@^1.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
string-width "^1.0.2 || 2"
|
string-width "^1.0.2 || 2"
|
||||||
|
|
||||||
|
wildcard@^1.1.0:
|
||||||
|
version "1.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-1.1.2.tgz#a7020453084d8cd2efe70ba9d3696263de1710a5"
|
||||||
|
integrity sha1-pwIEUwhNjNLv5wup02liY94XEKU=
|
||||||
|
|
||||||
word-wrap@^1.2.3, word-wrap@~1.2.3:
|
word-wrap@^1.2.3, word-wrap@~1.2.3:
|
||||||
version "1.2.3"
|
version "1.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
|
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
|
||||||
|
|
|
@ -16,8 +16,12 @@ class UploadsController < ApplicationController
|
||||||
# capture current user for block later on
|
# capture current user for block later on
|
||||||
me = current_user
|
me = current_user
|
||||||
|
|
||||||
|
params.permit(:type, :upload_type)
|
||||||
|
if params[:type].blank? && params[:upload_type].blank?
|
||||||
|
raise Discourse::InvalidParameters
|
||||||
|
end
|
||||||
# 50 characters ought to be enough for the upload type
|
# 50 characters ought to be enough for the upload type
|
||||||
type = params.require(:type).parameterize(separator: "_")[0..50]
|
type = (params[:upload_type].presence || params[:type].presence).parameterize(separator: "_")[0..50]
|
||||||
|
|
||||||
if type == "avatar" && !me.admin? && (SiteSetting.discourse_connect_overrides_avatar || !SiteSetting.allow_uploaded_avatars)
|
if type == "avatar" && !me.admin? && (SiteSetting.discourse_connect_overrides_avatar || !SiteSetting.allow_uploaded_avatars)
|
||||||
return render json: failed_json, status: 422
|
return render json: failed_json, status: 422
|
||||||
|
|
|
@ -267,6 +267,10 @@ basic:
|
||||||
client: true
|
client: true
|
||||||
default: true
|
default: true
|
||||||
hidden: true
|
hidden: true
|
||||||
|
enable_experimental_image_uploader:
|
||||||
|
client: true
|
||||||
|
default: false
|
||||||
|
hidden: true
|
||||||
default_theme_id:
|
default_theme_id:
|
||||||
default: -1
|
default: -1
|
||||||
hidden: true
|
hidden: true
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
"@uppy/aws-s3": "^1.7.12",
|
"@uppy/aws-s3": "^1.7.12",
|
||||||
"@uppy/aws-s3-multipart": "^1.8.18",
|
"@uppy/aws-s3-multipart": "^1.8.18",
|
||||||
"@uppy/core": "^1.19.2",
|
"@uppy/core": "^1.19.2",
|
||||||
|
"@uppy/drop-target": "^0.2.4",
|
||||||
"@uppy/xhr-upload": "^1.7.5",
|
"@uppy/xhr-upload": "^1.7.5",
|
||||||
"ace-builds": "1.4.12",
|
"ace-builds": "1.4.12",
|
||||||
"blueimp-file-upload": "10.13.0",
|
"blueimp-file-upload": "10.13.0",
|
||||||
|
|
|
@ -23,9 +23,13 @@ describe UploadsController do
|
||||||
let(:fake_jpg) { Rack::Test::UploadedFile.new(file_from_fixtures("fake.jpg")) }
|
let(:fake_jpg) { Rack::Test::UploadedFile.new(file_from_fixtures("fake.jpg")) }
|
||||||
let(:text_file) { Rack::Test::UploadedFile.new(File.new("#{Rails.root}/LICENSE.txt")) }
|
let(:text_file) { Rack::Test::UploadedFile.new(File.new("#{Rails.root}/LICENSE.txt")) }
|
||||||
|
|
||||||
it 'expects a type' do
|
it 'expects a type or upload_type' do
|
||||||
post "/uploads.json", params: { file: logo }
|
post "/uploads.json", params: { file: logo }
|
||||||
expect(response.status).to eq(400)
|
expect(response.status).to eq(400)
|
||||||
|
post "/uploads.json", params: { file: Rack::Test::UploadedFile.new(logo_file), type: "avatar" }
|
||||||
|
expect(response.status).to eq 200
|
||||||
|
post "/uploads.json", params: { file: Rack::Test::UploadedFile.new(logo_file), upload_type: "avatar" }
|
||||||
|
expect(response.status).to eq 200
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'is successful with an image' do
|
it 'is successful with an image' do
|
||||||
|
|
|
@ -9,3 +9,4 @@ Uppy.Plugin = Uppy.Core.Plugin
|
||||||
Uppy.XHRUpload = require('@uppy/xhr-upload')
|
Uppy.XHRUpload = require('@uppy/xhr-upload')
|
||||||
Uppy.AwsS3 = require('@uppy/aws-s3')
|
Uppy.AwsS3 = require('@uppy/aws-s3')
|
||||||
Uppy.AwsS3Multipart = require('@uppy/aws-s3-multipart')
|
Uppy.AwsS3Multipart = require('@uppy/aws-s3-multipart')
|
||||||
|
Uppy.DropTarget = require('@uppy/drop-target')
|
||||||
|
|
|
@ -500,7 +500,7 @@ var MultipartUploader = /*#__PURE__*/function () {
|
||||||
}();
|
}();
|
||||||
|
|
||||||
module.exports = MultipartUploader;
|
module.exports = MultipartUploader;
|
||||||
},{"@uppy/utils/lib/AbortController":20,"@uppy/utils/lib/delay":26}],3:[function(require,module,exports){
|
},{"@uppy/utils/lib/AbortController":21,"@uppy/utils/lib/delay":27}],3:[function(require,module,exports){
|
||||||
var _class, _temp;
|
var _class, _temp;
|
||||||
|
|
||||||
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
||||||
|
@ -1078,7 +1078,7 @@ module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
|
||||||
|
|
||||||
return AwsS3Multipart;
|
return AwsS3Multipart;
|
||||||
}(Plugin), _class.VERSION = "1.8.18", _temp);
|
}(Plugin), _class.VERSION = "1.8.18", _temp);
|
||||||
},{"./MultipartUploader":2,"@uppy/companion-client":12,"@uppy/core":15,"@uppy/utils/lib/EventTracker":21,"@uppy/utils/lib/RateLimitedQueue":24,"@uppy/utils/lib/emitSocketProgress":27,"@uppy/utils/lib/getSocketHost":34}],4:[function(require,module,exports){
|
},{"./MultipartUploader":2,"@uppy/companion-client":12,"@uppy/core":15,"@uppy/utils/lib/EventTracker":22,"@uppy/utils/lib/RateLimitedQueue":25,"@uppy/utils/lib/emitSocketProgress":28,"@uppy/utils/lib/getSocketHost":40}],4:[function(require,module,exports){
|
||||||
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||||
|
|
||||||
var cuid = require('cuid');
|
var cuid = require('cuid');
|
||||||
|
@ -1492,7 +1492,7 @@ module.exports = /*#__PURE__*/function () {
|
||||||
|
|
||||||
return MiniXHRUpload;
|
return MiniXHRUpload;
|
||||||
}();
|
}();
|
||||||
},{"@uppy/companion-client":12,"@uppy/utils/lib/EventTracker":21,"@uppy/utils/lib/NetworkError":22,"@uppy/utils/lib/ProgressTimeout":23,"@uppy/utils/lib/emitSocketProgress":27,"@uppy/utils/lib/getSocketHost":34,"@uppy/utils/lib/isNetworkError":38,"cuid":43}],5:[function(require,module,exports){
|
},{"@uppy/companion-client":12,"@uppy/utils/lib/EventTracker":22,"@uppy/utils/lib/NetworkError":23,"@uppy/utils/lib/ProgressTimeout":24,"@uppy/utils/lib/emitSocketProgress":28,"@uppy/utils/lib/getSocketHost":40,"@uppy/utils/lib/isNetworkError":44,"cuid":50}],5:[function(require,module,exports){
|
||||||
var _class, _temp;
|
var _class, _temp;
|
||||||
|
|
||||||
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
||||||
|
@ -1829,7 +1829,7 @@ module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
|
||||||
|
|
||||||
return AwsS3;
|
return AwsS3;
|
||||||
}(Plugin), _class.VERSION = "1.7.12", _temp);
|
}(Plugin), _class.VERSION = "1.7.12", _temp);
|
||||||
},{"./MiniXHRUpload":4,"./isXml":6,"@uppy/companion-client":12,"@uppy/core":15,"@uppy/utils/lib/RateLimitedQueue":24,"@uppy/utils/lib/Translator":25,"@uppy/utils/lib/hasProperty":36,"@uppy/utils/lib/settle":40,"qs-stringify":51,"url-parse":54}],6:[function(require,module,exports){
|
},{"./MiniXHRUpload":4,"./isXml":6,"@uppy/companion-client":12,"@uppy/core":15,"@uppy/utils/lib/RateLimitedQueue":25,"@uppy/utils/lib/Translator":26,"@uppy/utils/lib/hasProperty":42,"@uppy/utils/lib/settle":46,"qs-stringify":58,"url-parse":61}],6:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* Remove parameters like `charset=utf-8` from the end of a mime type string.
|
* Remove parameters like `charset=utf-8` from the end of a mime type string.
|
||||||
*
|
*
|
||||||
|
@ -2069,7 +2069,7 @@ module.exports = /*#__PURE__*/function (_RequestClient) {
|
||||||
|
|
||||||
return Provider;
|
return Provider;
|
||||||
}(RequestClient);
|
}(RequestClient);
|
||||||
},{"./RequestClient":9,"./tokenStorage":13,"qs-stringify":51,"url-parse":54}],9:[function(require,module,exports){
|
},{"./RequestClient":9,"./tokenStorage":13,"qs-stringify":58,"url-parse":61}],9:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _class, _temp;
|
var _class, _temp;
|
||||||
|
@ -2289,7 +2289,7 @@ module.exports = (_temp = _class = /*#__PURE__*/function () {
|
||||||
|
|
||||||
return RequestClient;
|
return RequestClient;
|
||||||
}(), _class.VERSION = "1.10.2", _temp);
|
}(), _class.VERSION = "1.10.2", _temp);
|
||||||
},{"./AuthError":7,"@uppy/utils/lib/fetchWithNetworkError":28}],10:[function(require,module,exports){
|
},{"./AuthError":7,"@uppy/utils/lib/fetchWithNetworkError":29}],10:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
|
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
|
||||||
|
@ -2424,7 +2424,7 @@ module.exports = /*#__PURE__*/function () {
|
||||||
|
|
||||||
return UppySocket;
|
return UppySocket;
|
||||||
}();
|
}();
|
||||||
},{"namespace-emitter":49}],12:[function(require,module,exports){
|
},{"namespace-emitter":56}],12:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
/**
|
/**
|
||||||
* Manages communications with Companion
|
* Manages communications with Companion
|
||||||
|
@ -2669,7 +2669,7 @@ module.exports = /*#__PURE__*/function () {
|
||||||
|
|
||||||
return Plugin;
|
return Plugin;
|
||||||
}();
|
}();
|
||||||
},{"@uppy/utils/lib/findDOMElement":29,"preact":50}],15:[function(require,module,exports){
|
},{"@uppy/utils/lib/findDOMElement":30,"preact":57}],15:[function(require,module,exports){
|
||||||
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||||
|
|
||||||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
||||||
|
@ -4592,7 +4592,7 @@ module.exports = function core(opts) {
|
||||||
module.exports.Uppy = Uppy;
|
module.exports.Uppy = Uppy;
|
||||||
module.exports.Plugin = Plugin;
|
module.exports.Plugin = Plugin;
|
||||||
module.exports.debugLogger = debugLogger;
|
module.exports.debugLogger = debugLogger;
|
||||||
},{"../package.json":18,"./Plugin":14,"./loggers":16,"./supportsUploadProgress":17,"@transloadit/prettier-bytes":1,"@uppy/store-default":19,"@uppy/utils/lib/Translator":25,"@uppy/utils/lib/findIndex":30,"@uppy/utils/lib/generateFileID":31,"@uppy/utils/lib/getFileNameAndExtension":32,"@uppy/utils/lib/getFileType":33,"cuid":43,"lodash.throttle":47,"mime-match":48,"namespace-emitter":49}],16:[function(require,module,exports){
|
},{"../package.json":18,"./Plugin":14,"./loggers":16,"./supportsUploadProgress":17,"@transloadit/prettier-bytes":1,"@uppy/store-default":20,"@uppy/utils/lib/Translator":26,"@uppy/utils/lib/findIndex":31,"@uppy/utils/lib/generateFileID":32,"@uppy/utils/lib/getFileNameAndExtension":38,"@uppy/utils/lib/getFileType":39,"cuid":50,"lodash.throttle":54,"mime-match":55,"namespace-emitter":56}],16:[function(require,module,exports){
|
||||||
var getTimeStamp = require('@uppy/utils/lib/getTimeStamp'); // Swallow all logs, except errors.
|
var getTimeStamp = require('@uppy/utils/lib/getTimeStamp'); // Swallow all logs, except errors.
|
||||||
// default if logger is not set or debug: false
|
// default if logger is not set or debug: false
|
||||||
|
|
||||||
|
@ -4646,7 +4646,7 @@ module.exports = {
|
||||||
justErrorsLogger: justErrorsLogger,
|
justErrorsLogger: justErrorsLogger,
|
||||||
debugLogger: debugLogger
|
debugLogger: debugLogger
|
||||||
};
|
};
|
||||||
},{"@uppy/utils/lib/getTimeStamp":35}],17:[function(require,module,exports){
|
},{"@uppy/utils/lib/getTimeStamp":41}],17:[function(require,module,exports){
|
||||||
// Edge 15.x does not fire 'progress' events on uploads.
|
// Edge 15.x does not fire 'progress' events on uploads.
|
||||||
// See https://github.com/transloadit/uppy/issues/945
|
// See https://github.com/transloadit/uppy/issues/945
|
||||||
// And https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12224510/
|
// And https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12224510/
|
||||||
|
@ -4720,6 +4720,171 @@ module.exports={
|
||||||
}
|
}
|
||||||
|
|
||||||
},{}],19:[function(require,module,exports){
|
},{}],19:[function(require,module,exports){
|
||||||
|
var _class, _temp;
|
||||||
|
|
||||||
|
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||||
|
|
||||||
|
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
|
||||||
|
|
||||||
|
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
||||||
|
|
||||||
|
var _require = require('@uppy/core'),
|
||||||
|
Plugin = _require.Plugin;
|
||||||
|
|
||||||
|
var getDroppedFiles = require('@uppy/utils/lib/getDroppedFiles');
|
||||||
|
|
||||||
|
var toArray = require('@uppy/utils/lib/toArray');
|
||||||
|
/**
|
||||||
|
* Drop Target plugin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
|
||||||
|
_inheritsLoose(DropTarget, _Plugin);
|
||||||
|
|
||||||
|
function DropTarget(uppy, opts) {
|
||||||
|
var _this;
|
||||||
|
|
||||||
|
_this = _Plugin.call(this, uppy, opts) || this;
|
||||||
|
|
||||||
|
_this.addFiles = function (files) {
|
||||||
|
var descriptors = files.map(function (file) {
|
||||||
|
return {
|
||||||
|
source: _this.id,
|
||||||
|
name: file.name,
|
||||||
|
type: file.type,
|
||||||
|
data: file,
|
||||||
|
meta: {
|
||||||
|
// path of the file relative to the ancestor directory the user selected.
|
||||||
|
// e.g. 'docs/Old Prague/airbnb.pdf'
|
||||||
|
relativePath: file.relativePath || null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
_this.uppy.addFiles(descriptors);
|
||||||
|
} catch (err) {
|
||||||
|
_this.uppy.log(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_this.handleDrop = function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
clearTimeout(_this.removeDragOverClassTimeout); // 2. Remove dragover class
|
||||||
|
|
||||||
|
event.currentTarget.classList.remove('uppy-is-drag-over');
|
||||||
|
|
||||||
|
_this.setPluginState({
|
||||||
|
isDraggingOver: false
|
||||||
|
}); // 3. Add all dropped files
|
||||||
|
|
||||||
|
|
||||||
|
_this.uppy.log('[DropTarget] Files were dropped');
|
||||||
|
|
||||||
|
var logDropError = function logDropError(error) {
|
||||||
|
_this.uppy.log(error, 'error');
|
||||||
|
};
|
||||||
|
|
||||||
|
getDroppedFiles(event.dataTransfer, {
|
||||||
|
logDropError: logDropError
|
||||||
|
}).then(function (files) {
|
||||||
|
return _this.addFiles(files);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
_this.handleDragOver = function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation(); // 1. Add a small (+) icon on drop
|
||||||
|
// (and prevent browsers from interpreting this as files being _moved_ into the browser,
|
||||||
|
// https://github.com/transloadit/uppy/issues/1978)
|
||||||
|
|
||||||
|
event.dataTransfer.dropEffect = 'copy';
|
||||||
|
clearTimeout(_this.removeDragOverClassTimeout);
|
||||||
|
event.currentTarget.classList.add('uppy-is-drag-over');
|
||||||
|
|
||||||
|
_this.setPluginState({
|
||||||
|
isDraggingOver: true
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
_this.handleDragLeave = function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
var currentTarget = event.currentTarget;
|
||||||
|
clearTimeout(_this.removeDragOverClassTimeout); // Timeout against flickering, this solution is taken from drag-drop library.
|
||||||
|
// Solution with 'pointer-events: none' didn't work across browsers.
|
||||||
|
|
||||||
|
_this.removeDragOverClassTimeout = setTimeout(function () {
|
||||||
|
currentTarget.classList.remove('uppy-is-drag-over');
|
||||||
|
|
||||||
|
_this.setPluginState({
|
||||||
|
isDraggingOver: false
|
||||||
|
});
|
||||||
|
}, 50);
|
||||||
|
};
|
||||||
|
|
||||||
|
_this.addListeners = function () {
|
||||||
|
var target = _this.opts.target;
|
||||||
|
|
||||||
|
if (target instanceof Element) {
|
||||||
|
_this.nodes = [target];
|
||||||
|
} else if (typeof target === 'string') {
|
||||||
|
_this.nodes = toArray(document.querySelectorAll(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_this.nodes && !_this.nodes.length > 0) {
|
||||||
|
throw new Error("\"" + target + "\" does not match any HTML elements");
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.nodes.forEach(function (node) {
|
||||||
|
node.addEventListener('dragover', _this.handleDragOver, false);
|
||||||
|
node.addEventListener('dragleave', _this.handleDragLeave, false);
|
||||||
|
node.addEventListener('drop', _this.handleDrop, false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
_this.removeListeners = function () {
|
||||||
|
if (_this.nodes) {
|
||||||
|
_this.nodes.forEach(function (node) {
|
||||||
|
node.removeEventListener('dragover', _this.handleDragOver, false);
|
||||||
|
node.removeEventListener('dragleave', _this.handleDragLeave, false);
|
||||||
|
node.removeEventListener('drop', _this.handleDrop, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_this.type = 'acquirer';
|
||||||
|
_this.id = _this.opts.id || 'DropTarget';
|
||||||
|
_this.title = 'Drop Target'; // Default options
|
||||||
|
|
||||||
|
var defaultOpts = {
|
||||||
|
target: null
|
||||||
|
}; // Merge default options with the ones set by user
|
||||||
|
|
||||||
|
_this.opts = _extends({}, defaultOpts, opts);
|
||||||
|
_this.removeDragOverClassTimeout = null;
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
|
||||||
|
var _proto = DropTarget.prototype;
|
||||||
|
|
||||||
|
_proto.install = function install() {
|
||||||
|
this.setPluginState({
|
||||||
|
isDraggingOver: false
|
||||||
|
});
|
||||||
|
this.addListeners();
|
||||||
|
};
|
||||||
|
|
||||||
|
_proto.uninstall = function uninstall() {
|
||||||
|
this.removeListeners();
|
||||||
|
};
|
||||||
|
|
||||||
|
return DropTarget;
|
||||||
|
}(Plugin), _class.VERSION = "0.2.4", _temp);
|
||||||
|
},{"@uppy/core":15,"@uppy/utils/lib/getDroppedFiles":33,"@uppy/utils/lib/toArray":47}],20:[function(require,module,exports){
|
||||||
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4775,7 +4940,7 @@ DefaultStore.VERSION = "1.2.7";
|
||||||
module.exports = function defaultStore() {
|
module.exports = function defaultStore() {
|
||||||
return new DefaultStore();
|
return new DefaultStore();
|
||||||
};
|
};
|
||||||
},{}],20:[function(require,module,exports){
|
},{}],21:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* Little AbortController proxy module so we can swap out the implementation easily later.
|
* Little AbortController proxy module so we can swap out the implementation easily later.
|
||||||
*/
|
*/
|
||||||
|
@ -4801,7 +4966,7 @@ function createAbortError(message) {
|
||||||
exports.AbortController = AbortController;
|
exports.AbortController = AbortController;
|
||||||
exports.AbortSignal = AbortSignal;
|
exports.AbortSignal = AbortSignal;
|
||||||
exports.createAbortError = createAbortError;
|
exports.createAbortError = createAbortError;
|
||||||
},{"abortcontroller-polyfill/dist/abortcontroller":42}],21:[function(require,module,exports){
|
},{"abortcontroller-polyfill/dist/abortcontroller":49}],22:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* Create a wrapper around an event emitter with a `remove` method to remove
|
* Create a wrapper around an event emitter with a `remove` method to remove
|
||||||
* all events that were added using the wrapped emitter.
|
* all events that were added using the wrapped emitter.
|
||||||
|
@ -4833,7 +4998,7 @@ module.exports = /*#__PURE__*/function () {
|
||||||
|
|
||||||
return EventTracker;
|
return EventTracker;
|
||||||
}();
|
}();
|
||||||
},{}],22:[function(require,module,exports){
|
},{}],23:[function(require,module,exports){
|
||||||
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
|
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
|
||||||
|
|
||||||
function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
|
function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
|
||||||
|
@ -4868,7 +5033,7 @@ var NetworkError = /*#__PURE__*/function (_Error) {
|
||||||
}( /*#__PURE__*/_wrapNativeSuper(Error));
|
}( /*#__PURE__*/_wrapNativeSuper(Error));
|
||||||
|
|
||||||
module.exports = NetworkError;
|
module.exports = NetworkError;
|
||||||
},{}],23:[function(require,module,exports){
|
},{}],24:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* Helper to abort upload requests if there has not been any progress for `timeout` ms.
|
* Helper to abort upload requests if there has not been any progress for `timeout` ms.
|
||||||
* Create an instance using `timer = new ProgressTimeout(10000, onTimeout)`
|
* Create an instance using `timer = new ProgressTimeout(10000, onTimeout)`
|
||||||
|
@ -4911,7 +5076,7 @@ var ProgressTimeout = /*#__PURE__*/function () {
|
||||||
}();
|
}();
|
||||||
|
|
||||||
module.exports = ProgressTimeout;
|
module.exports = ProgressTimeout;
|
||||||
},{}],24:[function(require,module,exports){
|
},{}],25:[function(require,module,exports){
|
||||||
var findIndex = require('./findIndex');
|
var findIndex = require('./findIndex');
|
||||||
|
|
||||||
function createCancelError() {
|
function createCancelError() {
|
||||||
|
@ -5093,7 +5258,7 @@ module.exports = /*#__PURE__*/function () {
|
||||||
|
|
||||||
return RateLimitedQueue;
|
return RateLimitedQueue;
|
||||||
}();
|
}();
|
||||||
},{"./findIndex":30}],25:[function(require,module,exports){
|
},{"./findIndex":31}],26:[function(require,module,exports){
|
||||||
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||||
|
|
||||||
var has = require('./hasProperty');
|
var has = require('./hasProperty');
|
||||||
|
@ -5259,7 +5424,7 @@ module.exports = /*#__PURE__*/function () {
|
||||||
|
|
||||||
return Translator;
|
return Translator;
|
||||||
}();
|
}();
|
||||||
},{"./hasProperty":36}],26:[function(require,module,exports){
|
},{"./hasProperty":42}],27:[function(require,module,exports){
|
||||||
var _require = require('./AbortController'),
|
var _require = require('./AbortController'),
|
||||||
createAbortError = _require.createAbortError;
|
createAbortError = _require.createAbortError;
|
||||||
/**
|
/**
|
||||||
|
@ -5299,7 +5464,7 @@ module.exports = function delay(ms, opts) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
},{"./AbortController":20}],27:[function(require,module,exports){
|
},{"./AbortController":21}],28:[function(require,module,exports){
|
||||||
var throttle = require('lodash.throttle');
|
var throttle = require('lodash.throttle');
|
||||||
|
|
||||||
function _emitSocketProgress(uploader, progressData, file) {
|
function _emitSocketProgress(uploader, progressData, file) {
|
||||||
|
@ -5321,7 +5486,7 @@ module.exports = throttle(_emitSocketProgress, 300, {
|
||||||
leading: true,
|
leading: true,
|
||||||
trailing: true
|
trailing: true
|
||||||
});
|
});
|
||||||
},{"lodash.throttle":47}],28:[function(require,module,exports){
|
},{"lodash.throttle":54}],29:[function(require,module,exports){
|
||||||
var NetworkError = require('./NetworkError');
|
var NetworkError = require('./NetworkError');
|
||||||
/**
|
/**
|
||||||
* Wrapper around window.fetch that throws a NetworkError when appropriate
|
* Wrapper around window.fetch that throws a NetworkError when appropriate
|
||||||
|
@ -5337,7 +5502,7 @@ module.exports = function fetchWithNetworkError() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
},{"./NetworkError":22}],29:[function(require,module,exports){
|
},{"./NetworkError":23}],30:[function(require,module,exports){
|
||||||
var isDOMElement = require('./isDOMElement');
|
var isDOMElement = require('./isDOMElement');
|
||||||
/**
|
/**
|
||||||
* Find a DOM element.
|
* Find a DOM element.
|
||||||
|
@ -5360,7 +5525,7 @@ module.exports = function findDOMElement(element, context) {
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},{"./isDOMElement":37}],30:[function(require,module,exports){
|
},{"./isDOMElement":43}],31:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* Array.prototype.findIndex ponyfill for old browsers.
|
* Array.prototype.findIndex ponyfill for old browsers.
|
||||||
*
|
*
|
||||||
|
@ -5375,7 +5540,7 @@ module.exports = function findIndex(array, predicate) {
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
},{}],31:[function(require,module,exports){
|
},{}],32:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* Takes a file object and turns it into fileID, by converting file.name to lowercase,
|
* Takes a file object and turns it into fileID, by converting file.name to lowercase,
|
||||||
* removing extra characters and adding type, size and lastModified
|
* removing extra characters and adding type, size and lastModified
|
||||||
|
@ -5422,7 +5587,147 @@ function encodeFilename(name) {
|
||||||
function encodeCharacter(character) {
|
function encodeCharacter(character) {
|
||||||
return character.charCodeAt(0).toString(32);
|
return character.charCodeAt(0).toString(32);
|
||||||
}
|
}
|
||||||
},{}],32:[function(require,module,exports){
|
},{}],33:[function(require,module,exports){
|
||||||
|
var webkitGetAsEntryApi = require('./utils/webkitGetAsEntryApi/index');
|
||||||
|
|
||||||
|
var fallbackApi = require('./utils/fallbackApi');
|
||||||
|
/**
|
||||||
|
* Returns a promise that resolves to the array of dropped files (if a folder is dropped, and browser supports folder parsing - promise resolves to the flat array of all files in all directories).
|
||||||
|
* Each file has .relativePath prop appended to it (e.g. "/docs/Prague/ticket_from_prague_to_ufa.pdf") if browser supports it. Otherwise it's undefined.
|
||||||
|
*
|
||||||
|
* @param {DataTransfer} dataTransfer
|
||||||
|
* @param {Function} logDropError - a function that's called every time some folder or some file error out (e.g. because of the folder name being too long on Windows). Notice that resulting promise will always be resolved anyway.
|
||||||
|
*
|
||||||
|
* @returns {Promise} - Array<File>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = function getDroppedFiles(dataTransfer, _temp) {
|
||||||
|
var _ref = _temp === void 0 ? {} : _temp,
|
||||||
|
_ref$logDropError = _ref.logDropError,
|
||||||
|
logDropError = _ref$logDropError === void 0 ? function () {} : _ref$logDropError;
|
||||||
|
|
||||||
|
// Get all files from all subdirs. Works (at least) in Chrome, Mozilla, and Safari
|
||||||
|
if (dataTransfer.items && dataTransfer.items[0] && 'webkitGetAsEntry' in dataTransfer.items[0]) {
|
||||||
|
return webkitGetAsEntryApi(dataTransfer, logDropError); // Otherwise just return all first-order files
|
||||||
|
}
|
||||||
|
|
||||||
|
return fallbackApi(dataTransfer);
|
||||||
|
};
|
||||||
|
},{"./utils/fallbackApi":34,"./utils/webkitGetAsEntryApi/index":37}],34:[function(require,module,exports){
|
||||||
|
var toArray = require('../../toArray'); // .files fallback, should be implemented in any browser
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = function fallbackApi(dataTransfer) {
|
||||||
|
var files = toArray(dataTransfer.files);
|
||||||
|
return Promise.resolve(files);
|
||||||
|
};
|
||||||
|
},{"../../toArray":47}],35:[function(require,module,exports){
|
||||||
|
/**
|
||||||
|
* Recursive function, calls the original callback() when the directory is entirely parsed.
|
||||||
|
*
|
||||||
|
* @param {FileSystemDirectoryReader} directoryReader
|
||||||
|
* @param {Array} oldEntries
|
||||||
|
* @param {Function} logDropError
|
||||||
|
* @param {Function} callback - called with ([ all files and directories in that directoryReader ])
|
||||||
|
*/
|
||||||
|
module.exports = function getFilesAndDirectoriesFromDirectory(directoryReader, oldEntries, logDropError, _ref) {
|
||||||
|
var onSuccess = _ref.onSuccess;
|
||||||
|
directoryReader.readEntries(function (entries) {
|
||||||
|
var newEntries = [].concat(oldEntries, entries); // According to the FileSystem API spec, getFilesAndDirectoriesFromDirectory() must be called until it calls the onSuccess with an empty array.
|
||||||
|
|
||||||
|
if (entries.length) {
|
||||||
|
setTimeout(function () {
|
||||||
|
getFilesAndDirectoriesFromDirectory(directoryReader, newEntries, logDropError, {
|
||||||
|
onSuccess: onSuccess
|
||||||
|
});
|
||||||
|
}, 0); // Done iterating this particular directory
|
||||||
|
} else {
|
||||||
|
onSuccess(newEntries);
|
||||||
|
}
|
||||||
|
}, // Make sure we resolve on error anyway, it's fine if only one directory couldn't be parsed!
|
||||||
|
function (error) {
|
||||||
|
logDropError(error);
|
||||||
|
onSuccess(oldEntries);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},{}],36:[function(require,module,exports){
|
||||||
|
/**
|
||||||
|
* Get the relative path from the FileEntry#fullPath, because File#webkitRelativePath is always '', at least onDrop.
|
||||||
|
*
|
||||||
|
* @param {FileEntry} fileEntry
|
||||||
|
*
|
||||||
|
* @returns {string|null} - if file is not in a folder - return null (this is to be consistent with .relativePath-s of files selected from My Device). If file is in a folder - return its fullPath, e.g. '/simpsons/hi.jpeg'.
|
||||||
|
*/
|
||||||
|
module.exports = function getRelativePath(fileEntry) {
|
||||||
|
// fileEntry.fullPath - "/simpsons/hi.jpeg" or undefined (for browsers that don't support it)
|
||||||
|
// fileEntry.name - "hi.jpeg"
|
||||||
|
if (!fileEntry.fullPath || fileEntry.fullPath === "/" + fileEntry.name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileEntry.fullPath;
|
||||||
|
};
|
||||||
|
},{}],37:[function(require,module,exports){
|
||||||
|
var toArray = require('../../../toArray');
|
||||||
|
|
||||||
|
var getRelativePath = require('./getRelativePath');
|
||||||
|
|
||||||
|
var getFilesAndDirectoriesFromDirectory = require('./getFilesAndDirectoriesFromDirectory');
|
||||||
|
|
||||||
|
module.exports = function webkitGetAsEntryApi(dataTransfer, logDropError) {
|
||||||
|
var files = [];
|
||||||
|
var rootPromises = [];
|
||||||
|
/**
|
||||||
|
* Returns a resolved promise, when :files array is enhanced
|
||||||
|
*
|
||||||
|
* @param {(FileSystemFileEntry|FileSystemDirectoryEntry)} entry
|
||||||
|
* @returns {Promise} - empty promise that resolves when :files is enhanced with a file
|
||||||
|
*/
|
||||||
|
|
||||||
|
var createPromiseToAddFileOrParseDirectory = function createPromiseToAddFileOrParseDirectory(entry) {
|
||||||
|
return new Promise(function (resolve) {
|
||||||
|
// This is a base call
|
||||||
|
if (entry.isFile) {
|
||||||
|
// Creates a new File object which can be used to read the file.
|
||||||
|
entry.file(function (file) {
|
||||||
|
file.relativePath = getRelativePath(entry);
|
||||||
|
files.push(file);
|
||||||
|
resolve();
|
||||||
|
}, // Make sure we resolve on error anyway, it's fine if only one file couldn't be read!
|
||||||
|
function (error) {
|
||||||
|
logDropError(error);
|
||||||
|
resolve();
|
||||||
|
}); // This is a recursive call
|
||||||
|
} else if (entry.isDirectory) {
|
||||||
|
var directoryReader = entry.createReader();
|
||||||
|
getFilesAndDirectoriesFromDirectory(directoryReader, [], logDropError, {
|
||||||
|
onSuccess: function onSuccess(entries) {
|
||||||
|
var promises = entries.map(function (entry) {
|
||||||
|
return createPromiseToAddFileOrParseDirectory(entry);
|
||||||
|
});
|
||||||
|
Promise.all(promises).then(function () {
|
||||||
|
return resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}; // For each dropped item, - make sure it's a file/directory, and start deepening in!
|
||||||
|
|
||||||
|
|
||||||
|
toArray(dataTransfer.items).forEach(function (item) {
|
||||||
|
var entry = item.webkitGetAsEntry(); // :entry can be null when we drop the url e.g.
|
||||||
|
|
||||||
|
if (entry) {
|
||||||
|
rootPromises.push(createPromiseToAddFileOrParseDirectory(entry));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return Promise.all(rootPromises).then(function () {
|
||||||
|
return files;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},{"../../../toArray":47,"./getFilesAndDirectoriesFromDirectory":35,"./getRelativePath":36}],38:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* Takes a full filename string and returns an object {name, extension}
|
* Takes a full filename string and returns an object {name, extension}
|
||||||
*
|
*
|
||||||
|
@ -5444,7 +5749,7 @@ module.exports = function getFileNameAndExtension(fullFileName) {
|
||||||
extension: fullFileName.slice(lastDot + 1)
|
extension: fullFileName.slice(lastDot + 1)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
},{}],33:[function(require,module,exports){
|
},{}],39:[function(require,module,exports){
|
||||||
var getFileNameAndExtension = require('./getFileNameAndExtension');
|
var getFileNameAndExtension = require('./getFileNameAndExtension');
|
||||||
|
|
||||||
var mimeTypes = require('./mimeTypes');
|
var mimeTypes = require('./mimeTypes');
|
||||||
|
@ -5466,7 +5771,7 @@ module.exports = function getFileType(file) {
|
||||||
|
|
||||||
return 'application/octet-stream';
|
return 'application/octet-stream';
|
||||||
};
|
};
|
||||||
},{"./getFileNameAndExtension":32,"./mimeTypes":39}],34:[function(require,module,exports){
|
},{"./getFileNameAndExtension":38,"./mimeTypes":45}],40:[function(require,module,exports){
|
||||||
module.exports = function getSocketHost(url) {
|
module.exports = function getSocketHost(url) {
|
||||||
// get the host domain
|
// get the host domain
|
||||||
var regex = /^(?:https?:\/\/|\/\/)?(?:[^@\n]+@)?(?:www\.)?([^\n]+)/i;
|
var regex = /^(?:https?:\/\/|\/\/)?(?:[^@\n]+@)?(?:www\.)?([^\n]+)/i;
|
||||||
|
@ -5474,7 +5779,7 @@ module.exports = function getSocketHost(url) {
|
||||||
var socketProtocol = /^http:\/\//i.test(url) ? 'ws' : 'wss';
|
var socketProtocol = /^http:\/\//i.test(url) ? 'ws' : 'wss';
|
||||||
return socketProtocol + "://" + host;
|
return socketProtocol + "://" + host;
|
||||||
};
|
};
|
||||||
},{}],35:[function(require,module,exports){
|
},{}],41:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* Returns a timestamp in the format of `hours:minutes:seconds`
|
* Returns a timestamp in the format of `hours:minutes:seconds`
|
||||||
*/
|
*/
|
||||||
|
@ -5493,11 +5798,11 @@ module.exports = function getTimeStamp() {
|
||||||
function pad(str) {
|
function pad(str) {
|
||||||
return str.length !== 2 ? 0 + str : str;
|
return str.length !== 2 ? 0 + str : str;
|
||||||
}
|
}
|
||||||
},{}],36:[function(require,module,exports){
|
},{}],42:[function(require,module,exports){
|
||||||
module.exports = function has(object, key) {
|
module.exports = function has(object, key) {
|
||||||
return Object.prototype.hasOwnProperty.call(object, key);
|
return Object.prototype.hasOwnProperty.call(object, key);
|
||||||
};
|
};
|
||||||
},{}],37:[function(require,module,exports){
|
},{}],43:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* Check if an object is a DOM element. Duck-typing based on `nodeType`.
|
* Check if an object is a DOM element. Duck-typing based on `nodeType`.
|
||||||
*
|
*
|
||||||
|
@ -5506,7 +5811,7 @@ module.exports = function has(object, key) {
|
||||||
module.exports = function isDOMElement(obj) {
|
module.exports = function isDOMElement(obj) {
|
||||||
return obj && typeof obj === 'object' && obj.nodeType === Node.ELEMENT_NODE;
|
return obj && typeof obj === 'object' && obj.nodeType === Node.ELEMENT_NODE;
|
||||||
};
|
};
|
||||||
},{}],38:[function(require,module,exports){
|
},{}],44:[function(require,module,exports){
|
||||||
function isNetworkError(xhr) {
|
function isNetworkError(xhr) {
|
||||||
if (!xhr) {
|
if (!xhr) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -5516,7 +5821,7 @@ function isNetworkError(xhr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = isNetworkError;
|
module.exports = isNetworkError;
|
||||||
},{}],39:[function(require,module,exports){
|
},{}],45:[function(require,module,exports){
|
||||||
// ___Why not add the mime-types package?
|
// ___Why not add the mime-types package?
|
||||||
// It's 19.7kB gzipped, and we only need mime types for well-known extensions (for file previews).
|
// It's 19.7kB gzipped, and we only need mime types for well-known extensions (for file previews).
|
||||||
// ___Where to take new extensions from?
|
// ___Where to take new extensions from?
|
||||||
|
@ -5572,7 +5877,7 @@ module.exports = {
|
||||||
gz: 'application/gzip',
|
gz: 'application/gzip',
|
||||||
dmg: 'application/x-apple-diskimage'
|
dmg: 'application/x-apple-diskimage'
|
||||||
};
|
};
|
||||||
},{}],40:[function(require,module,exports){
|
},{}],46:[function(require,module,exports){
|
||||||
module.exports = function settle(promises) {
|
module.exports = function settle(promises) {
|
||||||
var resolutions = [];
|
var resolutions = [];
|
||||||
var rejections = [];
|
var rejections = [];
|
||||||
|
@ -5595,7 +5900,14 @@ module.exports = function settle(promises) {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
},{}],41:[function(require,module,exports){
|
},{}],47:[function(require,module,exports){
|
||||||
|
/**
|
||||||
|
* Converts list into array
|
||||||
|
*/
|
||||||
|
module.exports = function toArray(list) {
|
||||||
|
return Array.prototype.slice.call(list || [], 0);
|
||||||
|
};
|
||||||
|
},{}],48:[function(require,module,exports){
|
||||||
var _class, _temp;
|
var _class, _temp;
|
||||||
|
|
||||||
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
||||||
|
@ -6335,7 +6647,7 @@ module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
|
||||||
|
|
||||||
return XHRUpload;
|
return XHRUpload;
|
||||||
}(Plugin), _class.VERSION = "1.7.5", _temp);
|
}(Plugin), _class.VERSION = "1.7.5", _temp);
|
||||||
},{"@uppy/companion-client":12,"@uppy/core":15,"@uppy/utils/lib/EventTracker":21,"@uppy/utils/lib/NetworkError":22,"@uppy/utils/lib/ProgressTimeout":23,"@uppy/utils/lib/RateLimitedQueue":24,"@uppy/utils/lib/Translator":25,"@uppy/utils/lib/emitSocketProgress":27,"@uppy/utils/lib/getSocketHost":34,"@uppy/utils/lib/isNetworkError":38,"@uppy/utils/lib/settle":40,"cuid":43}],42:[function(require,module,exports){
|
},{"@uppy/companion-client":12,"@uppy/core":15,"@uppy/utils/lib/EventTracker":22,"@uppy/utils/lib/NetworkError":23,"@uppy/utils/lib/ProgressTimeout":24,"@uppy/utils/lib/RateLimitedQueue":25,"@uppy/utils/lib/Translator":26,"@uppy/utils/lib/emitSocketProgress":28,"@uppy/utils/lib/getSocketHost":40,"@uppy/utils/lib/isNetworkError":44,"@uppy/utils/lib/settle":46,"cuid":50}],49:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', { value: true });
|
Object.defineProperty(exports, '__esModule', { value: true });
|
||||||
|
@ -6665,7 +6977,7 @@ exports.AbortController = AbortController;
|
||||||
exports.AbortSignal = AbortSignal;
|
exports.AbortSignal = AbortSignal;
|
||||||
exports.default = AbortController;
|
exports.default = AbortController;
|
||||||
|
|
||||||
},{}],43:[function(require,module,exports){
|
},{}],50:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* cuid.js
|
* cuid.js
|
||||||
* Collision-resistant UID generator for browsers and node.
|
* Collision-resistant UID generator for browsers and node.
|
||||||
|
@ -6751,7 +7063,7 @@ cuid.fingerprint = fingerprint;
|
||||||
|
|
||||||
module.exports = cuid;
|
module.exports = cuid;
|
||||||
|
|
||||||
},{"./lib/fingerprint.js":44,"./lib/getRandomValue.js":45,"./lib/pad.js":46}],44:[function(require,module,exports){
|
},{"./lib/fingerprint.js":51,"./lib/getRandomValue.js":52,"./lib/pad.js":53}],51:[function(require,module,exports){
|
||||||
var pad = require('./pad.js');
|
var pad = require('./pad.js');
|
||||||
|
|
||||||
var env = typeof window === 'object' ? window : self;
|
var env = typeof window === 'object' ? window : self;
|
||||||
|
@ -6765,7 +7077,7 @@ module.exports = function fingerprint () {
|
||||||
return clientId;
|
return clientId;
|
||||||
};
|
};
|
||||||
|
|
||||||
},{"./pad.js":46}],45:[function(require,module,exports){
|
},{"./pad.js":53}],52:[function(require,module,exports){
|
||||||
|
|
||||||
var getRandomValue;
|
var getRandomValue;
|
||||||
|
|
||||||
|
@ -6785,13 +7097,13 @@ if (crypto) {
|
||||||
|
|
||||||
module.exports = getRandomValue;
|
module.exports = getRandomValue;
|
||||||
|
|
||||||
},{}],46:[function(require,module,exports){
|
},{}],53:[function(require,module,exports){
|
||||||
module.exports = function pad (num, size) {
|
module.exports = function pad (num, size) {
|
||||||
var s = '000000000' + num;
|
var s = '000000000' + num;
|
||||||
return s.substr(s.length - size);
|
return s.substr(s.length - size);
|
||||||
};
|
};
|
||||||
|
|
||||||
},{}],47:[function(require,module,exports){
|
},{}],54:[function(require,module,exports){
|
||||||
(function (global){(function (){
|
(function (global){(function (){
|
||||||
/**
|
/**
|
||||||
* lodash (Custom Build) <https://lodash.com/>
|
* lodash (Custom Build) <https://lodash.com/>
|
||||||
|
@ -7234,7 +7546,7 @@ function toNumber(value) {
|
||||||
module.exports = throttle;
|
module.exports = throttle;
|
||||||
|
|
||||||
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||||||
},{}],48:[function(require,module,exports){
|
},{}],55:[function(require,module,exports){
|
||||||
var wildcard = require('wildcard');
|
var wildcard = require('wildcard');
|
||||||
var reMimePartSplit = /[\/\+\.]/;
|
var reMimePartSplit = /[\/\+\.]/;
|
||||||
|
|
||||||
|
@ -7260,7 +7572,7 @@ module.exports = function(target, pattern) {
|
||||||
return pattern ? test(pattern.split(';')[0]) : test;
|
return pattern ? test(pattern.split(';')[0]) : test;
|
||||||
};
|
};
|
||||||
|
|
||||||
},{"wildcard":55}],49:[function(require,module,exports){
|
},{"wildcard":62}],56:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* Create an event emitter with namespaces
|
* Create an event emitter with namespaces
|
||||||
* @name createNamespaceEmitter
|
* @name createNamespaceEmitter
|
||||||
|
@ -7398,7 +7710,7 @@ module.exports = function createNamespaceEmitter () {
|
||||||
return emitter
|
return emitter
|
||||||
}
|
}
|
||||||
|
|
||||||
},{}],50:[function(require,module,exports){
|
},{}],57:[function(require,module,exports){
|
||||||
!function() {
|
!function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
function VNode() {}
|
function VNode() {}
|
||||||
|
@ -7807,7 +8119,7 @@ module.exports = function createNamespaceEmitter () {
|
||||||
if ('undefined' != typeof module) module.exports = preact; else self.preact = preact;
|
if ('undefined' != typeof module) module.exports = preact; else self.preact = preact;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
},{}],51:[function(require,module,exports){
|
},{}],58:[function(require,module,exports){
|
||||||
var has = Object.prototype.hasOwnProperty
|
var has = Object.prototype.hasOwnProperty
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7839,7 +8151,7 @@ module.exports = function queryStringify (obj, prefix) {
|
||||||
return pairs.join('&')
|
return pairs.join('&')
|
||||||
}
|
}
|
||||||
|
|
||||||
},{}],52:[function(require,module,exports){
|
},{}],59:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var has = Object.prototype.hasOwnProperty
|
var has = Object.prototype.hasOwnProperty
|
||||||
|
@ -7959,7 +8271,7 @@ function querystringify(obj, prefix) {
|
||||||
exports.stringify = querystringify;
|
exports.stringify = querystringify;
|
||||||
exports.parse = querystring;
|
exports.parse = querystring;
|
||||||
|
|
||||||
},{}],53:[function(require,module,exports){
|
},{}],60:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7999,7 +8311,7 @@ module.exports = function required(port, protocol) {
|
||||||
return port !== 0;
|
return port !== 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
},{}],54:[function(require,module,exports){
|
},{}],61:[function(require,module,exports){
|
||||||
(function (global){(function (){
|
(function (global){(function (){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
@ -8465,7 +8777,7 @@ Url.qs = qs;
|
||||||
module.exports = Url;
|
module.exports = Url;
|
||||||
|
|
||||||
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||||||
},{"querystringify":52,"requires-port":53}],55:[function(require,module,exports){
|
},{"querystringify":59,"requires-port":60}],62:[function(require,module,exports){
|
||||||
/* jshint node: true */
|
/* jshint node: true */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
@ -8560,7 +8872,7 @@ module.exports = function(text, test, separator) {
|
||||||
return matcher;
|
return matcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
},{}],56:[function(require,module,exports){
|
},{}],63:[function(require,module,exports){
|
||||||
// We need a custom build of Uppy because we do not use webpack for
|
// We need a custom build of Uppy because we do not use webpack for
|
||||||
// our JS modules/build. The only way to get what you want from Uppy
|
// our JS modules/build. The only way to get what you want from Uppy
|
||||||
// is to use the webpack modules or to include the entire Uppy project
|
// is to use the webpack modules or to include the entire Uppy project
|
||||||
|
@ -8572,5 +8884,6 @@ Uppy.Plugin = Uppy.Core.Plugin
|
||||||
Uppy.XHRUpload = require('@uppy/xhr-upload')
|
Uppy.XHRUpload = require('@uppy/xhr-upload')
|
||||||
Uppy.AwsS3 = require('@uppy/aws-s3')
|
Uppy.AwsS3 = require('@uppy/aws-s3')
|
||||||
Uppy.AwsS3Multipart = require('@uppy/aws-s3-multipart')
|
Uppy.AwsS3Multipart = require('@uppy/aws-s3-multipart')
|
||||||
|
Uppy.DropTarget = require('@uppy/drop-target')
|
||||||
|
|
||||||
},{"@uppy/aws-s3":5,"@uppy/aws-s3-multipart":3,"@uppy/core":15,"@uppy/xhr-upload":41}]},{},[56]);
|
},{"@uppy/aws-s3":5,"@uppy/aws-s3-multipart":3,"@uppy/core":15,"@uppy/drop-target":19,"@uppy/xhr-upload":48}]},{},[63]);
|
||||||
|
|
|
@ -437,6 +437,13 @@
|
||||||
namespace-emitter "^2.0.1"
|
namespace-emitter "^2.0.1"
|
||||||
preact "8.2.9"
|
preact "8.2.9"
|
||||||
|
|
||||||
|
"@uppy/drop-target@^0.2.4":
|
||||||
|
version "0.2.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@uppy/drop-target/-/drop-target-0.2.4.tgz#92e4ffa0d34781a37760e98850262c14b8718c2d"
|
||||||
|
integrity sha512-aRACD7f5jznt7NhLAtw/Nyi94XVjgYnqO3LN2mIbBQrsoQ+mINMzIu4rdVBhpGvk7qNM6961d5jPmPYSUBNiUw==
|
||||||
|
dependencies:
|
||||||
|
"@uppy/utils" "^3.6.2"
|
||||||
|
|
||||||
"@uppy/store-default@^1.2.7":
|
"@uppy/store-default@^1.2.7":
|
||||||
version "1.2.7"
|
version "1.2.7"
|
||||||
resolved "https://registry.yarnpkg.com/@uppy/store-default/-/store-default-1.2.7.tgz#41a0b1579f4d5b86c236e7f5e52fdc01960bb011"
|
resolved "https://registry.yarnpkg.com/@uppy/store-default/-/store-default-1.2.7.tgz#41a0b1579f4d5b86c236e7f5e52fdc01960bb011"
|
||||||
|
|
Loading…
Reference in New Issue