Converse.js: [autocomplete] prioritize the user for which the nickname STARTS with the text typed

Created on 16 Sep 2020  路  14Comments  路  Source: conversejs/converse.js

Describe the bug
If you start typing the at-character ("@") followed by letters, the Converse UI will automatically try to auto-complete with the nickname of an occupant of the room.
For example, when I type "@ ber" I get this:

converse-bug

One thing that would be an improvement, is if Converse would prioritize the user for which the nickname STARTS with the text that I typed
You see in the example above that both Bernard's name as well as Viktor's match
If I would have pressed 'tab' after typing "@ ber" then it would have auto-completed with Viktor's name, instead of Bernard's
I think 99% of the times, a user intends to select the user who's nickname _starts_ with whatever is typed.

To Reproduce
type a text starting with "@"

Expected behavior
prioritize the user for which the nickname STARTS with the text that is typed

Environment (please complete the following information):

  • Desktop
  • Browser [Chrome]
  • Converse.js version [6.0.1]

All 14 comments

@Zash noted that the autocomplete behavior can be controlled with the muc_mention_autocomplete_filter configuration option. The default for this is contains but starts_with can also be used.

However, it would be preferable to prioritize nicknames that start with the provided input, when the contains option is used. That currently is not the case.

By analyzing the code, here are the different filters available:

https://github.com/conversejs/converse.js/blob/522e7706c17786e330a46e72335419839478be32/src/converse-autocomplete.js#L15-L22

What do you think of a solution that adds a third filter, "starts_or_contains" ?

What do you think of a solution that adds a third filter, "starts_or_contains" ?

I do not think that's the right approach. starts_or_contains would have the same results (something that 'starts' with a particular substring also 'contains' that substring).

Instead, I think you should modify the order of results that are returned with FILTER_CONTAINS.

The AutoComplete class has a sort configuration attribute (see here) and sorts with a function called SORT_BY_LENGTH.

You'll need to update AutoComplete to accept a function for the sort config parameter (and not just a boolean as currently), and then you need to update the MUC code that uses AutoComplete to pass in your own sort function that sorts according to whether the matches start with the string or not.

The sort function only takes two parameters, the current and the next element, but I'm supposed to reorganize the results according to the text typed by the user.

An idea on how I can have the text typed in a sort function without changing the signature of the function so that it remains compatible ?

The things being compared here are instances of the Suggestion class.

That class already has a value attribute which is the suggested match. What's still needed is the query string (the string being auto-completed). If you have that, then you have all the information necessary.

I've made a change to do that here: https://github.com/conversejs/converse.js/commit/a72ad8a53d5ac36821f700ed811d962545ddcd6f

So now you have the text typed by the user as the query attribute on the Suggestion instance.

Here is what I鈥檝e done #2234, it works as expected on my machine but it seems to break some unit tests, how can I fix that ?

You'll have to identify the failing tests and then run them individually to figure out why they're failing and then fix the tests or the underlying issue in the code.

I've written some documentation on how to run the tests:

https://github.com/conversejs/converse.js/blob/master/docs/source/testing.rst

tell me if I'm wrong, the auto-completion for contacts uses the "contains" filter but it looks like the results are not sorted,
what made the test can not pass, I saw the contact list available in the mock :

https://github.com/conversejs/converse.js/blob/fff9eeaa5c77ebf9d3e7508499deb09837802457/spec/mock.js#L541-L557

Tybalt, comes before Balthasar.

how do I activate the filter, when it comes to contacts?
my little change fixes the test but not totally, I can't activate the sorting function I created.

Can you please rephrase your question? We've disucced it in the chatroom, but couldn't understand what you're trying to say.

is it the same Autocomplete class located in the src/converse-autocomplete.js file that makes the following two examples work ?

au-completion in a chatroom
chatroom

au-completion for contact
Sans titre (1)

@bernard-ng Yes, AFAIK they both use the <converse-autocomplete> component, and that component makes a new instance of AutoComplete every time it's created.

See here: https://github.com/conversejs/converse.js/blob/e82d6785c2cc24d347c2044560d428a33a1ac6f6/src/components/autocomplete.js#L50

alright in this case I don't have anything more to do on my side, is there anything to modify before merging ?

Like I suggested in https://github.com/conversejs/converse.js/pull/2234#issuecomment-694847763 please remove all of the unneeded commits that are in the PR, to clean things up.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fabiomontefuscolo picture fabiomontefuscolo  路  4Comments

ge0rg picture ge0rg  路  7Comments

cesarplata picture cesarplata  路  6Comments

bessiejiang picture bessiejiang  路  3Comments

irfancnk picture irfancnk  路  6Comments