1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

live tv guide improvements

This commit is contained in:
Luke Pulverenti 2015-04-12 12:46:29 -04:00
parent f41b336e87
commit f4866f7344
10 changed files with 1095 additions and 173 deletions

View file

@ -12,7 +12,7 @@
}
.detailSectionHeader + .tvProgram {
border-top: 1px solid #444;
border-top: 1px solid #404040;
margin-top: 1px;
}
@ -25,7 +25,7 @@
top: 0;
left: 0;
bottom: 0;
border-bottom: 1px solid #444;
border-bottom: 1px solid #404040;
}
.tvProgramTimeSlotInner {
@ -35,12 +35,12 @@
.tvProgramInfo {
vertical-align: middle;
padding: .5em .5em;
border-bottom: 1px solid #444;
border-bottom: 1px solid #404040;
}
.tvProgramTimeSlot + .tvProgramInfo {
margin-left: 80px;
border-left: 1px solid #444;
border-left: 1px solid #404040;
}
.tvProgramCurrentTimeSlot {
@ -137,9 +137,23 @@
}
.timeslotHeaders {
overflow-y: hidden;
overflow-x: hidden;
white-space: nowrap;
overflow-x: scroll;
}
.mobileGuide .timeslotHeaders {
overflow-x: hidden;
}
.programContainer {
white-space: nowrap;
position: relative;
margin: 0 auto;
margin-top: 44px;
}
.mobileGuide .programContainer {
margin-top: 30px;
}
.channelPrograms {
@ -157,8 +171,8 @@
.timeslotCell {
display: inline-block;
border-bottom: 1px solid #444;
border-left: 1px solid #444;
border-bottom: 1px solid #404040;
border-left: 1px solid #404040;
border-collapse: collapse;
position: relative;
}
@ -166,9 +180,8 @@
.channelHeaderCell, .channelTimeslotHeader {
overflow: hidden;
text-overflow: ellipsis;
border-bottom: 1px solid #444;
border-left: 1px solid #444;
border-right: 1px solid #444;
border-bottom: 1px solid #404040;
border-right: 1px solid #404040;
width: 189px;
}
@ -183,7 +196,7 @@
}
.timeslotHeader, .channelTimeslotHeader {
height: 28px;
height: 34px;
}
.channelHeaderCellInner {
@ -200,16 +213,12 @@
}
.channelList {
overflow-y: hidden;
overflow-x: scroll;
float: left;
border-bottom: 4px solid #3B3B3B;
}
.programGrid {
overflow-y: scroll;
overflow-x: scroll;
padding-bottom: 4px;
overflow-x: scroll;
}
.programGrid, .timeslotHeaders {
@ -271,81 +280,7 @@
top: 7px;
}
.channelList, .programGrid {
height: 220px;
}
@media (min-height: 500px) {
.channelList, .programGrid {
height: 360px;
}
}
@media (min-height: 600px) {
.channelList, .programGrid {
height: 400px;
}
}
@media (min-height: 700px) {
.channelList, .programGrid {
height: 500px;
}
}
@media (min-height: 800px) {
.channelList, .programGrid {
height: 600px;
}
}
@media (min-height: 900px) {
.channelList, .programGrid {
height: 700px;
}
}
@media (min-height: 1000px) {
.channelList, .programGrid {
height: 800px;
}
}
@media (min-height: 1100px) {
.channelList, .programGrid {
height: 900px;
}
}
@media (min-height: 1200px) {
.channelList, .programGrid {
height: 1000px;
}
}
@media (min-height: 1300px) {
.channelList, .programGrid {
height: 1100px;
}
}
@media (min-height: 1400px) {
.channelList, .programGrid {
height: 1200px;
}
}
@media (max-width: 800px) {
@media (max-width: 600px) {
.guideChannelImage {
display: none;
@ -362,4 +297,16 @@
.programGrid, .timeslotHeaders {
margin-left: 90px;
}
.currentDate {
font-size: 11px;
}
.currentDay {
display: none;
}
}
.channelList, .programGrid {
height: auto !important;
}

View file

@ -26,6 +26,24 @@
<div class="ehsContent homeEhsContent">
<div class="sections"></div>
</div>
</div>
<div data-role="popup" class="popupConfigureViews" data-overlay-theme="b" data-theme="a" data-dismissible="false" data-positionto="window">
<div class="ui-bar-a" style="text-align: center; padding: 0 20px; position: relative;">
<h3 class="identificationHeader">${HeaderMyPreferences}</h3>
</div>
<div data-role="content" style="max-width:600px;">
<h1>${HeaderWelcomeExclamation}</h1>
<p>${MyPreferencesWelcomeMessage1}</p>
<p style="margin:1.5em 0 2em;">${MyPreferencesWelcomeMessage2}</p>
<a href="#" data-role="button" data-icon="action" data-theme="b" data-mini="true" class="btnMyPreferences">${ButtonMyPreferencesWelcomeYes}</a>
<a href="#" data-rel="back" data-role="button" data-icon="delete" data-mini="true">${ButtonMyPreferencesWelcomeNo}</a>
<div class="fieldDescription" style="margin-top:1em;">${ToAccessPreferencesHelp}</div>
</div>
</div>
</div>
</body>

View file

@ -15,27 +15,31 @@
</div>
<div data-role="content" style="padding-top: 5px;padding-left:0!important;padding-right:0!important;">
<div>
<div class="viewSettings">
<select id="selectDate" data-mini="true" data-inline="true">
</select>
<div style="display: inline-block; vertical-align: middle;" class="channelPaging">
<div class="tvGuide">
<div style="white-space: nowrap;position:fixed;top:99px;left:0;z-index:100; max-width: 100%;">
<div class="channelTimeslotHeader">
<div style="padding-top:4px;">
<a href="#popupConfig" data-rel="popup" class="accentButton" style="display:block;padding-left:5px;"><i class="fa fa-calendar"></i><span class="currentDate"></span></a>
</div>
</div>
<div>
<div style="position: relative; margin: 0 auto; display: inline-block; text-align: left; max-width: 100%;">
<div style="white-space: nowrap;">
<div class="channelTimeslotHeader">&nbsp;</div>
<div class="timeslotHeaders"></div>
</div>
<div style="white-space: nowrap;">
<div class="programContainer">
<div class="channelList"></div>
<div class="programGrid"></div>
</div>
<div class="channelPaging"></div>
</div>
<div data-role="popup" id="popupConfig" data-theme="b">
<div class="ui-bar-a" style="text-align: center; padding: 0 20px; position: relative;">
<h3 class="identificationHeader" style="margin:.5em 0;">${HeaderSelectDate}</h3>
</div>
<div data-role="content">
<select id="selectDate" data-mini="true" data-inline="true"></select>
<a href="#" data-rel="back" data-role="button" data-mini="true" data-icon="delete">${ButtonCancel}</a>
</div>
</div>
<div data-role="popup" class="popupLoading" data-overlay-theme="b" data-theme="b" data-dismissible="false" style="max-width: 250px;" data-history="false">

View file

@ -4,7 +4,7 @@
<title>Emby</title>
</head>
<body>
<div id="liveTvSuggestedPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}">
<div id="liveTvSuggestedPage" data-role="page" class="page libraryPage liveTvPage backdropPage globalBackdropPage" data-contextname="${HeaderLiveTv}" data-backdroptype="series,movie">
<div class="libraryViewNav">
<a href="#" class="ui-btn-active">${TabSuggestions}</a>
<a href="livetvguide.html">${TabGuide}</a>

View file

@ -59,7 +59,7 @@
return deferred.promise();
}
function showBackdrop(type) {
function showBackdrop(type, parentId) {
var apiClient = ConnectionManager.currentApiClient();
@ -67,9 +67,7 @@
return;
}
getBackdropItemIds(apiClient, Dashboard.getCurrentUserId(),
type,
LibraryMenu.getTopParentId()).done(function (images) {
getBackdropItemIds(apiClient, Dashboard.getCurrentUserId(), type, parentId).done(function (images) {
if (images.length) {
@ -154,17 +152,21 @@
var page = this;
if (!$(page).hasClass('staticBackdropPage')) {
var $page = $(page);
if ($(page).hasClass('backdropPage')) {
if (!$page.hasClass('staticBackdropPage')) {
if ($page.hasClass('backdropPage')) {
if (enabled()) {
var type = page.getAttribute('data-backdroptype');
showBackdrop(type);
var parentId = $page.hasClass('globalBackdropPage') ? '' : LibraryMenu.getTopParentId();
showBackdrop(type, parentId);
} else {
$(page).removeClass('backdropPage');
$page.removeClass('backdropPage');
clearBackdrop();
}
} else {

View file

@ -96,7 +96,7 @@
function loadlibraryButtons(elem, userId, index) {
getUserViews(userId).done(function (items) {
return getUserViews(userId).done(function (items) {
var html = '<br/>';
@ -172,7 +172,7 @@
UserId: userId
};
ApiClient.getJSON(ApiClient.getUrl("Channels/Items/Latest", options)).done(function (result) {
return ApiClient.getJSON(ApiClient.getUrl("Channels/Items/Latest", options)).done(function (result) {
var html = '';
@ -203,7 +203,7 @@
$(elem).removeClass('hiddenSectionOnMobile');
}
getUserViews(user.Id).done(function (items) {
return getUserViews(user.Id).done(function (items) {
var html = '';
@ -259,7 +259,7 @@
EnableImageTypes: "Primary,Backdrop,Banner,Thumb"
};
ApiClient.getItems(userId, options).done(function (result) {
return ApiClient.getItems(userId, options).done(function (result) {
var html = '';
@ -307,7 +307,7 @@
SupportsLatestItems: true
});
ApiClient.getJSON(ApiClient.getUrl("Channels", options)).done(function (result) {
return ApiClient.getJSON(ApiClient.getUrl("Channels", options)).done(function (result) {
var channels = result.Items;
@ -375,7 +375,7 @@
function loadLatestLiveTvRecordings(elem, userId, index) {
ApiClient.getLiveTvRecordings({
return ApiClient.getLiveTvRecordings({
userId: userId,
limit: 5,
@ -459,36 +459,40 @@
var elem = $('.section' + index, page);
if (section == 'latestmedia') {
Sections.loadRecentlyAdded(elem, user);
return Sections.loadRecentlyAdded(elem, user);
}
else if (section == 'librarytiles') {
Sections.loadLibraryTiles(elem, user, 'backdrop', index, false, showLibraryTileNames);
return Sections.loadLibraryTiles(elem, user, 'backdrop', index, false, showLibraryTileNames);
}
else if (section == 'smalllibrarytiles') {
Sections.loadLibraryTiles(elem, user, 'homePageSmallBackdrop', index, false, showLibraryTileNames);
return Sections.loadLibraryTiles(elem, user, 'homePageSmallBackdrop', index, false, showLibraryTileNames);
}
else if (section == 'smalllibrarytiles-automobile') {
Sections.loadLibraryTiles(elem, user, 'homePageSmallBackdrop', index, true, showLibraryTileNames);
return Sections.loadLibraryTiles(elem, user, 'homePageSmallBackdrop', index, true, showLibraryTileNames);
}
else if (section == 'librarytiles-automobile') {
Sections.loadLibraryTiles(elem, user, 'backdrop', index, true, showLibraryTileNames);
return Sections.loadLibraryTiles(elem, user, 'backdrop', index, true, showLibraryTileNames);
}
else if (section == 'librarybuttons') {
Sections.loadlibraryButtons(elem, userId, index);
return Sections.loadlibraryButtons(elem, userId, index);
}
else if (section == 'resume') {
Sections.loadResume(elem, userId);
return Sections.loadResume(elem, userId);
}
else if (section == 'latesttvrecordings') {
Sections.loadLatestLiveTvRecordings(elem, userId);
return Sections.loadLatestLiveTvRecordings(elem, userId);
}
else if (section == 'latestchannelmedia') {
Sections.loadLatestChannelMedia(elem, userId);
return Sections.loadLatestChannelMedia(elem, userId);
} else {
elem.empty();
var deferred = DeferredBuilder.Deferred();
deferred.resolve();
return deferred.promise();
}
}
@ -509,13 +513,17 @@
elem.html(html);
}
var promises = [];
for (i = 0, length = sectionCount; i < length; i++) {
loadSection(page, user, displayPreferences, i);
}
promises.push(loadSection(page, user, displayPreferences, i));
}
var homePageDismissValue = '5';
return $.when(promises);
}
var homePageDismissValue = '12';
var homePageTourKey = 'homePageTour';
function dismissWelcome(page, userId) {
@ -570,11 +578,25 @@
afterClose: function () {
dismissWelcome(page, userId);
$('.welcomeMessage', page).hide();
loadConfigureViewsWelcomeMessage(page, userId);
},
hideBarsDelay: 30000
});
}
function loadConfigureViewsWelcomeMessage(page, userId) {
$('.btnMyPreferences', page).attr('href', 'mypreferencesdisplay.html?userId=' + userId);
// Need the timeout because previous methods in the chain have popups that will be in the act of closing
setTimeout(function () {
$('.popupConfigureViews', page).popup('open');
}, 500);
}
$(document).on('pageinit', "#indexPage", function () {
var page = this;
@ -593,11 +615,12 @@
ApiClient.getDisplayPreferences('home', userId, 'webclient').done(function (result) {
showWelcomeIfNeeded(page, result);
Dashboard.getCurrentUser().done(function (user) {
loadSections(page, user, result);
loadSections(page, user, result).done(function () {
showWelcomeIfNeeded(page, result);
});
});
});

View file

@ -12,7 +12,7 @@
var channelQuery = {
StartIndex: 0,
Limit: 20,
Limit: 50,
EnableFavoriteSorting: true
};
var channelsPromise;
@ -90,12 +90,6 @@
channelQuery.StartIndex -= channelQuery.Limit;
reloadChannels(page);
});
$('.selectPageSize', page).on('change', function () {
channelQuery.Limit = parseInt(this.value);
channelQuery.StartIndex = 0;
reloadChannels(page);
});
});
}
@ -269,13 +263,13 @@
html += '<div class="guideProgramTime">';
if (program.IsLive) {
html += '<span class="liveTvProgram">'+Globalize.translate('LabelLiveProgram')+'&nbsp;&nbsp;</span>';
html += '<span class="liveTvProgram">' + Globalize.translate('LabelLiveProgram') + '&nbsp;&nbsp;</span>';
}
else if (program.IsPremiere) {
html += '<span class="premiereTvProgram">'+Globalize.translate('LabelPremiereProgram')+'&nbsp;&nbsp;</span>';
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>';
html += '<span class="newTvProgram">' + Globalize.translate('LabelNewProgram') + '&nbsp;&nbsp;</span>';
}
html += LiveTvHelpers.getDisplayTime(program.StartDateLocal);
@ -365,12 +359,27 @@
renderPrograms(page, date, channels, programs);
}
var gridScrolling = false;
var headersScrolling = false;
function onProgramGridScroll(page, elem) {
if (!headersScrolling) {
gridScrolling = true;
var grid = $(elem);
grid.prev().scrollTop(grid.scrollTop());
$('.timeslotHeaders', page).scrollLeft(grid.scrollLeft());
gridScrolling = false;
}
}
function onTimeslotHeadersScroll(page, elem) {
if (!gridScrolling) {
headersScrolling = true;
elem = $(elem);
$('.programGrid', page).scrollLeft(elem.scrollLeft());
headersScrolling = false;
}
}
function changeDate(page, date) {
@ -385,6 +394,10 @@
gridLocalEndDateMs = clone.getTime() - 1;
reloadGuide(page);
var text = LibraryBrowser.getFutureDateText(date);
text = '<span class="currentDay">' + text.replace(' ', ' </span>');
$('.currentDate', page).html(text);
}
function setDateRange(page, guideInfo) {
@ -446,9 +459,21 @@
date.setTime(parseInt(this.value));
changeDate(page, date);
$('#popupConfig', page).popup('close');
});
if ($.browser.mobile) {
$('.tvGuide', page).addClass('mobileGuide');
} else {
$('.tvGuide', page).removeClass('mobileGuide');
$('.timeslotHeaders', page).on('scroll', function () {
onTimeslotHeadersScroll(page, this);
});
}
}).on('pagebeforeshow', "#liveTvGuidePage", function () {
var page = this;

View file

@ -118,10 +118,10 @@
SortOrder: "Ascending",
IncludeItemTypes: "Playlist",
Recursive: true,
ParentId: parentId,
Fields: "PrimaryImageAspectRatio,SortName,CumulativeRunTimeTicks,CanDelete,SyncInfo",
StartIndex: 0,
Limit: 9
Limit: 9,
MediaTypes: "Audio"
};
ApiClient.getItems(Dashboard.getCurrentUserId(), options).done(function (result) {

View file

@ -4,7 +4,7 @@
<title>Emby</title>
</head>
<body>
<div id="songsPage" data-role="page" class="page libraryPage">
<div id="songsPage" data-role="page" class="page libraryPage backdropPage" data-backdroptype="musicartist">
<div class="libraryViewNav scopedLibraryViewNav">
<a href="musicrecommended.html">${TabSuggestions}</a>
<a href="#" class="ui-btn-active">${TabSongs}</a>

File diff suppressed because one or more lines are too long