(function () { function initTelegramFab() { const root = document.getElementById('telegramFabRoot'); if (!root || root.dataset.initialized === 'true') { return; } root.dataset.initialized = 'true'; const dataset = root.dataset; const offcanvasElement = document.getElementById('telegramPremiumOffcanvas'); const loadingSection = document.getElementById('telegramFabLoading'); const connectedSection = document.getElementById('telegramFabConnected'); const disconnectedSection = document.getElementById('telegramFabDisconnected'); const alertElement = document.getElementById('telegramFabAlert'); const retryButton = root.querySelector('.telegram-fab-retry'); const openButton = root.querySelector('.telegram-fab-open'); const unlinkButton = root.querySelector('.telegram-fab-unlink'); const usernameElement = root.querySelector('.telegram-fab-username'); const widgetPlaceholder = document.getElementById('telegramLoginWidgetPlaceholder'); const toastContainer = document.getElementById('telegramFabToasts'); const fabButton = document.getElementById('telegramPremiumFab'); if (!offcanvasElement || !loadingSection || !connectedSection || !disconnectedSection) { console.warn('[Telegram FAB] Missing required DOM nodes. Aborting initialization.'); return; } const offcanvas = bootstrap.Offcanvas.getOrCreateInstance(offcanvasElement); let currentStatus = null; let currentDeepLink = null; let widgetMounted = false; const messages = { loading: dataset.statusLoading || 'Loading...', error: dataset.statusError || 'Something went wrong.', connectedTemplate: dataset.statusConnected || 'Connected as {0}', disconnected: dataset.statusDisconnected || '', linkSuccess: dataset.linkSuccess || 'Linked successfully.', unlinkSuccess: dataset.unlinkSuccess || 'Unlinked successfully.', linkError: dataset.linkError || 'Unable to link. Try again.', unlinkError: dataset.unlinkError || 'Unable to unlink. Try again.', retry: dataset.retryLabel || 'Try again', open: dataset.openLabel || 'Open', unlink: dataset.unlinkLabel || 'Unlink' }; function toggleSections(state) { loadingSection.classList.toggle('d-none', state !== 'loading'); connectedSection.classList.toggle('d-none', state !== 'connected'); disconnectedSection.classList.toggle('d-none', state !== 'disconnected'); } function showAlert(message) { if (!alertElement) { return; } alertElement.textContent = message; alertElement.classList.remove('d-none'); } function hideAlert() { if (!alertElement) { return; } alertElement.classList.add('d-none'); alertElement.textContent = ''; } function showToast(message, type) { if (!toastContainer || !message) { return; } const palette = { success: 'text-bg-success', error: 'text-bg-danger', info: 'text-bg-info' }; const toast = document.createElement('div'); toast.className = `toast align-items-center ${palette[type] || palette.info} border-0`; toast.role = 'status'; toast.setAttribute('aria-live', 'polite'); toast.innerHTML = [ '
', `
${message}
`, '', '
' ].join(''); toastContainer.appendChild(toast); const toastInstance = bootstrap.Toast.getOrCreateInstance(toast, { delay: 4000, autohide: true }); toast.addEventListener('hidden.bs.toast', function () { toast.remove(); }); toastInstance.show(); } function updateConnectedView(username, deepLink) { toggleSections('connected'); hideAlert(); if (usernameElement) { usernameElement.textContent = username || ''; } currentDeepLink = deepLink || null; } function updateDisconnectedView() { toggleSections('disconnected'); hideAlert(); if (!widgetMounted) { mountLoginWidget(); } } function applyErrorState(message) { toggleSections('disconnected'); showAlert(message || messages.error); if (retryButton) { retryButton.classList.remove('d-none'); } } async function fetchStatus() { toggleSections('loading'); hideAlert(); try { const response = await fetch('/telegram/status', { method: 'GET', credentials: 'same-origin', headers: { 'Accept': 'application/json' } }); if (response.status === 401 || response.status === 403) { if (fabButton) { fabButton.setAttribute('hidden', 'hidden'); fabButton.setAttribute('tabindex', '-1'); } root.setAttribute('aria-hidden', 'true'); root.style.display = 'none'; return; } if (!response.ok) { throw new Error('status_request_failed'); } currentStatus = await response.json(); if (currentStatus && currentStatus.connected) { updateConnectedView(currentStatus.username || '', currentStatus.deepLink || null); } else { updateDisconnectedView(); } } catch (error) { console.warn('[Telegram FAB] Status request failed:', error); applyErrorState(messages.error); } } function mountLoginWidget() { const botUsernameRaw = (dataset.botUsername || '').trim(); if (!botUsernameRaw) { console.warn('[Telegram FAB] Telegram bot username missing. Configure Telegram:LoginWidgetBotUsername.'); applyErrorState(messages.error); return; } const botUsername = botUsernameRaw.startsWith('@') ? botUsernameRaw.slice(1) : botUsernameRaw; if (!widgetPlaceholder) { return; } widgetPlaceholder.innerHTML = ''; const widgetScript = document.createElement('script'); widgetScript.src = 'https://telegram.org/js/telegram-widget.js?22'; widgetScript.async = true; widgetScript.dataset.telegramLogin = botUsername; widgetScript.dataset.size = 'large'; widgetScript.dataset.userpic = 'false'; widgetScript.dataset.requestAccess = dataset.requestAccess || 'write'; const lang = (dataset.telegramLang || 'en').replace('-', '_'); widgetScript.dataset.lang = lang; widgetScript.dataset.onauth = 'telegramFabOnAuth'; widgetPlaceholder.appendChild(widgetScript); widgetMounted = true; } async function linkTelegram(payload) { toggleSections('loading'); hideAlert(); try { const response = await fetch('/telegram/link', { method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify(payload) }); if (!response.ok) { throw new Error('link_failed'); } showToast(messages.linkSuccess, 'success'); await fetchStatus(); } catch (error) { console.error('[Telegram FAB] Link failed:', error); showToast(messages.linkError, 'error'); applyErrorState(messages.linkError); } } async function unlinkTelegram() { toggleSections('loading'); hideAlert(); try { const response = await fetch('/telegram/unlink', { method: 'POST', credentials: 'same-origin', headers: { 'Accept': 'application/json' } }); if (!response.ok) { throw new Error('unlink_failed'); } showToast(messages.unlinkSuccess, 'success'); widgetMounted = false; await fetchStatus(); } catch (error) { console.error('[Telegram FAB] Unlink failed:', error); showToast(messages.unlinkError, 'error'); toggleSections('connected'); showAlert(messages.unlinkError); } } offcanvasElement.addEventListener('show.bs.offcanvas', function () { fetchStatus(); }); if (retryButton) { retryButton.addEventListener('click', function () { hideAlert(); fetchStatus(); }); } if (openButton) { openButton.addEventListener('click', function () { if (currentDeepLink) { window.open(currentDeepLink, '_blank', 'noopener'); } else { fetchStatus(); } }); } if (unlinkButton) { unlinkButton.addEventListener('click', function () { unlinkTelegram(); }); } window.telegramFabOnAuth = function (user) { if (!user) { showToast(messages.linkError, 'error'); return; } const payload = { id: user.id, hash: user.hash, first_name: user.first_name, last_name: user.last_name, username: user.username, photo_url: user.photo_url, auth_date: user.auth_date, bot_id: dataset.botId || null }; linkTelegram(payload); }; if (fabButton) { fabButton.addEventListener('keydown', function (event) { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); offcanvas.show(); } }); } } document.addEventListener('DOMContentLoaded', initTelegramFab); window.initTelegramFab = initTelegramFab; })();