1
0
mirror of https://github.com/flarum/core.git synced 2025-08-04 15:37:51 +02:00

chore(mentions,emoji): tie autocomplete to editor instance (#3913)

This commit is contained in:
Sami Mazouz
2023-11-10 22:44:00 +01:00
committed by GitHub
parent 5e3f8db095
commit 208b94dc12
2 changed files with 44 additions and 47 deletions

View File

@@ -7,8 +7,6 @@ import getEmojiIconCode from './helpers/getEmojiIconCode';
import cdn from './cdn'; import cdn from './cdn';
export default function addComposerAutocomplete() { export default function addComposerAutocomplete() {
const $container = $('<div class="ComposerBody-emojiDropdownContainer"></div>');
const dropdown = new AutocompleteDropdown();
let emojiMap = null; let emojiMap = null;
extend('flarum/common/components/TextEditor', 'oninit', function () { extend('flarum/common/components/TextEditor', 'oninit', function () {
@@ -16,18 +14,19 @@ export default function addComposerAutocomplete() {
}); });
extend('flarum/common/components/TextEditor', 'onbuild', function () { extend('flarum/common/components/TextEditor', 'onbuild', function () {
this.emojiDropdown = new AutocompleteDropdown();
const $editor = this.$('.TextEditor-editor').wrap('<div class="ComposerBody-emojiWrapper"></div>'); const $editor = this.$('.TextEditor-editor').wrap('<div class="ComposerBody-emojiWrapper"></div>');
this.navigator = new KeyboardNavigatable(); this.navigator = new KeyboardNavigatable();
this.navigator this.navigator
.when(() => dropdown.active) .when(() => this.emojiDropdown.active)
.onUp(() => dropdown.navigate(-1)) .onUp(() => this.emojiDropdown.navigate(-1))
.onDown(() => dropdown.navigate(1)) .onDown(() => this.emojiDropdown.navigate(1))
.onSelect(dropdown.complete.bind(dropdown)) .onSelect(this.emojiDropdown.complete.bind(this.emojiDropdown))
.onCancel(dropdown.hide.bind(dropdown)) .onCancel(this.emojiDropdown.hide.bind(this.emojiDropdown))
.bindTo($editor); .bindTo($editor);
$editor.after($container); $editor.after($('<div class="ComposerBody-emojiDropdownContainer"></div>'));
}); });
extend('flarum/common/components/TextEditor', 'buildEditorParams', function (params) { extend('flarum/common/components/TextEditor', 'buildEditorParams', function (params) {
@@ -40,7 +39,7 @@ export default function addComposerAutocomplete() {
const applySuggestion = (replacement) => { const applySuggestion = (replacement) => {
this.attrs.composer.editor.replaceBeforeCursor(absEmojiStart - 1, replacement + ' '); this.attrs.composer.editor.replaceBeforeCursor(absEmojiStart - 1, replacement + ' ');
dropdown.hide(); this.emojiDropdown.hide();
}; };
params.inputListeners.push(() => { params.inputListeners.push(() => {
@@ -68,8 +67,8 @@ export default function addComposerAutocomplete() {
} }
} }
dropdown.hide(); this.emojiDropdown.hide();
dropdown.active = false; this.emojiDropdown.active = false;
if (absEmojiStart) { if (absEmojiStart) {
typed = lastChunk.substring(relEmojiStart).toLowerCase(); typed = lastChunk.substring(relEmojiStart).toLowerCase();
@@ -80,7 +79,7 @@ export default function addComposerAutocomplete() {
key={emoji} key={emoji}
onclick={() => applySuggestion(emoji)} onclick={() => applySuggestion(emoji)}
onmouseenter={function () { onmouseenter={function () {
dropdown.setIndex($(this).parent().index() - 1); this.emojiDropdown.setIndex($(this).parent().index() - 1);
}} }}
> >
<img alt={emoji} className="emoji" draggable="false" loading="lazy" src={`${cdn}72x72/${code}.png`} /> <img alt={emoji} className="emoji" draggable="false" loading="lazy" src={`${cdn}72x72/${code}.png`} />
@@ -133,14 +132,14 @@ export default function addComposerAutocomplete() {
.map(makeSuggestion); .map(makeSuggestion);
if (suggestions.length) { if (suggestions.length) {
dropdown.items = suggestions; this.emojiDropdown.items = suggestions;
m.render($container[0], dropdown.render()); m.render(this.$('.ComposerBody-emojiDropdownContainer')[0], this.emojiDropdown.render());
dropdown.show(); this.emojiDropdown.show();
const coordinates = this.attrs.composer.editor.getCaretCoordinates(absEmojiStart); const coordinates = this.attrs.composer.editor.getCaretCoordinates(absEmojiStart);
const width = dropdown.$().outerWidth(); const width = this.emojiDropdown.$().outerWidth();
const height = dropdown.$().outerHeight(); const height = this.emojiDropdown.$().outerHeight();
const parent = dropdown.$().offsetParent(); const parent = this.emojiDropdown.$().offsetParent();
let left = coordinates.left; let left = coordinates.left;
let top = coordinates.top + 15; let top = coordinates.top + 15;
@@ -156,15 +155,15 @@ export default function addComposerAutocomplete() {
top = Math.max(-(parent.offset().top - $(document).scrollTop()), top); top = Math.max(-(parent.offset().top - $(document).scrollTop()), top);
left = Math.max(-parent.offset().left, left); left = Math.max(-parent.offset().left, left);
dropdown.show(left, top); this.emojiDropdown.show(left, top);
} }
}; };
buildSuggestions(); buildSuggestions();
dropdown.setIndex(0); this.emojiDropdown.setIndex(0);
dropdown.$().scrollTop(0); this.emojiDropdown.$().scrollTop(0);
dropdown.active = true; this.emojiDropdown.active = true;
} }
}); });
}); });

View File

@@ -7,22 +7,20 @@ import AutocompleteDropdown from './fragments/AutocompleteDropdown';
import MentionableModels from './mentionables/MentionableModels'; import MentionableModels from './mentionables/MentionableModels';
export default function addComposerAutocomplete() { export default function addComposerAutocomplete() {
const $container = $('<div class="ComposerBody-mentionsDropdownContainer"></div>');
const dropdown = new AutocompleteDropdown();
extend('flarum/common/components/TextEditor', 'onbuild', function () { extend('flarum/common/components/TextEditor', 'onbuild', function () {
this.mentionsDropdown = new AutocompleteDropdown();
const $editor = this.$('.TextEditor-editor').wrap('<div class="ComposerBody-mentionsWrapper"></div>'); const $editor = this.$('.TextEditor-editor').wrap('<div class="ComposerBody-mentionsWrapper"></div>');
this.navigator = new KeyboardNavigatable(); this.navigator = new KeyboardNavigatable();
this.navigator this.navigator
.when(() => dropdown.active) .when(() => this.mentionsDropdown.active)
.onUp(() => dropdown.navigate(-1)) .onUp(() => this.mentionsDropdown.navigate(-1))
.onDown(() => dropdown.navigate(1)) .onDown(() => this.mentionsDropdown.navigate(1))
.onSelect(dropdown.complete.bind(dropdown)) .onSelect(this.mentionsDropdown.complete.bind(this.mentionsDropdown))
.onCancel(dropdown.hide.bind(dropdown)) .onCancel(this.mentionsDropdown.hide.bind(this.mentionsDropdown))
.bindTo($editor); .bindTo($editor);
$editor.after($container); $editor.after($('<div class="ComposerBody-mentionsDropdownContainer"></div>'));
}); });
extend('flarum/common/components/TextEditor', 'buildEditorParams', function (params) { extend('flarum/common/components/TextEditor', 'buildEditorParams', function (params) {
@@ -32,12 +30,12 @@ export default function addComposerAutocomplete() {
let mentionables = new MentionableModels({ let mentionables = new MentionableModels({
onmouseenter: function () { onmouseenter: function () {
dropdown.setIndex($(this).parent().index()); this.mentionsDropdown.setIndex($(this).parent().index());
}, },
onclick: (replacement) => { onclick: (replacement) => {
this.attrs.composer.editor.replaceBeforeCursor(absMentionStart - 1, replacement + ' '); this.attrs.composer.editor.replaceBeforeCursor(absMentionStart - 1, replacement + ' ');
dropdown.hide(); this.mentionsDropdown.hide();
}, },
}); });
@@ -66,8 +64,8 @@ export default function addComposerAutocomplete() {
} }
} }
dropdown.hide(); this.mentionsDropdown.hide();
dropdown.active = false; this.mentionsDropdown.active = false;
if (absMentionStart) { if (absMentionStart) {
const typed = lastChunk.substring(relMentionStart).toLowerCase(); const typed = lastChunk.substring(relMentionStart).toLowerCase();
@@ -83,14 +81,14 @@ export default function addComposerAutocomplete() {
const suggestions = mentionables.buildSuggestions(); const suggestions = mentionables.buildSuggestions();
if (suggestions.length) { if (suggestions.length) {
dropdown.items = suggestions; this.mentionsDropdown.items = suggestions;
m.render($container[0], dropdown.render()); m.render(this.$('.ComposerBody-mentionsDropdownContainer')[0], this.mentionsDropdown.render());
dropdown.show(); this.mentionsDropdown.show();
const coordinates = this.attrs.composer.editor.getCaretCoordinates(absMentionStart); const coordinates = this.attrs.composer.editor.getCaretCoordinates(absMentionStart);
const width = dropdown.$().outerWidth(); const width = this.mentionsDropdown.$().outerWidth();
const height = dropdown.$().outerHeight(); const height = this.mentionsDropdown.$().outerHeight();
const parent = dropdown.$().offsetParent(); const parent = this.mentionsDropdown.$().offsetParent();
let left = coordinates.left; let left = coordinates.left;
let top = coordinates.top + 15; let top = coordinates.top + 15;
@@ -106,19 +104,19 @@ export default function addComposerAutocomplete() {
top = Math.max(-(parent.offset().top - $(document).scrollTop()), top); top = Math.max(-(parent.offset().top - $(document).scrollTop()), top);
left = Math.max(-parent.offset().left, left); left = Math.max(-parent.offset().left, left);
dropdown.show(left, top); this.mentionsDropdown.show(left, top);
} else { } else {
dropdown.active = false; this.mentionsDropdown.active = false;
dropdown.hide(); this.mentionsDropdown.hide();
} }
}; };
dropdown.active = true; this.mentionsDropdown.active = true;
buildSuggestions(); buildSuggestions();
dropdown.setIndex(0); this.mentionsDropdown.setIndex(0);
dropdown.$().scrollTop(0); this.mentionsDropdown.$().scrollTop(0);
mentionables.search()?.then(buildSuggestions); mentionables.search()?.then(buildSuggestions);
} }