diff --git a/app/assets/javascripts/discourse/app/components/composer-editor.js b/app/assets/javascripts/discourse/app/components/composer-editor.js index d110191c24c..84b6c137194 100644 --- a/app/assets/javascripts/discourse/app/components/composer-editor.js +++ b/app/assets/javascripts/discourse/app/components/composer-editor.js @@ -53,6 +53,13 @@ export function addComposerUploadHandler(extensions, method) { }); } +const uploadProcessorQueue = []; +const uploadProcessorActions = {}; +export function addComposerUploadProcessor(queueItem, actionItem) { + uploadProcessorQueue.push(queueItem); + Object.assign(uploadProcessorActions, actionItem); +} + const uploadMarkdownResolvers = []; export function addComposerUploadMarkdownResolver(resolver) { uploadMarkdownResolvers.push(resolver); @@ -634,12 +641,34 @@ export default Component.extend({ const $element = $(this.element); + $.blueimp.fileupload.prototype.processActions = uploadProcessorActions; + $element.fileupload({ url: getURL(`/uploads.json?client_id=${this.messageBus.clientId}`), dataType: "json", pasteZone: $element, + processQueue: uploadProcessorQueue, }); + $element + .on("fileuploadprocess", (e, data) => { + this.appEvents.trigger( + "composer:insert-text", + `[${I18n.t("processing_filename", { + filename: data.files[data.index].name, + })}]()\n` + ); + }) + .on("fileuploadprocessalways", (e, data) => { + this.appEvents.trigger( + "composer:replace-text", + `[${I18n.t("processing_filename", { + filename: data.files[data.index].name, + })}]()\n`, + "" + ); + }); + $element.on("fileuploadpaste", (e) => { this._pasted = true; diff --git a/app/assets/javascripts/discourse/app/lib/plugin-api.js b/app/assets/javascripts/discourse/app/lib/plugin-api.js index 4d00f3a9e2f..21c71426379 100644 --- a/app/assets/javascripts/discourse/app/lib/plugin-api.js +++ b/app/assets/javascripts/discourse/app/lib/plugin-api.js @@ -1,6 +1,7 @@ import ComposerEditor, { addComposerUploadHandler, addComposerUploadMarkdownResolver, + addComposerUploadProcessor, } from "discourse/components/composer-editor"; import { addButton, removeButton } from "discourse/widgets/post-menu"; import { @@ -72,7 +73,7 @@ import { replaceTagRenderer } from "discourse/lib/render-tag"; import { setNewCategoryDefaultColors } from "discourse/routes/new-category"; // If you add any methods to the API ensure you bump up this number -const PLUGIN_API_VERSION = "0.11.2"; +const PLUGIN_API_VERSION = "0.11.3"; class PluginApi { constructor(version, container) { @@ -933,6 +934,31 @@ class PluginApi { addComposerUploadHandler(extensions, method); } + /** + * Registers a pre-processor for file uploads + * See https://github.com/blueimp/jQuery-File-Upload/wiki/Options#file-processing-options + * Your theme/plugin will also need to load https://github.com/blueimp/jQuery-File-Upload/blob/v10.13.0/js/jquery.fileupload-process.js + * for this hook to work. + * + * Useful for transforming to-be uploaded files client-side + * + * Example: + * + * api.addComposerUploadProcessor({action: 'myFileTransformation'}, { + * myFileTransformation: function (data, options) { + * let p = new Promise((resolve, reject) => { + * let file = data.files[data.index]; + * console.log(`Transforming ${file.name}`); + * // do work... + * resolve(data); + * }); + * return p; + * }); + */ + addComposerUploadProcessor(queueItem, actionItem) { + addComposerUploadProcessor(queueItem, actionItem); + } + /** * Registers a function to generate Markdown after a file has been uploaded. * diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 3ee96c7bfb7..5308b7038b4 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -368,6 +368,7 @@ en: upload: "Upload" uploading: "Uploading..." uploading_filename: "Uploading: %{filename}..." + processing_filename: "Processing: %{filename}..." clipboard: "clipboard" uploaded: "Uploaded!"