2022-01-30 00:27:26 +03:00
|
|
|
import escapeHtml from 'escape-html';
|
2020-08-14 08:46:34 +02:00
|
|
|
import datetime from '../../scripts/datetime';
|
2024-08-14 13:31:34 -04:00
|
|
|
import globalize from '../../lib/globalize';
|
2023-05-01 10:04:13 -04:00
|
|
|
import { appRouter } from '../router/appRouter';
|
2020-08-14 08:46:34 +02:00
|
|
|
import itemHelper from '../itemHelper';
|
|
|
|
import indicators from '../indicators/indicators';
|
|
|
|
import 'material-design-icons-iconfont';
|
2021-01-26 16:25:38 -05:00
|
|
|
import './mediainfo.scss';
|
|
|
|
import '../guide/programs.scss';
|
2020-08-14 08:46:34 +02:00
|
|
|
import '../../elements/emby-button/emby-button';
|
2022-11-21 17:45:56 -06:00
|
|
|
import * as userSettings from '../../scripts/settings/userSettings';
|
2020-06-13 19:32:38 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
function getTimerIndicator(item) {
|
|
|
|
let status;
|
|
|
|
|
|
|
|
if (item.Type === 'SeriesTimer') {
|
|
|
|
return '<span class="material-icons mediaInfoItem mediaInfoIconItem mediaInfoTimerIcon fiber_smart_record" aria-hidden="true"></span>';
|
|
|
|
} else if (item.TimerId || item.SeriesTimerId) {
|
|
|
|
status = item.Status || 'Cancelled';
|
|
|
|
} else if (item.Type === 'Timer') {
|
|
|
|
status = item.Status;
|
|
|
|
} else {
|
|
|
|
return '';
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.SeriesTimerId) {
|
|
|
|
if (status !== 'Cancelled') {
|
2022-02-24 20:15:24 +03:00
|
|
|
return '<span class="material-icons mediaInfoItem mediaInfoIconItem mediaInfoTimerIcon fiber_smart_record" aria-hidden="true"></span>';
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
return '<span class="material-icons mediaInfoItem mediaInfoIconItem fiber_smart_record" aria-hidden="true"></span>';
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
return '<span class="material-icons mediaInfoItem mediaInfoIconItem mediaInfoTimerIcon fiber_manual_record" aria-hidden="true"></span>';
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
function getProgramInfoHtml(item, options) {
|
|
|
|
let html = '';
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
const miscInfo = [];
|
|
|
|
let text;
|
|
|
|
let date;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.StartDate && options.programTime !== false) {
|
|
|
|
try {
|
|
|
|
text = '';
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
date = datetime.parseISO8601Date(item.StartDate);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (options.startDate !== false) {
|
|
|
|
text += datetime.toLocaleDateString(date, { weekday: 'short', month: 'short', day: 'numeric' });
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
text += ` ${datetime.getDisplayTime(date)}`;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.EndDate) {
|
|
|
|
date = datetime.parseISO8601Date(item.EndDate);
|
|
|
|
text += ` - ${datetime.getDisplayTime(date)}`;
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
miscInfo.push(text);
|
|
|
|
} catch (e) {
|
|
|
|
console.error('error parsing date:', item.StartDate);
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.ChannelNumber) {
|
|
|
|
miscInfo.push(`CH ${item.ChannelNumber}`);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.ChannelName) {
|
|
|
|
if (options.interactive && item.ChannelId) {
|
|
|
|
miscInfo.push({
|
|
|
|
html: `<a is="emby-linkbutton" class="button-flat mediaInfoItem" href="${appRouter.getRouteUrl({
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
ServerId: item.ServerId,
|
|
|
|
Type: 'TvChannel',
|
|
|
|
Name: item.ChannelName,
|
|
|
|
Id: item.ChannelId
|
|
|
|
|
|
|
|
})}">${escapeHtml(item.ChannelName)}</a>`
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
miscInfo.push(escapeHtml(item.ChannelName));
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (options.timerIndicator !== false) {
|
|
|
|
const timerHtml = getTimerIndicator(item);
|
|
|
|
if (timerHtml) {
|
|
|
|
miscInfo.push({
|
|
|
|
html: timerHtml
|
|
|
|
});
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
html += miscInfo.map(m => {
|
|
|
|
return getMediaInfoItem(m);
|
|
|
|
}).join('');
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
return html;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
export function getMediaInfoHtml(item, options = {}) {
|
|
|
|
let html = '';
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
const miscInfo = [];
|
|
|
|
let text;
|
|
|
|
let date;
|
|
|
|
let count;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
const showFolderRuntime = item.Type === 'MusicAlbum' || item.MediaType === 'MusicArtist' || item.Type === 'Playlist' || item.MediaType === 'Playlist' || item.MediaType === 'MusicGenre';
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (showFolderRuntime) {
|
|
|
|
count = item.SongCount || item.ChildCount;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (count) {
|
|
|
|
miscInfo.push(globalize.translate('TrackCount', count));
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.RunTimeTicks) {
|
|
|
|
miscInfo.push(datetime.getDisplayDuration(item.RunTimeTicks));
|
|
|
|
}
|
|
|
|
} else if (item.Type === 'PhotoAlbum' || item.Type === 'BoxSet') {
|
|
|
|
count = item.ChildCount;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (count) {
|
|
|
|
miscInfo.push(globalize.translate('ItemCount', count));
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if ((item.Type === 'Episode' || item.MediaType === 'Photo')
|
2022-10-03 14:22:02 -04:00
|
|
|
&& options.originalAirDate !== false
|
|
|
|
&& item.PremiereDate
|
2023-04-19 01:56:05 -04:00
|
|
|
) {
|
|
|
|
try {
|
|
|
|
//don't modify date to locale if episode. Only Dates (not times) are stored, or editable in the edit metadata dialog
|
|
|
|
date = datetime.parseISO8601Date(item.PremiereDate, item.Type !== 'Episode');
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
text = datetime.toLocaleDateString(date);
|
|
|
|
miscInfo.push(text);
|
|
|
|
} catch (e) {
|
|
|
|
console.error('error parsing date:', item.PremiereDate);
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.Type === 'SeriesTimer') {
|
|
|
|
if (item.RecordAnyTime) {
|
|
|
|
miscInfo.push(globalize.translate('Anytime'));
|
|
|
|
} else {
|
|
|
|
miscInfo.push(datetime.getDisplayTime(item.StartDate));
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.RecordAnyChannel) {
|
|
|
|
miscInfo.push(globalize.translate('AllChannels'));
|
|
|
|
} else {
|
|
|
|
miscInfo.push(item.ChannelName || globalize.translate('OneChannel'));
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.StartDate && item.Type !== 'Program' && item.Type !== 'SeriesTimer' && item.Type !== 'Timer') {
|
|
|
|
try {
|
|
|
|
date = datetime.parseISO8601Date(item.StartDate);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
text = datetime.toLocaleDateString(date);
|
|
|
|
miscInfo.push(text);
|
|
|
|
|
|
|
|
if (item.Type !== 'Recording') {
|
|
|
|
text = datetime.getDisplayTime(date);
|
2019-01-10 15:39:37 +03:00
|
|
|
miscInfo.push(text);
|
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
} catch (e) {
|
|
|
|
console.error('error parsing date:', item.StartDate);
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (options.year !== false && item.ProductionYear && item.Type === 'Series') {
|
|
|
|
if (item.Status === 'Continuing') {
|
|
|
|
miscInfo.push(globalize.translate('SeriesYearToPresent', datetime.toLocaleString(item.ProductionYear, { useGrouping: false })));
|
|
|
|
} else if (item.ProductionYear) {
|
|
|
|
text = datetime.toLocaleString(item.ProductionYear, { useGrouping: false });
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.EndDate) {
|
2019-01-10 15:39:37 +03:00
|
|
|
try {
|
2023-04-19 01:56:05 -04:00
|
|
|
const endYear = datetime.toLocaleString(datetime.parseISO8601Date(item.EndDate).getFullYear(), { useGrouping: false });
|
2023-10-13 12:21:32 +08:00
|
|
|
/* At this point, text will contain only the start year */
|
2023-10-13 01:54:42 +08:00
|
|
|
if (endYear !== text) {
|
|
|
|
text += ` - ${endYear}`;
|
2023-04-19 01:56:05 -04:00
|
|
|
}
|
2019-11-23 00:29:38 +09:00
|
|
|
} catch (e) {
|
2023-04-19 01:56:05 -04:00
|
|
|
console.error('error parsing date:', item.EndDate);
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
|
|
|
|
miscInfo.push(text);
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.Type === 'Program' || item.Type === 'Timer') {
|
|
|
|
let program = item;
|
|
|
|
if (item.Type === 'Timer') {
|
|
|
|
program = item.ProgramInfo;
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (options.programIndicator !== false) {
|
|
|
|
if (program.IsLive && userSettings.get('guide-indicator-live') === 'true') {
|
|
|
|
miscInfo.push({
|
|
|
|
html: `<div class="mediaInfoProgramAttribute mediaInfoItem liveTvProgram">${globalize.translate('Live')}</div>`
|
|
|
|
});
|
|
|
|
} else if (program.IsPremiere && userSettings.get('guide-indicator-premiere') === 'true') {
|
|
|
|
miscInfo.push({
|
|
|
|
html: `<div class="mediaInfoProgramAttribute mediaInfoItem premiereTvProgram">${globalize.translate('Premiere')}</div>`
|
|
|
|
});
|
|
|
|
} else if (program.IsSeries && !program.IsRepeat && userSettings.get('guide-indicator-new') === 'true') {
|
|
|
|
miscInfo.push({
|
|
|
|
html: `<div class="mediaInfoProgramAttribute mediaInfoItem newTvProgram">${globalize.translate('New')}</div>`
|
|
|
|
});
|
|
|
|
} else if (program.IsSeries && program.IsRepeat && userSettings.get('guide-indicator-repeat') === 'true') {
|
|
|
|
miscInfo.push({
|
|
|
|
html: `<div class="mediaInfoProgramAttribute mediaInfoItem repeatTvProgram">${globalize.translate('Repeat')}</div>`
|
|
|
|
});
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if ((program.IsSeries || program.EpisodeTitle) && options.episodeTitle !== false) {
|
|
|
|
text = itemHelper.getDisplayName(program, {
|
|
|
|
includeIndexNumber: options.episodeTitleIndexNumber
|
2019-01-10 15:39:37 +03:00
|
|
|
});
|
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (text) {
|
|
|
|
miscInfo.push(escapeHtml(text));
|
|
|
|
}
|
|
|
|
} else if (program.IsMovie && program.ProductionYear && options.originalAirDate !== false) {
|
|
|
|
miscInfo.push(program.ProductionYear);
|
|
|
|
} else if (program.PremiereDate && options.originalAirDate !== false) {
|
|
|
|
try {
|
|
|
|
date = datetime.parseISO8601Date(program.PremiereDate);
|
|
|
|
text = globalize.translate('OriginalAirDateValue', datetime.toLocaleDateString(date));
|
|
|
|
miscInfo.push(text);
|
|
|
|
} catch (e) {
|
|
|
|
console.error('error parsing date:', program.PremiereDate);
|
|
|
|
}
|
|
|
|
} else if (program.ProductionYear && options.year !== false ) {
|
|
|
|
miscInfo.push(program.ProductionYear);
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (options.year !== false && item.Type !== 'Series' && item.Type !== 'Episode' && item.Type !== 'Person'
|
|
|
|
&& item.MediaType !== 'Photo' && item.Type !== 'Program' && item.Type !== 'Season'
|
|
|
|
) {
|
|
|
|
if (item.ProductionYear) {
|
|
|
|
miscInfo.push(item.ProductionYear);
|
|
|
|
} else if (item.PremiereDate) {
|
|
|
|
try {
|
|
|
|
text = datetime.toLocaleString(datetime.parseISO8601Date(item.PremiereDate).getFullYear(), { useGrouping: false });
|
|
|
|
miscInfo.push(text);
|
|
|
|
} catch (e) {
|
|
|
|
console.error('error parsing date:', item.PremiereDate);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.RunTimeTicks && item.Type !== 'Series' && item.Type !== 'Program' && item.Type !== 'Timer' && item.Type !== 'Book' && !showFolderRuntime && options.runtime !== false) {
|
|
|
|
if (item.Type === 'Audio') {
|
|
|
|
miscInfo.push(datetime.getDisplayRunningTime(item.RunTimeTicks));
|
|
|
|
} else {
|
|
|
|
miscInfo.push(datetime.getDisplayDuration(item.RunTimeTicks));
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (options.officialRating !== false && item.OfficialRating && item.Type !== 'Season' && item.Type !== 'Episode') {
|
|
|
|
miscInfo.push({
|
|
|
|
text: item.OfficialRating,
|
|
|
|
cssClass: 'mediaInfoOfficialRating'
|
|
|
|
});
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.Video3DFormat) {
|
|
|
|
miscInfo.push('3D');
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.MediaType === 'Photo' && item.Width && item.Height) {
|
|
|
|
miscInfo.push(`${item.Width}x${item.Height}`);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (options.container !== false && item.Type === 'Audio' && item.Container) {
|
|
|
|
miscInfo.push(item.Container);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
html += miscInfo.map(m => {
|
|
|
|
return getMediaInfoItem(m);
|
|
|
|
}).join('');
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (options.starRating !== false) {
|
|
|
|
html += getStarIconsHtml(item);
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.HasSubtitles && options.subtitles !== false) {
|
|
|
|
html += '<div class="mediaInfoItem mediaInfoText closedCaptionMediaInfoText">CC</div>';
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.CriticRating && options.criticRating !== false) {
|
|
|
|
if (item.CriticRating >= 60) {
|
|
|
|
html += `<div class="mediaInfoItem mediaInfoCriticRating mediaInfoCriticRatingFresh">${item.CriticRating}</div>`;
|
|
|
|
} else {
|
|
|
|
html += `<div class="mediaInfoItem mediaInfoCriticRating mediaInfoCriticRatingRotten">${item.CriticRating}</div>`;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (options.endsAt !== false) {
|
|
|
|
const endsAt = getEndsAt(item);
|
|
|
|
if (endsAt) {
|
|
|
|
html += getMediaInfoItem(endsAt, 'endsAt');
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
html += indicators.getMissingIndicator(item);
|
|
|
|
|
|
|
|
return html;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getEndsAt(item) {
|
|
|
|
if (item.MediaType === 'Video' && item.RunTimeTicks && !item.StartDate) {
|
|
|
|
let endDate = new Date().getTime() + (item.RunTimeTicks / 10000);
|
2018-10-23 01:05:09 +03:00
|
|
|
endDate = new Date(endDate);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-13 19:32:38 +03:00
|
|
|
const displayTime = datetime.getDisplayTime(endDate);
|
2019-02-03 02:41:16 +09:00
|
|
|
return globalize.translate('EndsAtValue', displayTime);
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
return null;
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
export function getEndsAtFromPosition(runtimeTicks, positionTicks, playbackRate, includeText) {
|
|
|
|
let endDate = new Date().getTime() + (1 / playbackRate) * ((runtimeTicks - (positionTicks || 0)) / 10000);
|
|
|
|
endDate = new Date(endDate);
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
const displayTime = datetime.getDisplayTime(endDate);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (includeText === false) {
|
|
|
|
return displayTime;
|
|
|
|
}
|
|
|
|
return globalize.translate('EndsAtValue', displayTime);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
function getMediaInfoItem(m, cssClass) {
|
|
|
|
cssClass = cssClass ? (`${cssClass} mediaInfoItem`) : 'mediaInfoItem';
|
|
|
|
let mediaInfoText = m;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (typeof (m) !== 'string' && typeof (m) !== 'number') {
|
|
|
|
if (m.html) {
|
|
|
|
return m.html;
|
|
|
|
}
|
|
|
|
mediaInfoText = m.text;
|
|
|
|
cssClass += ` ${m.cssClass}`;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
return `<div class="${cssClass}">${mediaInfoText}</div>`;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
function getStarIconsHtml(item) {
|
|
|
|
let html = '';
|
|
|
|
|
|
|
|
if (item.CommunityRating) {
|
|
|
|
html += '<div class="starRatingContainer mediaInfoItem">';
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
html += '<span class="material-icons starIcon star" aria-hidden="true"></span>';
|
|
|
|
html += item.CommunityRating.toFixed(1);
|
|
|
|
html += '</div>';
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
return html;
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
function dynamicEndTime(elem, item) {
|
|
|
|
const interval = setInterval(() => {
|
|
|
|
if (!document.body.contains(elem)) {
|
|
|
|
clearInterval(interval);
|
|
|
|
return;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
elem.innerHTML = getEndsAt(item);
|
|
|
|
}, 60000);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
export function fillPrimaryMediaInfo(elem, item, options) {
|
|
|
|
const html = getPrimaryMediaInfoHtml(item, options);
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
elem.innerHTML = html;
|
|
|
|
afterFill(elem, item, options);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function fillSecondaryMediaInfo(elem, item, options) {
|
|
|
|
const html = getSecondaryMediaInfoHtml(item, options);
|
|
|
|
|
|
|
|
elem.innerHTML = html;
|
|
|
|
afterFill(elem, item, options);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
function afterFill(elem, item, options) {
|
|
|
|
if (options.endsAt !== false) {
|
|
|
|
const endsAtElem = elem.querySelector('.endsAt');
|
|
|
|
if (endsAtElem) {
|
|
|
|
dynamicEndTime(endsAtElem, item);
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
const lnkChannel = elem.querySelector('.lnkChannel');
|
|
|
|
if (lnkChannel) {
|
|
|
|
lnkChannel.addEventListener('click', onChannelLinkClick);
|
|
|
|
}
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
function onChannelLinkClick(e) {
|
|
|
|
const channelId = this.getAttribute('data-id');
|
|
|
|
const serverId = this.getAttribute('data-serverid');
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
appRouter.showItem(channelId, serverId);
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
e.preventDefault();
|
|
|
|
return false;
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
export function getPrimaryMediaInfoHtml(item, options = {}) {
|
|
|
|
if (options.interactive === undefined) {
|
|
|
|
options.interactive = false;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
return getMediaInfoHtml(item, options);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
export function getSecondaryMediaInfoHtml(item, options) {
|
|
|
|
options = options || {};
|
|
|
|
if (options.interactive == null) {
|
|
|
|
options.interactive = false;
|
|
|
|
}
|
|
|
|
if (item.Type === 'Program') {
|
|
|
|
return getProgramInfoHtml(item, options);
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
return '';
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
export function getResolutionText(i) {
|
|
|
|
const width = i.Width;
|
|
|
|
const height = i.Height;
|
|
|
|
|
|
|
|
if (width && height) {
|
|
|
|
if (width >= 3800 || height >= 2000) {
|
|
|
|
return '4K';
|
|
|
|
}
|
|
|
|
if (width >= 2500 || height >= 1400) {
|
|
|
|
if (i.IsInterlaced) {
|
|
|
|
return '1440i';
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
return '1440p';
|
|
|
|
}
|
|
|
|
if (width >= 1800 || height >= 1000) {
|
|
|
|
if (i.IsInterlaced) {
|
|
|
|
return '1080i';
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
return '1080p';
|
|
|
|
}
|
|
|
|
if (width >= 1200 || height >= 700) {
|
|
|
|
if (i.IsInterlaced) {
|
|
|
|
return '720i';
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
return '720p';
|
|
|
|
}
|
|
|
|
if (width >= 700 || height >= 400) {
|
|
|
|
if (i.IsInterlaced) {
|
|
|
|
return '480i';
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
return '480p';
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
}
|
2023-04-19 01:56:05 -04:00
|
|
|
return null;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
function getAudioStreamForDisplay(item) {
|
|
|
|
if (!item.MediaSources) {
|
|
|
|
return null;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
const mediaSource = item.MediaSources[0];
|
|
|
|
if (!mediaSource) {
|
|
|
|
return null;
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
return (mediaSource.MediaStreams || []).filter(i => {
|
|
|
|
return i.Type === 'Audio' && (i.Index === mediaSource.DefaultAudioStreamIndex || mediaSource.DefaultAudioStreamIndex == null);
|
|
|
|
})[0];
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
export function getMediaInfoStats(item) {
|
|
|
|
const list = [];
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
const mediaSource = (item.MediaSources || [])[0] || {};
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
const videoStream = (mediaSource.MediaStreams || []).filter(i => {
|
|
|
|
return i.Type === 'Video';
|
|
|
|
})[0] || {};
|
|
|
|
const audioStream = getAudioStreamForDisplay(item) || {};
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.VideoType === 'Dvd') {
|
|
|
|
list.push({
|
|
|
|
type: 'mediainfo',
|
|
|
|
text: 'Dvd'
|
|
|
|
});
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.VideoType === 'BluRay') {
|
|
|
|
list.push({
|
|
|
|
type: 'mediainfo',
|
|
|
|
text: 'BluRay'
|
|
|
|
});
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
const resolutionText = getResolutionText(videoStream);
|
|
|
|
if (resolutionText) {
|
|
|
|
list.push({
|
|
|
|
type: 'mediainfo',
|
|
|
|
text: resolutionText
|
|
|
|
});
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (videoStream.Codec) {
|
|
|
|
list.push({
|
|
|
|
type: 'mediainfo',
|
|
|
|
text: videoStream.Codec
|
|
|
|
});
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
const channels = audioStream.Channels;
|
|
|
|
let channelText;
|
|
|
|
|
|
|
|
if (channels === 8) {
|
|
|
|
channelText = '7.1';
|
|
|
|
} else if (channels === 7) {
|
|
|
|
channelText = '6.1';
|
|
|
|
} else if (channels === 6) {
|
|
|
|
channelText = '5.1';
|
|
|
|
} else if (channels === 2) {
|
|
|
|
channelText = '2.0';
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (channelText) {
|
|
|
|
list.push({
|
|
|
|
type: 'mediainfo',
|
|
|
|
text: channelText
|
|
|
|
});
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
const audioCodec = (audioStream.Codec || '').toLowerCase();
|
|
|
|
|
|
|
|
if ((audioCodec === 'dca' || audioCodec === 'dts') && audioStream.Profile) {
|
|
|
|
list.push({
|
|
|
|
type: 'mediainfo',
|
|
|
|
text: audioStream.Profile
|
|
|
|
});
|
|
|
|
} else if (audioStream.Codec) {
|
|
|
|
list.push({
|
|
|
|
type: 'mediainfo',
|
|
|
|
text: audioStream.Codec
|
|
|
|
});
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
if (item.DateCreated && itemHelper.enableDateAddedDisplay(item)) {
|
|
|
|
const dateCreated = datetime.parseISO8601Date(item.DateCreated);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
list.push({
|
|
|
|
type: 'added',
|
|
|
|
text: globalize.translate('AddedOnValue', `${datetime.toLocaleDateString(dateCreated)} ${datetime.getDisplayTime(dateCreated)}`)
|
|
|
|
});
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2023-04-19 01:56:05 -04:00
|
|
|
return list;
|
|
|
|
}
|
2020-06-13 19:32:38 +03:00
|
|
|
|
|
|
|
export default {
|
|
|
|
getMediaInfoHtml: getPrimaryMediaInfoHtml,
|
|
|
|
getEndsAt: getEndsAt,
|
|
|
|
getEndsAtFromPosition: getEndsAtFromPosition,
|
|
|
|
getPrimaryMediaInfoHtml: getPrimaryMediaInfoHtml,
|
|
|
|
getSecondaryMediaInfoHtml: getSecondaryMediaInfoHtml,
|
|
|
|
fillPrimaryMediaInfo: fillPrimaryMediaInfo,
|
|
|
|
fillSecondaryMediaInfo: fillSecondaryMediaInfo,
|
|
|
|
getMediaInfoStats: getMediaInfoStats,
|
|
|
|
getResolutionText: getResolutionText
|
|
|
|
};
|