// Generated, do not edit. sha256:ab0e4307745aa40cfdb48df36e50ccead564b09ed673bdaf465f9ded7d5651dd import { listProviders, getProvider } from '../data/providers.js'; import { t } from '../i18n/index.js'; import { CONFIG, TARGETS, targetHash } from '../../shared/config.js'; import { appSetting } from '../app-settings.js'; import { initPrivacyBlur } from './blur.js'; import { generalAttention, attentionHasProblem, attentionDimmed } from './attention.js'; import { openPopover, closePopover } from './popover.js'; import { esc } from './escape.js'; const FADE_OK_MS = 2600; const FADE_FAIL_MS = 6000; const LABEL_MS = 2600; const MAX_COLS = 6; const MAX_ROWS = 3; const MOBILE_MQ = '(max-width: 768px)'; let rootEl = null; let dotsEl = null; let labelEls = []; let dotTimers = new Map(); let labelSlots = []; let dotKeys = ''; let attnEl = null; let labelActive = 0; let attnMenuOpen = false; async function callableProviders() { const rijen = await listProviders(); const configs = await Promise.all(rijen.map(r => getProvider(r.key))); return configs.filter(p => p && p.isActive && ((!p.isSystem && p.endpoints.length > 0) || isAskedService(p))); } function isAskedService(p) { if (p.key !== CONFIG.MARKET_SERVICE.PROVIDER_KEY) return false; try { return appSetting('market_spot') !== 'off'; } catch { return false; } } function rowsFor(n) { if (n <= 1) return 1; if (n <= MAX_COLS * 2) return 2; return MAX_ROWS; } async function syncDots() { const provs = await callableProviders(); const keys = provs.map(p => p.key).join('|'); if (keys === dotKeys) return; dotKeys = keys; const rows = rowsFor(provs.length); const cols = Math.max(1, Math.ceil(provs.length / rows)); dotsEl.style.setProperty('--sb-rows', String(rows)); rootEl.style.setProperty('--sb-vak', `max(2.1rem, ${cols * 7 + (cols - 1) * 5}px)`); dotsEl.innerHTML = provs.map(p => `` ).join(''); dotTimers.clear(); } function lightDot(key, ok) { const dot = dotsEl.querySelector(`[data-provider-key="${CSS.escape(key)}"]`); if (!dot) return; dot.classList.remove('is-active', 'is-ok', 'is-fail'); void dot.offsetWidth; dot.classList.add('is-active', ok ? 'is-ok' : 'is-fail'); const prev = dotTimers.get(key); if (prev) clearTimeout(prev); dotTimers.set(key, setTimeout(() => dot.classList.remove('is-active', 'is-ok', 'is-fail'), ok ? FADE_OK_MS : FADE_FAIL_MS)); } function showSymbol(sym) { if (!sym) return; let slot = labelSlots.find(s => s.ts === 0); if (!slot) slot = labelSlots[0].ts <= labelSlots[1].ts ? labelSlots[0] : labelSlots[1]; slot.ts = Date.now(); slot.el.textContent = sym; slot.el.classList.remove('is-flash'); void slot.el.offsetWidth; slot.el.classList.add('is-flash'); labelActive++; syncAttention(); if (slot.timer) clearTimeout(slot.timer); slot.timer = setTimeout(() => { slot.el.classList.remove('is-flash'); slot.el.textContent = ''; slot.ts = 0; labelActive = Math.max(0, labelActive - 1); syncAttention(); }, LABEL_MS); } function syncAttention() { if (!attnEl) return; const items = generalAttention(); const show = items.length > 0 && labelActive === 0; const dim = attentionDimmed(items); attnEl.textContent = items.length >= 2 ? String(items.length) : '!'; attnEl.classList.toggle('is-shown', show); attnEl.classList.toggle('is-count', items.length >= 2); attnEl.classList.toggle('is-dim', dim); attnEl.classList.toggle('is-problem', attentionHasProblem(items)); attnEl.setAttribute('aria-hidden', show ? 'false' : 'true'); attnEl.tabIndex = show ? 0 : -1; if (!show && attnMenuOpen) closePopover(); } function openAttentionMenu() { if (attnMenuOpen) return; const items = generalAttention(); if (!items.length) return; const { el, position } = openPopover(attnEl, { className: 'popover attn-menu', onClose: () => { attnMenuOpen = false; }, }); attnMenuOpen = true; el.innerHTML = `
` + items.map(a => ``).join(''); position(); el.addEventListener('click', (e) => { const b = e.target.closest('[data-hash]'); if (!b) return; closePopover(); if (b.dataset.hash) location.hash = b.dataset.hash; }); } function place(mq) { const slot = document.getElementById(mq.matches ? 'sb-slot-mobile' : 'sb-slot-desktop'); if (slot && rootEl.parentElement !== slot) slot.appendChild(rootEl); } export function initStatusBar() { if (rootEl) return; rootEl = document.createElement('div'); rootEl.className = 'statusbar'; rootEl.setAttribute('role', 'group'); rootEl.setAttribute('aria-label', t('integrations.indicatorHint')); rootEl.innerHTML = '' + '' + '' + '' + ''; dotsEl = rootEl.querySelector('.statusbar-dots'); labelEls = [...rootEl.querySelectorAll('.statusbar-label')]; labelSlots = labelEls.map(el => ({ el, ts: 0, timer: null })); attnEl = rootEl.querySelector('.statusbar-attn'); attnEl.addEventListener('click', openAttentionMenu); initPrivacyBlur(rootEl.querySelector('.statusbar-blur')); syncDots(); dotsEl.addEventListener('click', (e) => { const dot = e.target.closest('[data-provider-key]'); if (!dot) return; try { sessionStorage.setItem('integrations.focus', dot.dataset.providerKey); } catch { } location.hash = targetHash(TARGETS.INTEGRATIONS); }); document.addEventListener('api-call', (e) => { const d = e.detail || {}; if (d.provider_key) lightDot(d.provider_key, !!d.ok); if (d.symbol) showSymbol(d.symbol); }); document.addEventListener('providers-changed', syncDots); window.addEventListener('hashchange', syncDots); document.addEventListener('attention-changed', syncAttention); syncAttention(); const mq = window.matchMedia(MOBILE_MQ); mq.addEventListener('change', () => place(mq)); place(mq); }