diff --git a/public/assets/js/xinon-vodia-identity.js b/public/assets/js/xinon-vodia-identity.js index 965a6f640..a65dcf2a3 100644 --- a/public/assets/js/xinon-vodia-identity.js +++ b/public/assets/js/xinon-vodia-identity.js @@ -39,9 +39,11 @@ document.body.insertAdjacentHTML('beforeend', ` class VodiaIdentitySwitcher { API_BASE_URL = window.baseurl || '/'; - POLLING_INTERVAL_MS = 30000; - CACHE_DURATION_MS = 30000; - CACHE_KEY = 'vodiaIdentityCache'; // Key for localStorage + POLLING_INTERVAL_MS = 60000; + CACHE_DURATION_MS = 60000; + CACHE_KEY = 'vodiaIdentityCache'; + LOADING_CACHE_KEY = 'vodiaIdentityCache_loading'; + LOADING_TIMEOUT_MS = 2000; TEXT = { checking: "Prüfe...", @@ -49,10 +51,8 @@ class VodiaIdentitySwitcher { dropdownTitle: "Ausgehende Identität wählen:", ownExtension: "Eigene Nummer", customIdentity: "Andere Nummer", - // ## START: ADDED TEXT ## noActiveCall: "Kein aktiver Anruf gefunden.", lookupError: "Fehler bei der Anrufabfrage." - // ## END: ADDED TEXT ## }; pollingTimer = null; @@ -74,24 +74,23 @@ class VodiaIdentitySwitcher { this.getVodiaIdentity(); } - _getCache() { - const cachedString = localStorage.getItem(this.CACHE_KEY); + _getCache(key) { + const cachedString = localStorage.getItem(key); if (!cachedString) return null; try { return JSON.parse(cachedString); } catch (e) { - console.error("Vodia Cache Error: Could not parse cached data.", e); - localStorage.removeItem(this.CACHE_KEY); + localStorage.removeItem(key); return null; } } - _setCache(vodiaState) { - const itemToCache = { data: vodiaState, timestamp: Date.now() }; + _setCache(key, data) { + const itemToCache = { data, timestamp: Date.now() }; try { - localStorage.setItem(this.CACHE_KEY, JSON.stringify(itemToCache)); + localStorage.setItem(key, JSON.stringify(itemToCache)); } catch (e) { - console.error("Vodia Cache Error: Could not write to localStorage.", e); + console.error(`Vodia Cache Error (${key}): Could not write to localStorage.`, e); } } @@ -140,12 +139,12 @@ class VodiaIdentitySwitcher { const { callLookupButton, callLookupIconStack, callLookupSpinner } = this.elements; if (isLoading) { callLookupButton.setAttribute('disabled', 'true'); - callLookupIconStack.classList.add('d-none'); // Hide the icon stack - callLookupSpinner.classList.remove('d-none'); // Show the spinner + callLookupIconStack.classList.add('d-none'); + callLookupSpinner.classList.remove('d-none'); } else { callLookupButton.removeAttribute('disabled'); - callLookupIconStack.classList.remove('d-none'); // Show the icon stack - callLookupSpinner.classList.add('d-none'); // Hide the spinner + callLookupIconStack.classList.remove('d-none'); + callLookupSpinner.classList.add('d-none'); } } @@ -158,7 +157,7 @@ class VodiaIdentitySwitcher { const data = await response.json(); if (data.status === 'OK' && data.result.number && data.result.number.length >= 5) { const url = `${this.API_BASE_URL}Address/Index?filter[pfm]=${data.result.number}`; - window.open(url, '_blank'); // Open address book in a new tab + window.open(url, '_blank'); } else { if (window.notify) window.notify('info', this.TEXT.noActiveCall); } @@ -169,7 +168,6 @@ class VodiaIdentitySwitcher { this._setLookupButtonLoadingState(false); } } - // ## END: ADDED METHOD TO HANDLE CALL LOOKUP ## _setLoadingState(isLoading, message = '') { const { phoneIcon, currentName, currentNumber } = this.elements; @@ -184,39 +182,49 @@ class VodiaIdentitySwitcher { } } + _updateFromState(vodiaState) { + if (vodiaState?.enabled) { + this.elements.container.style.display = 'flex'; + this._updateUI(vodiaState); + this._setLoadingState(false); + } else { + this.elements.container.style.display = 'none'; + } + } + async getVodiaIdentity() { clearTimeout(this.pollingTimer); + const cachedData = this._getCache(this.CACHE_KEY); + if (cachedData && (Date.now() - cachedData.timestamp < this.CACHE_DURATION_MS)) { + this._updateFromState(cachedData.data); + this.pollingTimer = setTimeout(() => this.getVodiaIdentity(), this.POLLING_INTERVAL_MS); + return; + } + + const loadingLock = this._getCache(this.LOADING_CACHE_KEY); + if (loadingLock && (Date.now() - loadingLock.timestamp < this.LOADING_TIMEOUT_MS)) { + setTimeout(() => this.getVodiaIdentity(), 500); + return; + } + + this._setLoadingState(true, this.TEXT.checking); + this._setCache(this.LOADING_CACHE_KEY, true); + try { - const cachedItem = this._getCache(); - let vodiaState; + const response = await fetch(`${this.API_BASE_URL}User/Api/do=getVodiaIdentity`); + if (!response.ok) throw new Error('Network response was not ok'); + const data = await response.json(); + if (data.status !== "OK") throw new Error(data.message || 'API returned an error'); - if (cachedItem && (Date.now() - cachedItem.timestamp < this.CACHE_DURATION_MS)) { - vodiaState = cachedItem.data; - } else { - this._setLoadingState(true, this.TEXT.checking); - const response = await fetch(`${this.API_BASE_URL}User/Api/do=getVodiaIdentity`); - if (!response.ok) throw new Error('Network response was not ok'); - - const data = await response.json(); - if (data.status !== "OK") throw new Error(data.message || 'API returned an error'); - - vodiaState = data.result; - this._setCache(vodiaState); - } - - if (vodiaState?.enabled) { - this.elements.container.style.display = 'flex'; // Use flex to align items - this._updateUI(vodiaState); - this._setLoadingState(false); - } else { - this.elements.container.style.display = 'none'; - } + this._setCache(this.CACHE_KEY, data.result); + this._updateFromState(data.result); } catch (error) { console.error("Vodia Fetch Error:", error.message); this.elements.phoneIcon.className = 'phone-icon fas fa-phone text-danger'; this.elements.currentName.textContent = 'Fehler'; } finally { + localStorage.removeItem(this.LOADING_CACHE_KEY); this.pollingTimer = setTimeout(() => this.getVodiaIdentity(), this.POLLING_INTERVAL_MS); } } @@ -237,7 +245,8 @@ class VodiaIdentitySwitcher { const data = await response.json(); if (data.status !== "OK") throw new Error(data.message || 'API returned an error.'); - localStorage.removeItem(this.CACHE_KEY) + localStorage.removeItem(this.CACHE_KEY); + localStorage.removeItem(this.LOADING_CACHE_KEY); } catch (error) { console.error("Vodia Set Error:", error.message); if (window.notify) window.notify.error("Fehler beim Ändern der ID!"); @@ -318,4 +327,4 @@ class VodiaIdentitySwitcher { document.addEventListener('DOMContentLoaded', () => { const topbar = document.querySelector("#topbar"); if (topbar) new VodiaIdentitySwitcher(topbar); -}); \ No newline at end of file +});