From a70dfabaaef5141771dfb31a9d8056aab1e3dc86 Mon Sep 17 00:00:00 2001 From: vyneer Date: Tue, 16 Jul 2024 15:11:55 +0300 Subject: [PATCH] refactor: simplify autocomplete positioning setter --- assets/chat/js/autocomplete.js | 56 ++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/assets/chat/js/autocomplete.js b/assets/chat/js/autocomplete.js index 5ad8b6c1..53c59e32 100644 --- a/assets/chat/js/autocomplete.js +++ b/assets/chat/js/autocomplete.js @@ -65,19 +65,49 @@ function updateHelpers(ac) { } function selectHelper(ac) { // Positioning - if (ac.selected !== -1 && ac.results.length > 0) { - const list = ac.ui.find(`li`).get(); - const offset = ac.container.position().left; - const maxwidth = ac.ui.width(); - $(list[ac.selected + 3]).each((i, e) => { - const right = $(e).position().left + offset + $(e).outerWidth(); - if (right > maxwidth) ac.container.css('left', offset + maxwidth - right); - }); - $(list[Math.max(0, ac.selected - 2)]).each((i, e) => { - const left = $(e).position().left + offset; - if (left < 0) ac.container.css('left', -$(e).position().left); - }); - list.forEach((e, i) => $(e).toggleClass('active', i === ac.selected)); + if (ac.results.length === 0) { + return; + } + + const list = ac.ui.find(`li`).get(); + + list.forEach((e, i) => $(e).toggleClass('active', i === ac.selected)); + + const fullWidth = ac.container.width(); + const visibleWidth = ac.ui.width(); + const selectedItem = list[ac.selected]; + + if (visibleWidth > fullWidth) { + return; + } + + const offset = ac.container.position().left; + + const nearStart = selectedItem.offsetLeft < -offset; + const nearEnd = + fullWidth - selectedItem.offsetLeft + selectedItem.clientWidth * 2 < + visibleWidth; + const anywhereElse = + selectedItem.offsetLeft + selectedItem.clientWidth * 2 > visibleWidth; + + if (nearEnd) { + ac.container.css('left', -fullWidth + visibleWidth); + return; + } + + if (anywhereElse) { + ac.container.css( + 'left', + -selectedItem.offsetLeft - + selectedItem.clientWidth / 2 + + visibleWidth / 2, + ); + return; + } + + // this is needed to properly loop back the list to the beginning + if (nearStart) { + ac.container.css('left', -selectedItem.offsetLeft); } }