0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-11-25 18:50:27 +01:00

Merge pull request #163 from paviliondev/uploader_compatibility_fixes

COMPATIBILITY: support new uploader
Dieser Commit ist enthalten in:
Angus McLeod 2021-12-01 16:38:07 +08:00 committet von GitHub
Commit b95639b315
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
6 geänderte Dateien mit 68 neuen und 225 gelöschten Zeilen

Datei anzeigen

@ -4,7 +4,6 @@
//= require discourse/app/mixins/singleton //= require discourse/app/mixins/singleton
//= require discourse/app/mixins/upload //= require discourse/app/mixins/upload
//= require discourse/app/mixins/composer-upload
//= require discourse/app/mixins/textarea-text-manipulation //= require discourse/app/mixins/textarea-text-manipulation
//= require discourse/app/adapters/rest //= require discourse/app/adapters/rest

Datei anzeigen

@ -4,24 +4,14 @@ import {
on, on,
} from "discourse-common/utils/decorators"; } from "discourse-common/utils/decorators";
import { findRawTemplate } from "discourse-common/lib/raw-templates"; import { findRawTemplate } from "discourse-common/lib/raw-templates";
import { next, scheduleOnce, throttle } from "@ember/runloop"; import { scheduleOnce, throttle } from "@ember/runloop";
import { caretPosition, inCodeBlock } from "discourse/lib/utilities"; import { caretPosition, inCodeBlock } from "discourse/lib/utilities";
import highlightSyntax from "discourse/lib/highlight-syntax"; import highlightSyntax from "discourse/lib/highlight-syntax";
import { getToken } from "wizard/lib/ajax";
import {
displayErrorForUpload,
getUploadMarkdown,
uploadIcon,
validateUploadedFiles,
} from "discourse/lib/uploads";
import { cacheShortUploadUrl } from "pretty-text/upload-short-url";
import { alias } from "@ember/object/computed"; import { alias } from "@ember/object/computed";
import WizardI18n from "../lib/wizard-i18n";
import Site from "../models/site"; import Site from "../models/site";
import { uploadIcon } from "discourse/lib/uploads";
import { dasherize } from "@ember/string";
const uploadMarkdownResolvers = [];
const uploadHandlers = [];
export default ComposerEditor.extend({ export default ComposerEditor.extend({
classNameBindings: ["fieldClass"], classNameBindings: ["fieldClass"],
allowUpload: true, allowUpload: true,
@ -35,6 +25,7 @@ export default ComposerEditor.extend({
popupMenuOptions: [], popupMenuOptions: [],
draftStatus: "null", draftStatus: "null",
replyPlaceholder: alias("field.placeholder"), replyPlaceholder: alias("field.placeholder"),
uploadingFieldId: null,
@on("didInsertElement") @on("didInsertElement")
_composerEditorInit() { _composerEditorInit() {
@ -90,6 +81,50 @@ export default ComposerEditor.extend({
} }
this._bindUploadTarget(); this._bindUploadTarget();
const wizardEventNames = ["insert-text", "replace-text"];
const eventPrefix = this.eventPrefix;
const session = this.get("session");
this.appEvents.reopen({
trigger(name, ...args) {
let eventParts = name.split(":");
let currentEventPrefix = eventParts[0];
let currentEventName = eventParts[1];
if (
currentEventPrefix !== "wizard-editor" &&
wizardEventNames.some((wen) => wen === currentEventName)
) {
let wizardName = name.replace(eventPrefix, "wizard-editor");
if (currentEventName === "insert-text") {
args = {
text: args[0],
};
}
if (currentEventName === "replace-text") {
args = {
oldVal: args[0],
newVal: args[1],
};
}
let wizardArgs = Object.assign(
{},
{
fieldId: session.get("uploadingFieldId"),
},
args
);
return this._super(wizardName, wizardArgs);
} else {
return this._super(name, ...args);
}
},
});
},
@discourseComputed("field.id")
fileUploadElementId(fieldId) {
return `file-uploader-${dasherize(fieldId)}`;
}, },
@discourseComputed @discourseComputed
@ -105,192 +140,6 @@ export default ComposerEditor.extend({
return uploadIcon(false, this.siteSettings); return uploadIcon(false, this.siteSettings);
}, },
_setUploadPlaceholderSend() {
if (!this.composer.get("reply")) {
this.composer.set("reply", "");
}
this._super(...arguments);
},
_bindUploadTarget() {
this._super(...arguments);
const $element = $(this.element);
// adding dropZone property post initialization
$element.fileupload("option", "dropZone", $element);
$element.off("fileuploadsubmit");
$element.on("fileuploadsubmit", (e, data) => {
const max = this.siteSettings.simultaneous_uploads;
// Limit the number of simultaneous uploads
if (max > 0 && data.files.length > max) {
bootbox.alert(
WizardI18n("post.errors.too_many_dragged_and_dropped_files", { max })
);
return false;
}
// Look for a matching file upload handler contributed from a plugin
const matcher = (handler) => {
const ext = handler.extensions.join("|");
const regex = new RegExp(`\\.(${ext})$`, "i");
return regex.test(data.files[0].name);
};
const matchingHandler = uploadHandlers.find(matcher);
if (data.files.length === 1 && matchingHandler) {
if (!matchingHandler.method(data.files[0], this)) {
return false;
}
}
// If no plugin, continue as normal
const isPrivateMessage = this.get("composer.privateMessage");
data.formData = { type: "composer" };
data.formData.authenticity_token = getToken();
if (isPrivateMessage) {
data.formData.for_private_message = true;
}
if (this._pasted) {
data.formData.pasted = true;
}
const opts = {
user: this.currentUser,
siteSettings: this.siteSettings,
isPrivateMessage,
allowStaffToUploadAnyFileInPm: this.siteSettings
.allow_staff_to_upload_any_file_in_pm,
};
const isUploading = validateUploadedFiles(data.files, opts);
this.setProperties({ uploadProgress: 0, isUploading });
return isUploading;
});
$element.on("fileuploadprogressall", (e, data) => {
this.set(
"uploadProgress",
parseInt((data.loaded / data.total) * 100, 10)
);
});
$element.on("fileuploadfail", (e, data) => {
this._setUploadPlaceholderDone(data);
this._resetUpload(true);
const userCancelled = this._xhr && this._xhr._userCancelled;
this._xhr = null;
if (!userCancelled) {
displayErrorForUpload(data, this.siteSettings);
}
});
$element.on("fileuploadsend", (e, data) => {
this._pasted = false;
this._validUploads++;
this._setUploadPlaceholderSend(data);
this.appEvents.trigger("wizard-editor:insert-text", {
fieldId: this.field.id,
text: this.uploadPlaceholder,
});
if (data.xhr && data.originalFiles.length === 1) {
this.set("isCancellable", true);
this._xhr = data.xhr();
}
});
$element.on("fileuploaddone", (e, data) => {
let upload = data.result;
this._setUploadPlaceholderDone(data);
if (!this._xhr || !this._xhr._userCancelled) {
const markdown = uploadMarkdownResolvers.reduce(
(md, resolver) => resolver(upload) || md,
getUploadMarkdown(upload)
);
cacheShortUploadUrl(upload.short_url, upload);
this.appEvents.trigger("wizard-editor:replace-text", {
fieldId: this.field.id,
oldVal: this.uploadPlaceholder.trim(),
newVal: markdown,
});
this._resetUpload(false);
} else {
this._resetUpload(true);
}
});
},
_resetUpload(removePlaceholder) {
next(() => {
if (this._validUploads > 0) {
this._validUploads--;
}
if (this._validUploads === 0) {
this.setProperties({
uploadProgress: 0,
isUploading: false,
isCancellable: false,
});
}
if (removePlaceholder) {
this.appEvents.trigger("wizard-editor:replace-text", {
fieldId: this.field.id,
oldVal: this.uploadPlaceholder,
newVal: "",
});
}
this._resetUploadFilenamePlaceholder();
});
},
_registerImageScaleButtonClick($preview) {
const imageScaleRegex = /!\[(.*?)\|(\d{1,4}x\d{1,4})(,\s*\d{1,3}%)?(.*?)\]\((upload:\/\/.*?)\)(?!(.*`))/g;
$preview.off("click", ".scale-btn").on("click", ".scale-btn", (e) => {
const index = parseInt($(e.target).parent().attr("data-image-index"), 10);
const scale = e.target.attributes["data-scale"].value;
const matchingPlaceholder = this.get("composer.reply").match(
imageScaleRegex
);
if (matchingPlaceholder) {
const match = matchingPlaceholder[index];
if (match) {
const replacement = match.replace(
imageScaleRegex,
`![$1|$2, ${scale}%$4]($5)`
);
this.appEvents.trigger("wizard-editor:replace-text", {
fieldId: this.field.id,
oldVal: matchingPlaceholder[index],
newVal: replacement,
options: {
regex: imageScaleRegex,
index,
},
});
}
}
e.preventDefault();
return;
});
},
click(e) { click(e) {
if ($(e.target).hasClass("wizard-composer-hyperlink")) { if ($(e.target).hasClass("wizard-composer-hyperlink")) {
this.set("showHyperlinkBox", false); this.set("showHyperlinkBox", false);
@ -372,7 +221,8 @@ export default ComposerEditor.extend({
}, },
showUploadModal() { showUploadModal() {
$(this.element.querySelector(".wizard-composer-upload")).trigger("click"); this.session.set("uploadingFieldId", this.field.id);
document.getElementById(this.fileUploadElementId).click();
}, },
}, },
}); });

Datei anzeigen

@ -16,7 +16,7 @@ export default Ember.Component.extend({
"composer", "composer",
EmberObject.create({ EmberObject.create({
loading: false, loading: false,
reply: this.get("field.value"), reply: this.get("field.value") || "",
}) })
); );
}, },

Datei anzeigen

@ -111,8 +111,16 @@ export default {
model() {}, model() {},
}); });
$.ajaxPrefilter(function (_, __, jqXHR) { // Add a CSRF token to all AJAX requests
jqXHR.setRequestHeader("X-CSRF-Token", getToken()); let token = getToken();
session.set("csrfToken", token);
let callbacks = $.Callbacks();
$.ajaxPrefilter(callbacks.fire);
callbacks.add(function (options, originalOptions, xhr) {
if (!options.crossDomain) {
xhr.setRequestHeader("X-CSRF-Token", session.get("csrfToken"));
}
}); });
}, },
}; };

Datei anzeigen

@ -16,24 +16,10 @@
disabled=disableTextarea disabled=disableTextarea
outletArgs=(hash composer=composer editorType="composer")}} outletArgs=(hash composer=composer editorType="composer")}}
{{input <input
class="wizard-composer-upload hidden-upload-field"
disabled=isUploading
type="file" type="file"
accept=allowedFileTypes id={{fileUploadElementId}}
multiple=true}} class="wizard-composer-upload"
accept={{allowedFileTypes}}
{{#if showHyperlinkBox}} multiple
{{wizard-composer-hyperlink >
addLink=(action "addLink")
hideBox=(action "hideBox")}}
{{/if}}
{{#if isUploading}}
<div id="file-uploading">
{{loading-spinner size="small"}}<span>{{wizard-i18n "upload_selector.uploading"}} {{uploadProgress}}%</span>
{{#if isCancellable}}
<a href id="cancel-file-upload" {{action "cancelUpload"}}>{{d-icon "times"}}</a>
{{/if}}
</div>
{{/if}}

Datei anzeigen

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
# name: discourse-custom-wizard # name: discourse-custom-wizard
# about: Create custom wizards # about: Create custom wizards
# version: 1.15.4 # version: 1.15.5
# authors: Angus McLeod # authors: Angus McLeod
# url: https://github.com/paviliondev/discourse-custom-wizard # url: https://github.com/paviliondev/discourse-custom-wizard
# contact emails: angus@thepavilion.io # contact emails: angus@thepavilion.io