diff --git a/package-lock.json b/package-lock.json index 8b1ed2b..ee63518 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "call-me", - "version": "1.3.08", + "version": "1.3.09", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "call-me", - "version": "1.3.08", + "version": "1.3.09", "license": "AGPLv3", "dependencies": { "@ngrok/ngrok": "1.7.0", diff --git a/package.json b/package.json index 43ab932..862abd9 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "call-me", - "version": "1.3.08", + "version": "1.3.09", "description": "Your Go-To for Instant Video Calls", "author": "Miroslav Pejic - miroslav.pejic.85@gmail.com", "license": "AGPLv3", diff --git a/public/client.js b/public/client.js index b78fb0b..bf49c44 100755 --- a/public/client.js +++ b/public/client.js @@ -2148,6 +2148,11 @@ async function waitForDataChannelDrain() { // Select user by value in the user list function renderUserList() { + // Dispose existing Bootstrap tooltips before clearing the list + userList.querySelectorAll('[data-toggle="tooltip"]').forEach((el) => { + const tip = bootstrap.Tooltip.getInstance(el); + if (tip) tip.dispose(); + }); userList.innerHTML = ''; filteredUsers.forEach((user) => { const li = document.createElement('li'); @@ -2162,8 +2167,6 @@ function renderUserList() { const actionBtnEl = document.createElement('button'); actionBtnEl.style.marginRight = '10px'; actionBtnEl.style.cursor = 'pointer'; - actionBtnEl.setAttribute('data-toggle', 'tooltip'); - actionBtnEl.setAttribute('data-placement', 'top'); if (isInActiveCall) { // Show hang-up button only if in active call (user has answered) @@ -2201,8 +2204,6 @@ function renderUserList() { sendFileBtn.innerHTML = ''; sendFileBtn.style.marginRight = '10px'; sendFileBtn.style.cursor = 'pointer'; - sendFileBtn.setAttribute('data-toggle', 'tooltip'); - sendFileBtn.setAttribute('data-placement', 'top'); sendFileBtn.title = t('file.sendToUser', { username: user }); sendFileBtn.addEventListener('click', (e) => { e.stopPropagation(); @@ -2250,6 +2251,17 @@ function renderUserList() { }); userList.appendChild(li); }); + + // Initialize Bootstrap tooltips on dynamically created buttons (skip on mobile) + if (!userInfo.device.isMobile) { + const tooltipEls = userList.querySelectorAll('[title]'); + tooltipEls.forEach((el) => { + el.setAttribute('data-toggle', 'tooltip'); + el.setAttribute('data-placement', 'top'); + const tip = new bootstrap.Tooltip(el); + el.addEventListener('click', () => tip.hide()); + }); + } } // Filter user list based on search input