0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-11-21 17:00:29 +01:00

COMPATIBILITY: Convert composer editor to modern ember component

Dieser Commit ist enthalten in:
Angus McLeod 2024-10-11 12:48:10 +02:00
Ursprung 87b19ec364
Commit 5eec15160c
4 geänderte Dateien mit 134 neuen und 242 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,97 @@
import ComposerEditor from "discourse/components/composer-editor";
import discourseComputed, { bind } from "discourse-common/utils/decorators";
import { alias } from "@ember/object/computed";
import { uploadIcon } from "discourse/lib/uploads";
import { dasherize } from "@ember/string";
import InsertHyperlink from "discourse/components/modal/insert-hyperlink";
import { inject as service } from "@ember/service";
import { action } from "@ember/object";
export const wizardComposerEdtiorEventPrefix = "wizard-editor";
export default class CustomWizardComposerEditor extends ComposerEditor {
@service modal;
allowUpload = true;
showLink = false;
topic = null;
showToolbar = true;
focusTarget = "reply";
canWhisper = false;
lastValidatedAt = "lastValidatedAt";
popupMenuOptions = [];
draftStatus = "null";
@alias("topicList.loadingMore") loadingMore;
wizardEventFieldId = null;
composerEventPrefix = wizardComposerEdtiorEventPrefix;
init() {
super.init(...arguments);
this.fileUploadElementId = `file-uploader-${dasherize(this.field.id)}`;
this.editorInputClass = `.${dasherize(this.field.type)}-${dasherize(
this.field.id
)} .d-editor-input`;
}
@discourseComputed
allowedFileTypes() {
return this.siteSettings.authorized_extensions
.split("|")
.map((ext) => "." + ext)
.join(",");
}
@discourseComputed()
uploadIcon() {
return uploadIcon(false, this.siteSettings);
}
@bind
_handleImageDeleteButtonClick() {
this.session.set("wizardEventFieldId", this.field.id);
super._handleImageDeleteButtonClick(...arguments);
}
@action
extraButtons(toolbar) {
const component = this;
if (this.allowUpload && this.uploadIcon) {
toolbar.addButton({
id: "upload",
group: "insertions",
icon: this.uploadIcon,
title: "upload",
sendAction: (event) => component.send("showUploadModal", event),
});
}
toolbar.addButton({
id: "link",
icon: "link",
group: "insertions",
shortcut: "K",
trimLeading: true,
unshift: true,
sendAction: (event) => component.send("showLinkModal", event),
});
}
@action
showLinkModal(toolbarEvent) {
let linkText = "";
this._lastSel = toolbarEvent.selected;
if (this._lastSel) {
linkText = this._lastSel.value;
}
this.modal.show(InsertHyperlink, {
model: { linkText, toolbarEvent },
});
}
@action
showUploadModal() {
this.session.set("wizardEventFieldId", this.field.id);
document.getElementById(this.fileUploadElementId).click();
}
}

Datei anzeigen

@ -1,205 +0,0 @@
import ComposerEditor from "discourse/components/composer-editor";
import {
bind,
default as discourseComputed,
on,
} from "discourse-common/utils/decorators";
import { findRawTemplate } from "discourse-common/lib/raw-templates";
import { scheduleOnce } from "@ember/runloop";
import { caretPosition, inCodeBlock } from "discourse/lib/utilities";
import highlightSyntax from "discourse/lib/highlight-syntax";
import { alias } from "@ember/object/computed";
import Site from "discourse/models/site";
import { uploadIcon } from "discourse/lib/uploads";
import { dasherize } from "@ember/string";
import InsertHyperlink from "discourse/components/modal/insert-hyperlink";
import { inject as service } from "@ember/service";
import { action } from "@ember/object";
const IMAGE_MARKDOWN_REGEX =
/!\[(.*?)\|(\d{1,4}x\d{1,4})(,\s*\d{1,3}%)?(.*?)\]\((upload:\/\/.*?)\)(?!(.*`))/g;
export const wizardComposerEdtiorEventPrefix = "wizard-editor";
export default ComposerEditor.extend({
modal: service(),
classNameBindings: ["fieldClass"],
allowUpload: true,
showLink: false,
topic: null,
showToolbar: true,
focusTarget: "reply",
canWhisper: false,
lastValidatedAt: "lastValidatedAt",
popupMenuOptions: [],
draftStatus: "null",
replyPlaceholder: alias("field.translatedPlaceholder"),
wizardEventFieldId: null,
@on("didInsertElement")
_composerEditorInit() {
this._super(...arguments);
this.composerEventPrefix = wizardComposerEdtiorEventPrefix;
if (this.siteSettings.mentionables_enabled) {
const $input = $(this.element.querySelector(".d-editor-input"));
Site.currentProp("mentionable_items", this.wizard.mentionable_items);
const { SEPARATOR } = requirejs(
"discourse/plugins/discourse-mentionables/discourse/lib/discourse-markdown/mentionable-items"
);
const { searchMentionableItem } = requirejs(
"discourse/plugins/discourse-mentionables/discourse/lib/mentionable-item-search"
);
$input.autocomplete({
template: findRawTemplate("javascripts/mentionable-item-autocomplete"),
key: SEPARATOR,
afterComplete: (value) => {
this.composer.set("reply", value);
scheduleOnce("afterRender", () => $input.blur().focus());
},
transformComplete: (item) => item.model.slug,
dataSource: (term) =>
term.match(/\s/)
? null
: searchMentionableItem(term, this.siteSettings),
triggerRule: (textarea) =>
!inCodeBlock(textarea.value, caretPosition(textarea)),
});
}
const field = this.field;
this.editorInputClass = `.${dasherize(field.type)}-${dasherize(
field.id
)} .d-editor-input`;
this._uppyInstance.on("file-added", () => {
this.session.set("wizardEventFieldId", field.id);
});
},
@discourseComputed("field.id")
fileUploadElementId(fieldId) {
return `file-uploader-${dasherize(fieldId)}`;
},
@discourseComputed
allowedFileTypes() {
return this.siteSettings.authorized_extensions
.split("|")
.map((ext) => "." + ext)
.join(",");
},
@discourseComputed()
uploadIcon() {
return uploadIcon(false, this.siteSettings);
},
@bind
_handleImageDeleteButtonClick(event) {
if (!event.target.classList.contains("delete-image-button")) {
return;
}
const index = parseInt(
event.target.closest(".button-wrapper").dataset.imageIndex,
10
);
const matchingPlaceholder =
this.get("composer.reply").match(IMAGE_MARKDOWN_REGEX);
this.session.set("wizardEventFieldId", this.field.id);
this.appEvents.trigger(
"composer:replace-text",
matchingPlaceholder[index],
"",
{ regex: IMAGE_MARKDOWN_REGEX, index }
);
},
@action
extraButtons(toolbar) {
const component = this;
if (this.allowUpload && this.uploadIcon) {
toolbar.addButton({
id: "upload",
group: "insertions",
icon: this.uploadIcon,
title: "upload",
sendAction: (event) => component.send("showUploadModal", event),
});
}
toolbar.addButton({
id: "link",
icon: "link",
group: "insertions",
shortcut: "K",
trimLeading: true,
unshift: true,
sendAction: (event) => component.send("showLinkModal", event),
});
if (this.siteSettings.mentionables_enabled) {
const { SEPARATOR } = requirejs(
"discourse/plugins/discourse-mentionables/discourse/lib/discourse-markdown/mentionable-items"
);
toolbar.addButton({
id: "insert-mentionable",
group: "extras",
icon: this.siteSettings.mentionables_composer_button_icon,
title: "mentionables.composer.insert.title",
perform: () => {
this.appEvents.trigger("wizard-editor:insert-text", {
fieldId: this.field.id,
text: SEPARATOR,
});
const $textarea = $(
document.querySelector(
`.composer-field.${this.field.id} textarea.d-editor-input`
)
);
$textarea.trigger("keyup.autocomplete");
},
});
}
},
@action
previewUpdated(preview) {
highlightSyntax(preview, this.siteSettings, this.session);
if (this.siteSettings.mentionables_enabled) {
const { linkSeenMentionableItems } = requirejs(
"discourse/plugins/discourse-mentionables/discourse/lib/mentionable-items-preview-styling"
);
linkSeenMentionableItems(preview, this.siteSettings);
}
this._super(...arguments);
},
@action
showLinkModal(toolbarEvent) {
let linkText = "";
this._lastSel = toolbarEvent.selected;
if (this._lastSel) {
linkText = this._lastSel.value;
}
this.modal.show(InsertHyperlink, {
model: { linkText, toolbarEvent },
});
},
@action
showUploadModal() {
this.session.set("wizardEventFieldId", this.field.id);
document.getElementById(this.fileUploadElementId).click();
},
});

Datei anzeigen

@ -1,26 +1,28 @@
<DEditor
@tabindex={{field.tabindex}}
@value={{composer.reply}}
@placeholderOverride={{replyPlaceholder}}
@previewUpdated={{this.previewUpdated}}
@markdownOptions={{markdownOptions}}
@extraButtons={{this.extraButtons}}
@importQuote={{this.importQuote}}
@showUploadModal={{this.showUploadModal}}
@togglePreview={{this.togglePreview}}
@validation={{validation}}
@loading={{composer.loading}}
@showLink={{showLink}}
@wizardComposer={{true}}
@fieldId={{field.id}}
@disabled={{disableTextarea}}
@outletArgs={{hash composer=composer editorType="composer"}}
/>
<div class={{this.fieldClass}}>
<DEditor
@tabindex={{field.tabindex}}
@value={{composer.reply}}
@placeholderOverride={{replyPlaceholder}}
@previewUpdated={{this.previewUpdated}}
@markdownOptions={{markdownOptions}}
@extraButtons={{this.extraButtons}}
@importQuote={{this.importQuote}}
@showUploadModal={{this.showUploadModal}}
@togglePreview={{this.togglePreview}}
@validation={{validation}}
@loading={{composer.loading}}
@showLink={{showLink}}
@wizardComposer={{true}}
@fieldId={{field.id}}
@disabled={{disableTextarea}}
@outletArgs={{hash composer=composer editorType="composer"}}
/>
<input
type="file"
id={{fileUploadElementId}}
class="wizard-composer-upload"
accept={{allowedFileTypes}}
multiple
/>
<input
type="file"
id={{this.fileUploadElementId}}
class="wizard-composer-upload"
accept={{this.allowedFileTypes}}
multiple
/>
</div>

Datei anzeigen

@ -1,8 +1,8 @@
<CustomWizardComposerEditor
@field={{field}}
@composer={{composer}}
@wizard={{wizard}}
@fieldClass={{fieldClass}}
@field={{this.field}}
@composer={{this.composer}}
@wizard={{this.wizard}}
@fieldClass={{this.fieldClass}}
@groupsMentioned={{this.groupsMentioned}}
@cannotSeeMention={{this.cannotSeeMention}}
@importQuote={{this.importQuote}}
@ -11,15 +11,13 @@
/>
<div class="bottom-bar">
<button
<DButton
@action={{this.togglePreview}}
class="wizard-btn toggle-preview"
{{action "togglePreview"}}
type="button"
>
<span class="d-button-label">{{i18n togglePreviewLabel}}</span>
</button>
@label={{togglePreviewLabel}}
/>
{{#if field.char_counter}}
{{wizard-char-counter field.value field.max_length}}
{{#if this.field.char_counter}}
{{wizard-char-counter this.field.value field.max_length}}
{{/if}}
</div>