Fix #2231 add sort by query (#2234)

Use of lowercase letters and Infinity to avoid calculation errors when the index is -1
This commit is contained in:
bernard ng 2020-10-01 12:06:35 +02:00 committed by GitHub
parent e761923cc9
commit efd4e50378
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 2 deletions

View File

@ -6,6 +6,7 @@
configuration settings should now be accessed via `_converse.api.settings.get` and not directly on the `_converse` object.
Soon we'll deprecate the latter, so prepare now.
- #2231: add sort_by_query and remove sort_by_length
- #1313: Stylistic improvements to the send button
- #1481: MUC OMEMO: Error No record for device
- #1490: Busy-loop when fetching registration form fails

View File

@ -60,6 +60,53 @@ describe("The nickname autocomplete feature", function () {
done();
}));
it("should order by query index position and length", mock.initConverse(
['rosterGroupsFetched', 'chatBoxesFetched'], {}, async function (done, _converse) {
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'tom');
const view = _converse.chatboxviews.get('lounge@montague.lit');
// Nicknames from presences
['bernard', 'naber', 'helberlo', 'john', 'jones'].forEach((nick) => {
_converse.connection._dataRecv(mock.createRequest(
$pres({
'to': 'tom@montague.lit/resource',
'from': `lounge@montague.lit/${nick}`
})
.c('x', { xmlns: Strophe.NS.MUC_USER })
.c('item', {
'affiliation': 'none',
'jid': `${nick}@montague.lit/resource`,
'role': 'participant'
})));
});
const textarea = view.el.querySelector('textarea.chat-textarea');
const at_event = {
'target': textarea,
'preventDefault': function preventDefault() { },
'stopPropagation': function stopPropagation() { },
'keyCode': 50,
'key': '@'
};
// Test that results are sorted by query index
view.onKeyDown(at_event);
textarea.value = '@ber';
view.onKeyUp(at_event);
await u.waitUntil(() => view.el.querySelectorAll('.suggestion-box__results li').length === 3);
expect(view.el.querySelector('.suggestion-box__results li:first-child').textContent).toBe('bernard');
expect(view.el.querySelector('.suggestion-box__results li:nth-child(2)').textContent).toBe('naber');
expect(view.el.querySelector('.suggestion-box__results li:nth-child(3)').textContent).toBe('helberlo');
// Test that when the query index is equal, results should be sorted by length
textarea.value = '@jo';
view.onKeyUp(at_event);
await u.waitUntil(() => view.el.querySelectorAll('.suggestion-box__results li').length === 2);
expect(view.el.querySelector('.suggestion-box__results li:first-child').textContent).toBe('john');
expect(view.el.querySelector('.suggestion-box__results li:nth-child(2)').textContent).toBe('jones');
done();
}));
it("autocompletes when the user presses tab",
mock.initConverse(
['rosterGroupsFetched', 'chatBoxesFetched'], {},

View File

@ -22,13 +22,24 @@ export const FILTER_STARTSWITH = function (text, input) {
};
const SORT_BYLENGTH = function (a, b) {
const SORT_BY_LENGTH = function (a, b) {
if (a.length !== b.length) {
return a.length - b.length;
}
return a < b? -1 : 1;
};
const SORT_BY_QUERY_POSITION = function (a, b) {
const query = a.query.toLowerCase();
const x = a.label.toLowerCase().indexOf(query);
const y = b.label.toLowerCase().indexOf(query);
if (x === y) {
return SORT_BY_LENGTH(a, b);
}
return (x === -1 ? Infinity : x) < (y === -1 ? Infinity : y) ? -1 : 1
}
const ITEM = (text, input) => {
input = input.trim();
@ -147,7 +158,7 @@ export class AutoComplete {
'auto_first': false, // Should the first element be automatically selected?
'data': a => a,
'filter': FILTER_CONTAINS,
'sort': config.sort === false ? false : SORT_BYLENGTH,
'sort': config.sort === false ? false : SORT_BY_QUERY_POSITION,
'item': ITEM
}, config);