/** * Module for display list view. * @module components/listview/listview */ import escapeHtml from 'escape-html'; import itemHelper from '../itemHelper'; import mediaInfo from '../mediainfo/mediainfo'; import indicators from '../indicators/indicators'; import layoutManager from '../layoutManager'; import globalize from '../../scripts/globalize'; import datetime from '../../scripts/datetime'; import cardBuilder from '../cardbuilder/cardBuilder'; import './listview.scss'; import '../../elements/emby-ratingbutton/emby-ratingbutton'; import '../../elements/emby-playstatebutton/emby-playstatebutton'; import ServerConnections from '../ServerConnections'; function getIndex(item, options) { if (options.index === 'disc') { return item.ParentIndexNumber == null ? '' : globalize.translate('ValueDiscNumber', item.ParentIndexNumber); } const sortBy = (options.sortBy || '').toLowerCase(); let code; let name; if (sortBy.indexOf('sortname') === 0) { if (item.Type === 'Episode') { return ''; } // SortName name = (item.SortName || item.Name || '?')[0].toUpperCase(); code = name.charCodeAt(0); if (code < 65 || code > 90) { return '#'; } return name.toUpperCase(); } if (sortBy.indexOf('officialrating') === 0) { return item.OfficialRating || globalize.translate('Unrated'); } if (sortBy.indexOf('communityrating') === 0) { if (item.CommunityRating == null) { return globalize.translate('Unrated'); } return Math.floor(item.CommunityRating); } if (sortBy.indexOf('criticrating') === 0) { if (item.CriticRating == null) { return globalize.translate('Unrated'); } return Math.floor(item.CriticRating); } if (sortBy.indexOf('albumartist') === 0) { // SortName if (!item.AlbumArtist) { return ''; } name = item.AlbumArtist[0].toUpperCase(); code = name.charCodeAt(0); if (code < 65 || code > 90) { return '#'; } return name.toUpperCase(); } return ''; } function getImageUrl(item, size) { const apiClient = ServerConnections.getApiClient(item.ServerId); let itemId; const options = { fillWidth: size, fillHeight: size, type: 'Primary' }; if (item.ImageTags?.Primary) { options.tag = item.ImageTags.Primary; itemId = item.Id; } else if (item.AlbumId && item.AlbumPrimaryImageTag) { options.tag = item.AlbumPrimaryImageTag; itemId = item.AlbumId; } else if (item.SeriesId && item.SeriesPrimaryImageTag) { options.tag = item.SeriesPrimaryImageTag; itemId = item.SeriesId; } else if (item.ParentPrimaryImageTag) { options.tag = item.ParentPrimaryImageTag; itemId = item.ParentPrimaryImageItemId; } if (itemId) { return apiClient.getScaledImageUrl(itemId, options); } return null; } function getChannelImageUrl(item, size) { const apiClient = ServerConnections.getApiClient(item.ServerId); const options = { fillWidth: size, fillHeight: size, type: 'Primary' }; if (item.ChannelId && item.ChannelPrimaryImageTag) { options.tag = item.ChannelPrimaryImageTag; } if (item.ChannelId) { return apiClient.getScaledImageUrl(item.ChannelId, options); } } function getTextLinesHtml(textlines, isLargeStyle) { let html = ''; const largeTitleTagName = layoutManager.tv ? 'h2' : 'div'; for (const [i, text] of textlines.entries()) { if (!text) { continue; } let elem; if (i === 0) { if (isLargeStyle) { elem = document.createElement(largeTitleTagName); } else { elem = document.createElement('div'); } } else { elem = document.createElement('div'); elem.classList.add('secondary'); } elem.classList.add('listItemBodyText'); elem.innerHTML = '' + escapeHtml(text) + ''; html += elem.outerHTML; } return html; } function getRightButtonsHtml(options) { let html = ''; for (let i = 0, length = options.rightButtons.length; i < length; i++) { const button = options.rightButtons[i]; html += ``; } return html; } export function getListViewHtml(options) { const items = options.items; let groupTitle = ''; const action = options.action || 'link'; const isLargeStyle = options.imageSize === 'large'; const enableOverview = options.enableOverview; const clickEntireItem = layoutManager.tv; const outerTagName = clickEntireItem ? 'button' : 'div'; const enableSideMediaInfo = options.enableSideMediaInfo != null ? options.enableSideMediaInfo : true; let outerHtml = ''; const enableContentWrapper = options.enableOverview && !layoutManager.tv; for (let i = 0, length = items.length; i < length; i++) { const item = items[i]; let html = ''; if (options.showIndex) { const itemGroupTitle = getIndex(item, options); if (itemGroupTitle !== groupTitle) { if (html) { html += ''; } if (i === 0) { html += '