nodebb-plugin-composer-quill icon indicating copy to clipboard operation
nodebb-plugin-composer-quill copied to clipboard

BUG: @textcomplete dropdown mentions and emojis not working on mouse click

Open cisnerosebastian opened this issue 3 years ago • 8 comments

Since nodebb update 2.6.1 (it has updates on composer default and new @textcomplete plugin) mentions and emjis dropdown item on click not working. Its working just fine if selected with keyboard and "enter" key. Its working perfect on composer default, but not on quill composer. When you click with mouse button, the composer content area scrolls up, and no autofill is done.

image

I've installed a clean new nodebb 2.6.1 , quill 3.0.2 and its not working also updated nodebb to 2.7.0 and still not working then unistalled quill, and used composer default, and its working just fine

I'm not 100% sure where to report this bug, as it can be on nodebb update, or composer-quill, or composerdefault, or maybe in the @textcomplete plugin. Let me know if I have to report this in another repo.

Thanks.

cisnerosebastian avatar Dec 20 '22 14:12 cisnerosebastian

Looks bugged, I also get this error in the browser console sometimes

Uncaught Error: Unexpected
    at ContenteditableEditor.getRange (ContenteditableEditor.js:113:19)
    at ContenteditableEditor.getRange (ContenteditableEditor.js:117:28)
    at ContenteditableEditor.getBeforeCursor (ContenteditableEditor.js:86:28)
    at ContenteditableEditor.emitChangeEvent (Editor.js:71:36)
    at ContenteditableEditor.onInput (ContenteditableEditor.js:11:18)

barisusakli avatar Dec 20 '22 15:12 barisusakli

Hi there @barisusakli ! I was wondering if there has been a fix to this issue yet. My users keep drawing my attention to it and I'm hoping to address the problem asap. Thank you very much!

Incryve avatar Feb 22 '23 12:02 Incryve

@Incryve nope, I tried to fix this but couldn't figure out the issue. Seems like textcomplete and quill don't play nice together. Selecting a option from the dropdown in textcomplete doesn't add the selected text into the quill composer.

barisusakli avatar Feb 22 '23 15:02 barisusakli

@barisusakli I may have some time to check on this issue. If you have any idea where the problem may be let me know.

cisnerosebastian avatar Mar 03 '23 13:03 cisnerosebastian

Some of the related code is here https://github.com/NodeBB/nodebb-plugin-composer-quill/blob/master/static/lib/quill-nbb.js#L338-L367, it works when you press enter but mouse clicks on the dropdown doesn't work. The autocomplete module is actually in composer-default here https://github.com/NodeBB/nodebb-plugin-composer-default/blob/master/static/lib/composer/autocomplete.js#L17-L65

barisusakli avatar Mar 03 '23 14:03 barisusakli

@barisusakli I've been trying to understand how this works. Its like quill is intercepting keyboard and mouse events to update the quill contents and cursor. So, in this code

https://github.com/NodeBB/nodebb-plugin-composer-quill/blob/master/static/lib/quill-nbb.js#L362-L367

what is doing is like adding the tab and enter key events on the top of the list of quill events

maybe something similar is what we have to achieve with the mouse events?

On another hand, I can see that the textcomplete is actually getting the click event , and returning the right value, but that content is not been added on the quill contents.

Anyway, I will try to spend more time on this next week.

cisnerosebastian avatar Mar 07 '23 17:03 cisnerosebastian

Yeah that's what I found out too, when you click something in the dropdown that text doesn't get inserted into the quill editor.

barisusakli avatar Mar 07 '23 17:03 barisusakli

Hi, it is me again. I'm still trying to fix this. So, I've made some progress, but still not 100% there yet.

This seeems more like missing functionallity than a bug.

in the default composer autocomplete.js there is a

data.element.on('textComplete:select', function () {
			preview.render(postContainer);
		});

im thinking this is the code that should print the mentions after select, but it doesn't. This is not the right event string, and preview.render does nothing on nodebb quilll plugin.

So, what I did is captured the right event, and triggered my own custom event to get the replacement done

textcomplete.on('selected', function (ev) {
			var data = ev.detail.searchResult.data;
			if (typeof data === 'string') {
				console.log('ev', ev);
				var quillElem = $(editor.el).parent();
				var quill = $(quillElem[0]).data('quill')
				var payload = {
					quill: quill,
					context: 'mentions',
					original: ev.detail.searchResult.term,
					fullreplace: slugigyFullMention(data),
				};
				$(window).trigger('action:composer.textcompleteReplace', payload);
			}
		});
		
		function slugigyFullMention(mention) {
			// Strip (fullname) part from mentions
			mention = mention.replace(/ \(.+\)/, '');
			mention = $('<div/>').html(mention);
			// Strip letter avatar
			mention.find('span').remove();
			let ret = '@' + slugify(mention.text(), true) + ' ';
			return ret;
		}

then on quill nodebb im trying to do the replacement, but im failing there, as I cant get the right cursor placement to replace the words. I tryied to do a full replacement in the qhole text of the quill contents, but that also not working

$(window).on('action:composer.textcompleteReplace', (evt, data) => {
		const quill = data.quill;
		const fullText = quill.getText(); // Obtenemos todo el texto del editor
		const searchText = '@' + data.original; // Texto que queremos encontrar y reemplazar

		// Función para encontrar la primera posición válida del searchText como palabra completa
		function findWholeWord(text, search) {
			let index = text.indexOf(search);
			while (index !== -1) {
				const charBefore = index > 0 ? text[index - 1] : ' ';
				const charAfter = text[index + search.length] || ' ';
				// Comprobamos si ambos caracteres antes y después no son parte de una palabra
				if (!charBefore.match(/\w/) && !charAfter.match(/\w/)) {
					return index; // Si ambos caracteres no son alfanuméricos, es una palabra completa
				}
				// Si no, sigue buscando más adelante en el texto
				index = text.indexOf(search, index + 1);
			}
			return -1;
		}

		// Buscamos la primera ocurrencia de searchText como palabra completa en el contenido completo
		const startIndex = findWholeWord(fullText, searchText);

		if (startIndex !== -1) { // Verificamos si encontramos el texto
			const endIndex = startIndex + searchText.length;
			quill.deleteText(startIndex, searchText.length); // Borramos el texto antiguo
			quill.insertText(startIndex, data.fullreplace); // Insertamos el nuevo texto
		} else {
			console.log('Texto no encontrado para reemplazar');
		}

	});

I think I'm close, but not there yet.

maybe If I know how to do this replace properly ... not sure where the code of this replacement is on composer or quills code. I'm trying to see how you calculate the position of the old word to be replaced to then remove it and wirte the new word in its place.

any thgouhts?

cisnerosebastian avatar Jun 13 '24 15:06 cisnerosebastian