1import { 2 bindLocaleRerender, 3 getCanonicalContext, 4 createFormatter, 5 getCanonicalLocale, 6 getServerData, 7 initOnce, 8} from '../../../client-utils.js'; 9import { renderSupportArticleCards } from '../../support/support-utils.js'; 10import { selectDashboardSupportItems } from '../support/model.js'; 11import { buildDashboardNewsById } from './model.js'; 12import { applyNewsImage, applySupportImage, clearNewsImage } from '../../../image-proxy.js'; 13import { initDashboardInviteFriends } from './invite-friends/controller.js'; 14 15const DASHBOARD_NEWS_LIST_SELECTOR = '[data-dashboard-news-list]'; 16const DASHBOARD_NEWS_CARD_SELECTOR = '[data-dashboard-news-card]'; 17const DASHBOARD_SUPPORT_ARTICLES_LIMIT = 4; 18const DASHBOARD_RESPONSIVE_EXTRA_INDEX = 3; 19const DASHBOARD_RESPONSIVE_EXTRA_CLASSES = ['hidden', '@xl:block', '@4xl:hidden']; 20const DASHBOARD_HOME_CARD_IMAGE_SIZES = '(min-width: 1280px) 33vw, (min-width: 768px) 50vw, 100vw'; 21const DASHBOARD_SUPPORT_ARTICLES_SELECTOR = '[data-dashboard-home-support] [data-support-articles]'; 22const DASHBOARD_SUPPORT_ARTICLES_LIST_SELECTOR = '[data-dashboard-home-support] [data-support-articles-list]'; 23 24const markDashboardHomeResponsiveExtraCard = (list) => { 25 const responsiveExtraCard = list?.children?.[DASHBOARD_RESPONSIVE_EXTRA_INDEX]; 26 responsiveExtraCard?.classList?.add(...DASHBOARD_RESPONSIVE_EXTRA_CLASSES); 27}; 28 29const setText = (element, value) => { 30 if (element) { 31 element.textContent = value; 32 } 33}; 34 35const renderDashboardNewsLocale = (list, locale) => { 36 const canonicalLocale = getCanonicalLocale(); 37 const formatter = createFormatter(locale); 38 if (!canonicalLocale || !formatter) { 39 return false; 40 } 41 42 const newsById = buildDashboardNewsById(getServerData(), locale, canonicalLocale); 43 if (!newsById.size) { 44 return false; 45 } 46 47 let updated = false; 48 list.querySelectorAll(DASHBOARD_NEWS_CARD_SELECTOR).forEach((card) => { 49 const item = newsById.get(String(card.getAttribute('data-id') || '')); 50 if (!item) { 51 return; 52 } 53 54 const title = formatter.toText(item.title || ''); 55 setText(card.querySelector('[data-dashboard-news-card-title]'), title); 56 57 const arrow = card.querySelector('[data-dashboard-news-card-arrow]'); 58 if (arrow) { 59 arrow.setAttribute('aria-label', title); 60 } 61 62 const image = card.querySelector('[data-dashboard-news-card-image]'); 63 if (image instanceof HTMLImageElement) { 64 if (item.coverImage) { 65 applyNewsImage(image, { 66 sourceUrl: item.coverImage, 67 altText: title, 68 serverData: getServerData(), 69 }); 70 } else { 71 clearNewsImage(image); 72 } 73 } 74 updated = true; 75 }); 76 77 return updated; 78}; 79 80const renderDashboardSupportLocale = (section, list, templateItem, locale) => { 81 const canonicalLocale = getCanonicalLocale(); 82 const canonicalContext = getCanonicalContext(canonicalLocale); 83 const formatter = createFormatter(locale); 84 const serverData = getServerData(); 85 if (!canonicalLocale || !canonicalContext || !formatter) { 86 return false; 87 } 88 89 const displayArticles = selectDashboardSupportItems(serverData, 'lastSupportArticles', locale, canonicalLocale); 90 91 const rendered = renderSupportArticleCards({ 92 items: displayArticles, 93 formatter, 94 canonicalContext, 95 list, 96 templateItem, 97 section, 98 limit: DASHBOARD_SUPPORT_ARTICLES_LIMIT, 99 imageRenderer: (image, imageOptions) => applySupportImage(image, { ...imageOptions, serverData }), 100 imageSizes: DASHBOARD_HOME_CARD_IMAGE_SIZES, 101 }); 102 if (rendered) { 103 markDashboardHomeResponsiveExtraCard(list); 104 } 105 return rendered; 106}; 107 108const initDashboardHome = () => { 109 const list = document.querySelector(DASHBOARD_NEWS_LIST_SELECTOR); 110 if (!(list instanceof HTMLElement) || !initOnce(list, 'dashboardHomeInitialized')) { 111 return; 112 } 113 114 const supportSection = document.querySelector(DASHBOARD_SUPPORT_ARTICLES_SELECTOR); 115 const supportList = document.querySelector(DASHBOARD_SUPPORT_ARTICLES_LIST_SELECTOR); 116 const supportTemplate = document.getElementById('support-article-card-template'); 117 const supportTemplateItem = 118 supportTemplate instanceof HTMLTemplateElement ? supportTemplate.content.firstElementChild : null; 119 120 bindLocaleRerender({ 121 hasServerMarkup: () => Boolean(list.querySelector(DASHBOARD_NEWS_CARD_SELECTOR) || supportList?.children.length), 122 render: (locale) => { 123 renderDashboardNewsLocale(list, locale); 124 if (supportSection && supportList && supportTemplateItem) { 125 renderDashboardSupportLocale(supportSection, supportList, supportTemplateItem, locale); 126 } 127 }, 128 }); 129 130 void initDashboardInviteFriends().catch((error) => { 131 console.error('Failed to initialize dashboard invitations:', error); 132 }); 133}; 134 135export { 136 initDashboardHome, 137 markDashboardHomeResponsiveExtraCard, 138 renderDashboardNewsLocale, 139 renderDashboardSupportLocale, 140};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.