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

add tv guide hover menus

This commit is contained in:
Luke Pulverenti 2014-01-15 17:19:45 -05:00
parent 817effb7d8
commit e768e496ed
11 changed files with 267 additions and 58 deletions

View file

@ -156,10 +156,8 @@
} }
.detailButtonsContainer { .detailButtonsContainer {
padding: .5em 0 .5em; padding: .35em 0 .35em;
text-align: center; text-align: center;
border-top: 1px solid #333;
border-bottom: 1px solid #333;
} }
.viewSettings { .viewSettings {
@ -272,18 +270,19 @@
padding: 2px 4px; padding: 2px 4px;
position: relative; position: relative;
top: -1px; top: -1px;
border-radius: 2px;
} }
.metascorehigh { .metascorehigh {
background-color: rgba(102, 204, 51, .65); background-color: rgba(102, 204, 51, .7);
} }
.metascoremid { .metascoremid {
background-color: rgba(255, 204, 51, .65); background-color: rgba(255, 204, 51, .7);
} }
.metascorelow { .metascorelow {
background-color: rgba(240, 0, 0, .65); background-color: rgba(240, 0, 0, .7);
} }
.criticRating + .metascore, .starRatingValue + .metascore { .criticRating + .metascore, .starRatingValue + .metascore {
@ -771,7 +770,7 @@ a.itemTag:hover {
} }
.primaryDetailPageContent { .primaryDetailPageContent {
max-width: 900px; max-width: 850px;
} }
} }
@ -972,26 +971,12 @@ a.itemTag:hover {
top: 3px; top: 3px;
} }
.userDataIcons .itemProgressText {
vertical-align: top;
margin-right: 1.5em;
}
.tileItem .itemProgressBar { .tileItem .itemProgressBar {
top: 2px; top: 2px;
width: 40px; width: 40px;
margin-right: 1em; margin-right: 1em;
} }
.itemProgressText {
color: #ddd;
vertical-align: middle;
}
.tileItem .itemProgressText {
display: none;
}
.timelineHeader { .timelineHeader {
margin-bottom: .25em; margin-bottom: .25em;
} }

View file

@ -49,7 +49,7 @@
.nowPlayingMediaInfo { .nowPlayingMediaInfo {
display: none; display: inline-block;
} }
.nowPlayingText { .nowPlayingText {
@ -60,9 +60,9 @@
font-weight: normal; font-weight: normal;
} }
@media all and (min-width: 650px) { @media all and (max-width: 650px) {
.nowPlayingMediaInfo { .nowPlayingMediaInfo {
display: inline-block; display: none;
} }
} }
@ -164,19 +164,36 @@ input[type="range"]::-ms-fill-upper {
display: none; /* display and visibility only */ display: none; /* display and visibility only */
} }
@media all and (max-width: 800px) {
.volumeButton, .volumeSliderContainer, .muteButton, .unmuteButton, .nowPlayingMediaInfo {
display: none!important;
}
}
@media all and (max-width: 600px) { @media all and (max-width: 600px) {
.volumeButton, .volumeSliderContainer, .nowPlayingText, .chaptersButton, .audioTracksButton { .chaptersButton, .audioTracksButton, .sendMediaButton {
display: none!important; display: none!important;
} }
.positionSliderContainer { .positionSliderContainer, .currentTime {
width: 50px; top: 0!important;
position: relative!important;
} }
} }
@media all and (max-width: 750px) { @media all and (max-width: 500px) {
.positionSliderContainer { .positionSliderContainer {
width: 50px; width: 80px;
}
.previousTrackButton, .nextTrackButton {
display: none!important;
}
}
@media all and (max-width: 400px) {
.playlistButton {
display: none!important;
} }
} }

View file

@ -7,4 +7,5 @@
#pluginUpdatesForm td + td { #pluginUpdatesForm td + td {
text-align: center; text-align: center;
} }

View file

@ -31,7 +31,7 @@
</div> </div>
</div> </div>
</div> </div>
<div data-role="popup" id="popupEnterText" class="popup"> <div data-role="popup" data-transition="slidefade" id="popupEnterText" class="popup">
<div class="ui-bar-a" style="text-align: center; padding: 0 20px;"> <div class="ui-bar-a" style="text-align: center; padding: 0 20px;">
<h3>Rename</h3> <h3>Rename</h3>

View file

@ -93,7 +93,7 @@
options.header = options.header || "Select Media Path"; options.header = options.header || "Select Media Path";
options.instruction = options.instruction || "Any path will do, but for optimal playback of bluray, dvd folders, and games, <b>network paths (UNC)</b> are recommended."; options.instruction = options.instruction || "Any path will do, but for optimal playback of bluray, dvd folders, and games, <b>network paths (UNC)</b> are recommended.";
var html = '<div data-role="popup" id="popupDirectoryPicker" class="popup" style="min-width:65%;">'; var html = '<div data-transition="fade" data-role="popup" id="popupDirectoryPicker" class="popup" style="min-width:65%;">';
html += '<div class="ui-bar-a" style="text-align: center; padding: 0 20px;">'; html += '<div class="ui-bar-a" style="text-align: center; padding: 0 20px;">';
html += '<h3>' + options.header + '</h3>'; html += '<h3>' + options.header + '</h3>';

View file

@ -2201,7 +2201,7 @@
for (var i = 0, length = genres.length; i < length; i++) { for (var i = 0, length = genres.length; i < length; i++) {
if (i > 0) { if (i > 0) {
html += '&nbsp;&nbsp;/&nbsp;&nbsp;'; html += '<span>&nbsp;&nbsp;/&nbsp;&nbsp;</span>';
} }
var param = item.Type == "Audio" || item.Type == "MusicArtist" || item.Type == "MusicAlbum" ? "musicgenre" : "genre"; var param = item.Type == "Audio" || item.Type == "MusicArtist" || item.Type == "MusicAlbum" ? "musicgenre" : "genre";

View file

@ -53,7 +53,7 @@
cssClass += " movieProgramInfo"; cssClass += " movieProgramInfo";
} }
html += '<div class="' + cssClass + '">'; html += '<div data-programid="' + program.Id + '" class="' + cssClass + '">';
var name = program.Name; var name = program.Name;
@ -101,7 +101,7 @@
html += '</a>'; html += '</a>';
} }
$('#programList', page).html(html).trigger('create'); $('#programList', page).html(html).trigger('create').createGuideHoverMenu('.tvProgramInfo');
} }
function loadPrograms(page) { function loadPrograms(page) {

View file

@ -214,6 +214,7 @@
var href; var href;
var cssClass = "timeslotCellInner"; var cssClass = "timeslotCellInner";
var style; var style;
var dataProgramId;
if (program) { if (program) {
if (program.IsKids) { if (program.IsKids) {
@ -241,13 +242,15 @@
} else { } else {
style = ''; style = '';
} }
dataProgramId = ' data-programid="' + program.Id + '"';
} else { } else {
cellTagName = "div"; cellTagName = "div";
href = ''; href = '';
style = ''; style = '';
dataProgramId = '';
} }
html += '<' + cellTagName + ' class="' + cssClass + '"' + href + style + '>'; html += '<' + cellTagName + dataProgramId + ' class="' + cssClass + '"' + href + style + '>';
if (program) { if (program) {
@ -311,7 +314,8 @@
html.push(getChannelProgramsHtml(page, date, channels[i], programs)); html.push(getChannelProgramsHtml(page, date, channels[i], programs));
} }
$('.programGrid', page).html(html.join('')).scrollTop(0).scrollLeft(0); $('.programGrid', page).html(html.join('')).scrollTop(0).scrollLeft(0)
.createGuideHoverMenu('.timeslotCellInnerWithProgram');
} }
function renderChannelHeaders(page, channels) { function renderChannelHeaders(page, channels) {
@ -445,3 +449,205 @@
}); });
})(jQuery, document, ApiClient); })(jQuery, document, ApiClient);
(function ($, document, window) {
var showOverlayTimeout;
var hideOverlayTimeout;
var currentPosterItem;
function onOverlayMouseOver() {
if (hideOverlayTimeout) {
clearTimeout(hideOverlayTimeout);
hideOverlayTimeout = null;
}
}
function onOverlayMouseOut() {
startHideOverlayTimer();
}
function getOverlayHtml(item) {
var html = '';
html += '<div class="itemOverlayContent">';
if (item.EpisodeTitle) {
html += '<p>';
html += item.EpisodeTitle;
html += '</p>';
}
html += '<p class="itemMiscInfo miscTvProgramInfo"></p>';
html += '<p style="margin: 1.25em 0;">';
html += '<div class="itemCommunityRating" style="display:inline-block;">';
html += LibraryBrowser.getRatingHtml(item);
html += '</div>';
html += '<span class="userDataIcons">';
html += LibraryBrowser.getUserDataIconsHtml(item);
html += '</span>';
html += '</p>';
html += '<p class="itemGenres"></p>';
html += '<p class="itemOverlayHtml">';
html += (item.OverviewHtml || item.Overview || '');
html += '</p>';
//html += '<p>';
//html += '<button type="button" data-mini="true" data-inline="true" data-icon="play" data-iconpos="notext">Play</button>';
//html += '<button type="button" data-mini="true" data-inline="true" data-icon="remote" data-iconpos="notext">Play</button>';
//html += '</p>';
html += '</div>';
return html;
}
function showOverlay(elem, item) {
$('.itemFlyout').popup('close').remove();
var html = '<div data-role="popup" class="itemFlyout" data-theme="b" data-arrow="true" data-history="false">';
html += '<div class="ui-bar-b" style="text-align:center;">';
html += '<h3 style="margin: .5em 0;padding:0 1em;font-weight:normal;">' + item.Name + '</h3>';
html += '</div>';
html += '<div style="padding: 0 1em;">';
html += getOverlayHtml(item);
html += '</div>';
html += '</div>';
$('.itemFlyout').popup('close').popup('destroy').remove();
$(document.body).append(html);
var popup = $('.itemFlyout').on('mouseenter', onOverlayMouseOver).on('mouseleave', onOverlayMouseOut).popup({
positionTo: elem
}).trigger('create').popup("open").on("popupafterclose", function () {
$(this).off("popupafterclose").off("mouseenter").off("mouseleave").remove();
});
LibraryBrowser.renderGenres($('.itemGenres', popup), {
Type: item.type,
Genres: item.Genres.splice(0, 3)
}, 'livetv');
LiveTvHelpers.renderMiscProgramInfo($('.miscTvProgramInfo', popup), item);
popup.parents().prev('.ui-popup-screen').remove();
currentPosterItem = elem;
}
function onProgramClicked() {
if (showOverlayTimeout) {
clearTimeout(showOverlayTimeout);
showOverlayTimeout = null;
}
if (hideOverlayTimeout) {
clearTimeout(hideOverlayTimeout);
hideOverlayTimeout = null;
}
hideOverlay();
}
function hideOverlay() {
$('.itemFlyout').popup('close').remove();
if (currentPosterItem) {
$(currentPosterItem).off('click.overlay');
currentPosterItem = null;
}
}
function startHideOverlayTimer() {
if (hideOverlayTimeout) {
clearTimeout(hideOverlayTimeout);
hideOverlayTimeout = null;
}
hideOverlayTimeout = setTimeout(hideOverlay, 200);
}
function onHoverOut() {
if (showOverlayTimeout) {
clearTimeout(showOverlayTimeout);
showOverlayTimeout = null;
}
startHideOverlayTimer();
}
$.fn.createGuideHoverMenu = function (childSelector) {
function onShowTimerExpired(elem) {
var id = elem.getAttribute('data-programid');
ApiClient.getLiveTvProgram(id, Dashboard.getCurrentUserId()).done(function (item) {
showOverlay(elem, item);
});
}
function onHoverIn() {
if (showOverlayTimeout) {
clearTimeout(showOverlayTimeout);
showOverlayTimeout = null;
}
if (hideOverlayTimeout) {
clearTimeout(hideOverlayTimeout);
hideOverlayTimeout = null;
}
var elem = this;
if (currentPosterItem) {
if (currentPosterItem && currentPosterItem == elem) {
return;
} else {
hideOverlay();
}
}
showOverlayTimeout = setTimeout(function () {
onShowTimerExpired(elem);
}, 1000);
}
// https://hacks.mozilla.org/2013/04/detecting-touch-its-the-why-not-the-how/
if (('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)) {
/* browser with either Touch Events of Pointer Events
running on touch-capable device */
return this;
}
return this.on('mouseenter', childSelector, onHoverIn)
.on('mouseleave', childSelector, onHoverOut)
.on('click', childSelector, onProgramClicked);
};
})(jQuery, document, window);

View file

@ -64,7 +64,7 @@
var item = options.item; var item = options.item;
var html = '<div data-role="popup" id="remoteControlFlyout" data-theme="a">'; var html = '<div data-role="popup" id="remoteControlFlyout" data-transition="slidefade" data-theme="a">';
html += '<a href="#" data-rel="back" data-role="button" data-icon="delete" data-iconpos="notext" class="ui-btn-right" data-theme="b">Close</a>'; html += '<a href="#" data-rel="back" data-role="button" data-icon="delete" data-iconpos="notext" class="ui-btn-right" data-theme="b">Close</a>';
@ -632,7 +632,7 @@
function showMenu(sessions, options) { function showMenu(sessions, options) {
var html = '<div data-role="popup" id="remoteControlFlyout" data-theme="a">'; var html = '<div data-role="popup" data-transition="slidefade" id="remoteControlFlyout" data-theme="a">';
html += '<a href="#" data-rel="back" data-role="button" data-icon="delete" data-iconpos="notext" class="ui-btn-right" data-theme="b">Close</a>'; html += '<a href="#" data-rel="back" data-role="button" data-icon="delete" data-iconpos="notext" class="ui-btn-right" data-theme="b">Close</a>';

View file

@ -395,7 +395,7 @@ var Dashboard = {
$('#confirmFlyout').popup("close").remove(); $('#confirmFlyout').popup("close").remove();
var html = '<div data-role="popup" id="confirmFlyout" style="max-width:500px;" data-theme="a">'; var html = '<div data-role="popup" data-transition="slidefade" id="confirmFlyout" style="max-width:500px;" data-theme="a">';
html += '<div class="ui-bar-a" style="text-align:center;">'; html += '<div class="ui-bar-a" style="text-align:center;">';
html += '<h3>' + title + '</h3>'; html += '<h3>' + title + '</h3>';
@ -491,7 +491,7 @@ var Dashboard = {
Dashboard.getCurrentUser().done(function (user) { Dashboard.getCurrentUser().done(function (user) {
var html = '<div data-role="popup" id="userFlyout" style="max-width:400px;margin-top:30px;margin-right:20px;" data-theme="a">'; var html = '<div data-role="popup" data-transition="slidefade" id="userFlyout" style="max-width:400px;margin-top:30px;margin-right:20px;" data-theme="a">';
html += '<a href="#" data-rel="back" data-role="button" data-icon="delete" data-iconpos="notext" class="ui-btn-right" data-theme="b">Close</a>'; html += '<a href="#" data-rel="back" data-role="button" data-icon="delete" data-iconpos="notext" class="ui-btn-right" data-theme="b">Close</a>';
@ -1319,15 +1319,15 @@ $(function () {
footerHtml += '<div id="nowPlayingBar" class="nowPlayingBar" style="display:none;">'; footerHtml += '<div id="nowPlayingBar" class="nowPlayingBar" style="display:none;">';
footerHtml += '<div class="barBackground ui-bar-b"></div>'; footerHtml += '<div class="barBackground ui-bar-b"></div>';
footerHtml += '<div style="display:inline-block;width:12px;"></div>'; footerHtml += '<div style="display:inline-block;width:12px;"></div>';
footerHtml += '<a id="playlistButton" class="mediaButton" href="playlist.html" data-role="button" data-icon="bullets" data-iconpos="notext" data-inline="true" title="Playlist">Playlist</a>'; footerHtml += '<a id="playlistButton" class="mediaButton playlistButton" href="playlist.html" data-role="button" data-icon="bullets" data-iconpos="notext" data-inline="true" title="Playlist">Playlist</a>';
footerHtml += '<button id="previousTrackButton" class="mediaButton" title="Previous Track" type="button" onclick="MediaPlayer.previousTrack();" data-icon="previous-track" data-iconpos="notext" data-inline="true">Previous Track</button>'; footerHtml += '<button id="previousTrackButton" class="mediaButton previousTrackButton" title="Previous Track" type="button" onclick="MediaPlayer.previousTrack();" data-icon="previous-track" data-iconpos="notext" data-inline="true">Previous Track</button>';
footerHtml += '<button id="playButton" class="mediaButton" title="Play" type="button" onclick="MediaPlayer.unpause();" data-icon="play" data-iconpos="notext" data-inline="true">Play</button>'; footerHtml += '<button id="playButton" class="mediaButton" title="Play" type="button" onclick="MediaPlayer.unpause();" data-icon="play" data-iconpos="notext" data-inline="true">Play</button>';
footerHtml += '<button id="pauseButton" class="mediaButton" title="Pause" type="button" onclick="MediaPlayer.pause();" data-icon="pause" data-iconpos="notext" data-inline="true">Pause</button>'; footerHtml += '<button id="pauseButton" class="mediaButton" title="Pause" type="button" onclick="MediaPlayer.pause();" data-icon="pause" data-iconpos="notext" data-inline="true">Pause</button>';
footerHtml += '<div id="mediaElement"></div>'; footerHtml += '<div id="mediaElement"></div>';
footerHtml += '<button id="stopButton" class="mediaButton" title="Stop" type="button" onclick="MediaPlayer.stop();" data-icon="stop" data-iconpos="notext" data-inline="true">Stop</button>'; footerHtml += '<button id="stopButton" class="mediaButton" title="Stop" type="button" onclick="MediaPlayer.stop();" data-icon="stop" data-iconpos="notext" data-inline="true">Stop</button>';
footerHtml += '<button id="nextTrackButton" class="mediaButton" title="Next Track" type="button" onclick="MediaPlayer.nextTrack();" data-icon="next-track" data-iconpos="notext" data-inline="true">Next Track</button>'; footerHtml += '<button id="nextTrackButton" class="mediaButton nextTrackButton" title="Next Track" type="button" onclick="MediaPlayer.nextTrack();" data-icon="next-track" data-iconpos="notext" data-inline="true">Next Track</button>';
footerHtml += '<div class="positionSliderContainer sliderContainer">'; footerHtml += '<div class="positionSliderContainer sliderContainer">';
footerHtml += '<input type="range" class="mediaSlider positionSlider slider" step=".001" min="0" max="100" value="0" style="display:none;" data-mini="true" data-theme="a" data-highlight="true" />'; footerHtml += '<input type="range" class="mediaSlider positionSlider slider" step=".001" min="0" max="100" value="0" style="display:none;" data-mini="true" data-theme="a" data-highlight="true" />';
@ -1336,8 +1336,8 @@ $(function () {
footerHtml += '<div class="currentTime"></div>'; footerHtml += '<div class="currentTime"></div>';
footerHtml += '<div class="nowPlayingMediaInfo"></div>'; footerHtml += '<div class="nowPlayingMediaInfo"></div>';
footerHtml += '<button id="muteButton" class="mediaButton" title="Mute" type="button" onclick="MediaPlayer.mute();" data-icon="audio" data-iconpos="notext" data-inline="true">Mute</button>'; footerHtml += '<button id="muteButton" class="mediaButton muteButton" title="Mute" type="button" onclick="MediaPlayer.mute();" data-icon="audio" data-iconpos="notext" data-inline="true">Mute</button>';
footerHtml += '<button id="unmuteButton" class="mediaButton" title="Unmute" type="button" onclick="MediaPlayer.unmute();" data-icon="volume-off" data-iconpos="notext" data-inline="true">Unmute</button>'; footerHtml += '<button id="unmuteButton" class="mediaButton unmuteButton" title="Unmute" type="button" onclick="MediaPlayer.unmute();" data-icon="volume-off" data-iconpos="notext" data-inline="true">Unmute</button>';
footerHtml += '<div class="volumeSliderContainer sliderContainer">'; footerHtml += '<div class="volumeSliderContainer sliderContainer">';
footerHtml += '<input type="range" class="mediaSlider volumeSlider slider" step=".05" min="0" max="1" value="0" style="display:none;" data-mini="true" data-theme="a" data-highlight="true" />'; footerHtml += '<input type="range" class="mediaSlider volumeSlider slider" step=".05" min="0" max="1" value="0" style="display:none;" data-mini="true" data-theme="a" data-highlight="true" />';

View file

@ -24,7 +24,7 @@
</div> </div>
<p>Refer to <a href="https://github.com/MediaBrowser/MediaBrowser/wiki/Library-Structure" target="_blank">media library wiki.</a></p> <p>Refer to <a href="https://github.com/MediaBrowser/MediaBrowser/wiki/Library-Structure" target="_blank">media library wiki.</a></p>
<div data-role="popup" id="popupEnterText" class="popup"> <div data-role="popup" data-transition="slidefade" id="popupEnterText" class="popup">
<div class="ui-corner-top ui-bar-a" style="text-align: center; padding: 0 20px;"> <div class="ui-corner-top ui-bar-a" style="text-align: center; padding: 0 20px;">
<h3>Rename</h3> <h3>Rename</h3>