jellyfin-web/dashboard-ui/scripts/livetvguide.js

505 lines
14 KiB
JavaScript
Raw Normal View History

2014-10-15 20:26:39 -07:00
(function ($, document) {
2014-01-05 18:59:21 -07:00
2014-01-06 06:33:14 -07:00
// 30 mins
var cellCurationMinutes = 30;
2014-01-06 09:48:43 -07:00
var cellDurationMs = cellCurationMinutes * 60 * 1000;
var msPerDay = 86400000;
2014-01-06 06:33:14 -07:00
var currentDate;
2014-01-10 06:52:01 -07:00
2015-05-22 12:16:14 -07:00
var defaultChannels = 50;
var channelLimit = 1000;
2014-01-10 06:52:01 -07:00
var channelQuery = {
StartIndex: 0,
2015-05-22 12:16:14 -07:00
Limit: defaultChannels,
2015-04-11 18:38:38 -07:00
EnableFavoriteSorting: true
2014-01-10 06:52:01 -07:00
};
2015-05-22 12:16:14 -07:00
var channelsPromise;
2014-01-05 18:59:21 -07:00
function normalizeDateToTimeslot(date) {
2014-01-06 09:48:43 -07:00
var minutesOffset = date.getMinutes() - cellCurationMinutes;
2014-01-05 18:59:21 -07:00
if (minutesOffset >= 0) {
2014-01-06 09:48:43 -07:00
date.setHours(date.getHours(), cellCurationMinutes, 0, 0);
2014-01-05 18:59:21 -07:00
} else {
2014-01-06 09:48:43 -07:00
date.setHours(date.getHours(), 0, 0, 0);
2014-01-05 18:59:21 -07:00
}
return date;
}
2014-01-15 15:19:45 -07:00
2014-01-10 06:52:01 -07:00
function reloadChannels(page) {
channelsPromise = null;
reloadGuide(page);
}
2014-01-05 18:59:21 -07:00
function reloadGuide(page) {
2015-06-23 15:13:06 -07:00
Dashboard.showModalLoadingMsg();
2014-01-05 18:59:21 -07:00
2015-08-24 20:13:04 -07:00
channelQuery.UserId = Dashboard.getCurrentUserId();
2014-01-05 18:59:21 -07:00
2015-05-22 12:16:14 -07:00
channelQuery.Limit = Math.min(channelQuery.Limit || defaultChannels, channelLimit);
2015-08-24 20:13:04 -07:00
channelQuery.AddCurrentProgram = false;
2015-05-22 12:16:14 -07:00
2014-10-15 20:26:39 -07:00
channelsPromise = channelsPromise || ApiClient.getLiveTvChannels(channelQuery);
2014-01-05 18:59:21 -07:00
var date = currentDate;
var nextDay = new Date(date.getTime() + msPerDay - 1);
2015-06-26 20:27:38 -07:00
Logger.log(nextDay);
2014-01-15 15:19:45 -07:00
channelsPromise.done(function (channelsResult) {
2014-01-05 18:59:21 -07:00
2014-10-15 20:26:39 -07:00
ApiClient.getLiveTvPrograms({
2014-01-10 06:52:01 -07:00
UserId: Dashboard.getCurrentUserId(),
MaxStartDate: nextDay.toISOString(),
MinEndDate: date.toISOString(),
2014-01-15 15:19:45 -07:00
channelIds: channelsResult.Items.map(function (c) {
2014-01-10 06:52:01 -07:00
return c.Id;
2015-08-03 17:09:54 -07:00
}).join(','),
ImageTypeLimit: 1,
EnableImageTypes: "Primary"
2014-01-15 15:19:45 -07:00
}).done(function (programsResult) {
2014-01-10 06:52:01 -07:00
renderGuide(page, date, channelsResult.Items, programsResult.Items);
2015-06-23 15:13:06 -07:00
Dashboard.hideModalLoadingMsg();
2015-06-29 22:45:20 -07:00
LibraryBrowser.setLastRefreshed(page);
2014-01-10 06:52:01 -07:00
});
2014-01-15 15:19:45 -07:00
2015-06-18 11:29:44 -07:00
var channelPagingHtml = LibraryBrowser.getQueryPagingHtml({
startIndex: channelQuery.StartIndex,
limit: channelQuery.Limit,
totalRecordCount: channelsResult.TotalRecordCount,
2015-06-28 07:45:21 -07:00
updatePageSizeSetting: false,
showLimit: true
2015-06-18 11:29:44 -07:00
});
2015-06-28 07:45:21 -07:00
var channelPaging = page.querySelector('.channelPaging');
channelPaging.innerHTML = channelPagingHtml;
$(channelPaging).trigger('create');
2014-01-10 06:52:01 -07:00
2015-06-28 07:45:21 -07:00
Events.on(page.querySelector('.btnNextPage'), 'click', function () {
2014-01-10 06:52:01 -07:00
channelQuery.StartIndex += channelQuery.Limit;
reloadChannels(page);
});
2015-06-28 07:45:21 -07:00
Events.on(page.querySelector('.btnPreviousPage'), 'click', function () {
2014-01-10 06:52:01 -07:00
channelQuery.StartIndex -= channelQuery.Limit;
reloadChannels(page);
});
2015-04-14 08:26:02 -07:00
2015-06-28 07:45:21 -07:00
Events.on(page.querySelector('#selectPageSize'), 'change', function () {
2015-04-14 08:26:02 -07:00
channelQuery.Limit = parseInt(this.value);
channelQuery.StartIndex = 0;
reloadChannels(page);
});
2014-01-05 18:59:21 -07:00
});
}
function getTimeslotHeadersHtml(startDate, endDateTime) {
2014-01-05 18:59:21 -07:00
var html = '';
// clone
startDate = new Date(startDate.getTime());
2015-05-22 12:16:14 -07:00
html += '<div class="timeslotHeadersInner">';
2014-01-05 18:59:21 -07:00
while (startDate.getTime() < endDateTime) {
2014-01-05 18:59:21 -07:00
html += '<div class="timeslotHeader">';
2014-01-06 06:33:14 -07:00
html += '<div class="timeslotHeaderInner">';
2015-03-18 22:56:55 -07:00
2015-05-22 12:16:14 -07:00
html += LibraryBrowser.getDisplayTime(startDate);
2014-01-05 18:59:21 -07:00
html += '</div>';
2014-01-06 06:33:14 -07:00
html += '</div>';
2014-01-05 18:59:21 -07:00
// Add 30 mins
startDate.setTime(startDate.getTime() + cellDurationMs);
2014-01-05 18:59:21 -07:00
}
html += '</div>';
2014-01-05 18:59:21 -07:00
return html;
}
function parseDates(program) {
2014-01-06 06:33:14 -07:00
if (!program.StartDateLocal) {
try {
2014-01-06 06:33:14 -07:00
program.StartDateLocal = parseISO8601Date(program.StartDate, { toLocal: true });
2014-01-06 06:33:14 -07:00
} catch (err) {
2014-01-06 06:33:14 -07:00
}
}
2014-01-06 06:33:14 -07:00
if (!program.EndDateLocal) {
try {
2014-01-06 06:33:14 -07:00
program.EndDateLocal = parseISO8601Date(program.EndDate, { toLocal: true });
2014-01-06 06:33:14 -07:00
} catch (err) {
2014-01-06 06:33:14 -07:00
}
}
return null;
}
function getChannelProgramsHtml(page, date, channel, programs) {
2014-01-05 18:59:21 -07:00
var html = '';
var startMs = date.getTime();
var endMs = startMs + msPerDay - 1;
2014-01-06 06:33:14 -07:00
programs = programs.filter(function (curr) {
return curr.ChannelId == channel.Id;
});
2014-01-05 18:59:21 -07:00
2014-01-06 06:33:14 -07:00
html += '<div class="channelPrograms">';
2014-01-05 18:59:21 -07:00
for (var i = 0, length = programs.length; i < length; i++) {
2014-01-06 09:48:43 -07:00
var program = programs[i];
2014-01-06 06:33:14 -07:00
if (program.ChannelId != channel.Id) {
continue;
}
2014-01-06 06:33:14 -07:00
parseDates(program);
2014-01-06 06:33:14 -07:00
if (program.EndDateLocal.getTime() < startMs) {
continue;
2015-03-18 22:56:55 -07:00
}
2014-01-06 06:33:14 -07:00
if (program.StartDateLocal.getTime() > endMs) {
break;
2014-01-06 06:33:14 -07:00
}
var renderStartMs = Math.max(program.StartDateLocal.getTime(), startMs);
var startPercent = (program.StartDateLocal.getTime() - startMs) / msPerDay;
startPercent *= 100;
startPercent = Math.max(startPercent, 0);
2014-01-06 06:33:14 -07:00
var renderEndMs = Math.min(program.EndDateLocal.getTime(), endMs);
var endPercent = (renderEndMs - renderStartMs) / msPerDay;
endPercent *= 100;
2014-01-10 06:52:01 -07:00
html += '<div class="programCell" style="left:' + startPercent + '%;width:' + endPercent + '%;">';
2014-01-06 09:48:43 -07:00
var cssClass = "programCellInner";
2015-08-25 07:33:21 -07:00
var addAccent = true;
2014-01-06 06:33:14 -07:00
if (program.IsKids) {
cssClass += " childProgramInfo";
} else if (program.IsSports) {
cssClass += " sportsProgramInfo";
} else if (program.IsNews) {
cssClass += " newsProgramInfo";
} else if (program.IsMovie) {
cssClass += " movieProgramInfo";
}
else {
cssClass += " plainProgramInfo";
2015-08-25 07:33:21 -07:00
addAccent = false;
}
2014-01-06 06:33:14 -07:00
2015-07-28 20:42:03 -07:00
html += '<a href="itemdetails.html?id=' + program.Id + '" class="' + cssClass + '" data-programid="' + program.Id + '">';
2014-01-06 06:33:14 -07:00
html += '<div class="guideProgramName">';
html += program.Name;
html += '</div>';
2014-01-06 09:48:43 -07:00
html += '<div class="guideProgramTime">';
if (program.IsLive) {
html += '<span class="liveTvProgram">' + Globalize.translate('LabelLiveProgram') + '&nbsp;&nbsp;</span>';
}
else if (program.IsPremiere) {
html += '<span class="premiereTvProgram">' + Globalize.translate('LabelPremiereProgram') + '&nbsp;&nbsp;</span>';
}
else if (program.IsSeries && !program.IsRepeat) {
html += '<span class="newTvProgram">' + Globalize.translate('LabelNewProgram') + '&nbsp;&nbsp;</span>';
}
2014-01-06 09:48:43 -07:00
2015-05-22 12:16:14 -07:00
html += LibraryBrowser.getDisplayTime(program.StartDateLocal);
html += ' - ';
2015-05-22 12:16:14 -07:00
html += LibraryBrowser.getDisplayTime(program.EndDateLocal);
2014-01-06 06:33:14 -07:00
if (program.SeriesTimerId) {
html += '<div class="timerCircle seriesTimerCircle"></div>';
html += '<div class="timerCircle seriesTimerCircle"></div>';
html += '<div class="timerCircle seriesTimerCircle"></div>';
2014-01-06 06:33:14 -07:00
}
else if (program.TimerId) {
2014-01-06 06:33:14 -07:00
html += '<div class="timerCircle"></div>';
}
2014-01-06 06:33:14 -07:00
html += '</div>';
2015-08-25 07:33:21 -07:00
if (addAccent) {
html += '<div class="programAccent"></div>';
}
html += '</a>';
html += '</div>';
2014-01-06 06:33:14 -07:00
}
2014-01-05 18:59:21 -07:00
html += '</div>';
return html;
}
2014-01-06 06:33:14 -07:00
function renderPrograms(page, date, channels, programs) {
2014-01-05 18:59:21 -07:00
var html = [];
for (var i = 0, length = channels.length; i < length; i++) {
2014-01-06 06:33:14 -07:00
html.push(getChannelProgramsHtml(page, date, channels[i], programs));
2014-01-05 18:59:21 -07:00
}
2015-06-28 07:45:21 -07:00
var programGrid = page.querySelector('.programGrid');
programGrid.innerHTML = html.join('');
$(programGrid).scrollTop(0).scrollLeft(0)
.createGuideHoverMenu('.programCellInner');
2014-01-06 06:33:14 -07:00
}
function renderChannelHeaders(page, channels) {
var html = '';
for (var i = 0, length = channels.length; i < length; i++) {
var channel = channels[i];
html += '<div class="channelHeaderCellContainer">';
2014-01-06 09:48:43 -07:00
html += '<div class="channelHeaderCell">';
2015-08-17 21:22:45 -07:00
html += '<a class="channelHeaderCellInner" href="itemdetails.html?id=' + channel.Id + '">';
2014-01-06 11:25:33 -07:00
2015-07-23 07:58:27 -07:00
var hasChannelImage = channel.ImageTags.Primary;
var cssClass = hasChannelImage ? 'guideChannelInfo guideChannelInfoWithImage' : 'guideChannelInfo';
2014-01-06 11:25:33 -07:00
2015-07-23 07:58:27 -07:00
html += '<div class="' + cssClass + '">' + channel.Name + '<br/>' + channel.Number + '</div>';
if (hasChannelImage) {
2014-01-06 11:25:33 -07:00
var url = ApiClient.getScaledImageUrl(channel.Id, {
maxHeight: 35,
maxWidth: 60,
2014-01-06 11:25:33 -07:00
tag: channel.ImageTags.Primary,
type: "Primary"
});
2015-09-24 22:15:29 -07:00
html += '<div class="guideChannelImage lazy" data-src="' + url + '"></div>';
2014-01-06 11:25:33 -07:00
}
2014-01-06 09:48:43 -07:00
html += '</a>';
2014-01-06 06:33:14 -07:00
html += '</div>';
html += '</div>';
}
2015-09-24 22:15:29 -07:00
var channelList = page.querySelector('.channelList');
channelList.innerHTML = html;
ImageLoader.lazyChildren(channelList);
2014-01-05 18:59:21 -07:00
}
function renderGuide(page, date, channels, programs) {
2014-01-06 06:33:14 -07:00
renderChannelHeaders(page, channels);
var startDate = date;
var endDate = new Date(startDate.getTime() + msPerDay);
2015-06-28 07:45:21 -07:00
page.querySelector('.timeslotHeaders').innerHTML = getTimeslotHeadersHtml(startDate, endDate);
2014-01-06 06:33:14 -07:00
renderPrograms(page, date, channels, programs);
}
2015-04-12 09:46:29 -07:00
var gridScrolling = false;
var headersScrolling = false;
2014-01-06 06:33:14 -07:00
function onProgramGridScroll(page, elem) {
2015-04-12 09:46:29 -07:00
if (!headersScrolling) {
gridScrolling = true;
2014-01-06 06:33:14 -07:00
2015-06-28 07:45:21 -07:00
$(page.querySelector('.timeslotHeaders')).scrollLeft($(elem).scrollLeft());
2015-04-12 09:46:29 -07:00
gridScrolling = false;
}
}
function onTimeslotHeadersScroll(page, elem) {
if (!gridScrolling) {
headersScrolling = true;
2015-06-28 07:45:21 -07:00
$(page.querySelector('.programGrid')).scrollLeft($(elem).scrollLeft());
2015-04-12 09:46:29 -07:00
headersScrolling = false;
}
2014-01-05 18:59:21 -07:00
}
function changeDate(page, date) {
currentDate = normalizeDateToTimeslot(date);
reloadGuide(page);
2015-04-12 09:46:29 -07:00
var text = LibraryBrowser.getFutureDateText(date);
text = '<span class="currentDay">' + text.replace(' ', ' </span>');
2015-06-28 07:45:21 -07:00
page.querySelector('.currentDate').innerHTML = text;
}
2015-06-19 09:36:51 -07:00
var dateOptions = [];
function setDateRange(page, guideInfo) {
var today = new Date();
today.setHours(today.getHours(), 0, 0, 0);
var start = parseISO8601Date(guideInfo.StartDate, { toLocal: true });
var end = parseISO8601Date(guideInfo.EndDate, { toLocal: true });
start.setHours(0, 0, 0, 0);
end.setHours(0, 0, 0, 0);
2014-08-16 22:38:13 -07:00
if (start.getTime() >= end.getTime()) {
end.setDate(start.getDate() + 1);
}
start = new Date(Math.max(today, start));
2015-06-19 09:36:51 -07:00
dateOptions = [];
while (start <= end) {
2015-06-19 09:36:51 -07:00
dateOptions.push({
name: LibraryBrowser.getFutureDateText(start),
2015-06-19 15:01:47 -07:00
id: start.getTime(),
ironIcon: 'today'
2015-06-19 09:36:51 -07:00
});
start.setDate(start.getDate() + 1);
start.setHours(0, 0, 0, 0);
}
var date = new Date();
2014-08-16 22:38:13 -07:00
2015-06-19 09:36:51 -07:00
if (currentDate) {
date.setTime(currentDate.getTime());
2014-08-16 22:38:13 -07:00
}
changeDate(page, date);
}
2015-05-22 12:22:26 -07:00
function reloadPageAfterValidation(page, limit) {
channelLimit = limit;
ApiClient.getLiveTvGuideInfo().done(function (guideInfo) {
setDateRange(page, guideInfo);
});
}
function reloadPage(page) {
2015-05-26 10:48:05 -07:00
$('.guideRequiresUnlock', page).hide();
2015-05-22 12:22:26 -07:00
RegistrationServices.validateFeature('livetv').done(function () {
2015-06-23 15:13:06 -07:00
Dashboard.showModalLoadingMsg();
2015-05-22 12:22:26 -07:00
reloadPageAfterValidation(page, 1000);
}).fail(function () {
2015-05-26 10:48:05 -07:00
2015-06-23 15:13:06 -07:00
Dashboard.showModalLoadingMsg();
2015-05-26 10:48:05 -07:00
var limit = 5;
$('.guideRequiresUnlock', page).show();
$('.unlockText', page).html(Globalize.translate('MessageLiveTvGuideRequiresUnlock', limit));
reloadPageAfterValidation(page, limit);
2015-05-22 12:22:26 -07:00
});
}
2015-06-19 09:36:51 -07:00
function selectDate(page) {
2014-01-06 06:33:14 -07:00
2015-06-28 07:45:21 -07:00
require(['actionsheet'], function () {
2015-06-19 09:36:51 -07:00
ActionSheetElement.show({
items: dateOptions,
showCancel: true,
title: Globalize.translate('HeaderSelectDate'),
callback: function (id) {
2014-01-06 06:33:14 -07:00
2015-06-19 09:36:51 -07:00
var date = new Date();
date.setTime(parseInt(id));
changeDate(page, date);
}
});
2014-01-06 06:33:14 -07:00
});
2015-06-19 09:36:51 -07:00
}
2014-01-06 06:33:14 -07:00
2015-08-18 08:52:48 -07:00
window.LiveTvPage.initGuideTab = function (page, tabContent) {
2014-01-05 18:59:21 -07:00
2015-08-18 08:52:48 -07:00
Events.on(tabContent.querySelector('.programGrid'), 'scroll', function () {
2015-08-18 08:52:48 -07:00
onProgramGridScroll(tabContent, this);
});
2014-01-05 18:59:21 -07:00
2015-04-12 09:46:29 -07:00
if ($.browser.mobile) {
2015-08-18 08:52:48 -07:00
tabContent.querySelector('.tvGuide').classList.add('mobileGuide');
2015-04-12 09:46:29 -07:00
} else {
2015-08-18 08:52:48 -07:00
tabContent.querySelector('.tvGuide').classList.remove('mobileGuide');
2015-04-12 09:46:29 -07:00
2015-08-18 08:52:48 -07:00
Events.on(tabContent.querySelector('.timeslotHeaders'), 'scroll', function () {
2015-04-12 09:46:29 -07:00
2015-08-18 08:52:48 -07:00
onTimeslotHeadersScroll(tabContent, this);
2015-04-12 09:46:29 -07:00
});
}
2015-05-06 20:11:51 -07:00
if (AppInfo.enableHeadRoom) {
2015-05-08 20:48:43 -07:00
requirejs(["thirdparty/headroom"], function () {
2015-05-04 07:35:38 -07:00
2015-06-28 07:45:21 -07:00
// construct an instance of Headroom, passing the element
2015-08-18 08:52:48 -07:00
var headroom = new Headroom(tabContent.querySelector('.tvGuideHeader'));
2015-06-28 07:45:21 -07:00
// initialise
headroom.init();
2015-05-06 20:11:51 -07:00
});
}
2015-05-04 07:35:38 -07:00
2015-08-18 08:52:48 -07:00
$('.btnUnlockGuide', tabContent).on('click', function () {
2015-05-26 10:48:05 -07:00
2015-08-18 08:52:48 -07:00
reloadPage(tabContent);
2015-05-26 10:48:05 -07:00
});
2015-08-18 08:52:48 -07:00
$('.btnSelectDate', tabContent).on('click', function () {
2015-06-19 09:36:51 -07:00
2015-08-18 08:52:48 -07:00
selectDate(tabContent);
2015-06-19 09:36:51 -07:00
});
2015-08-18 08:52:48 -07:00
};
2015-06-19 09:36:51 -07:00
2015-08-18 08:52:48 -07:00
window.LiveTvPage.renderGuideTab = function (page, tabContent) {
2015-08-02 16:47:31 -07:00
2015-08-18 08:52:48 -07:00
if (LibraryBrowser.needsRefresh(tabContent)) {
reloadPage(tabContent);
}
};
2014-01-05 18:59:21 -07:00
2015-05-22 12:16:14 -07:00
})(jQuery, document);