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

Merge pull request #777 from timhobbs/master

Cast updates and lazy loading
This commit is contained in:
Luke 2014-04-10 11:17:36 -04:00
commit b7c828e294
19 changed files with 607 additions and 127 deletions

View file

@ -139,7 +139,7 @@
text-align: left;
margin-left: 0;
right: 0;
bottom: 83px;
bottom: 85px;
}
/* Media queries
@ -259,7 +259,7 @@
}
#mediaPlayer #videoControls .mediaPlayerFlyout {
bottom: 148px;
bottom: 150px;
}
}

View file

@ -66,6 +66,17 @@
this.hasReceivers = false;
this.currentMediaOffset = 0;
// Progress bar element id
this.progressBar = "positionSlider";
// Timec display element id
this.duration = "currentTime";
// Playback display element id
this.playback = "playTime";
this.initializeCastPlayer();
};
@ -89,7 +100,7 @@
// v1 Id AE4DA10A
// v2 Id 472F0435
var applicationID = 'AE4DA10A';
var applicationID = '472F0435';
// request session
var sessionRequest = new chrome.cast.SessionRequest(applicationID);
@ -445,6 +456,8 @@
function getMetadata(item) {
console.log("md item", item);
var metadata = {};
if (item.Type == 'Episode') {
@ -512,7 +525,7 @@
else if (item.MediaType == 'Movie') {
metadata = new chrome.cast.media.MovieMediaMetadata();
metadata.type = chrome.cast.media.MetadataType.MUSIC_TRACK;
metadata.type = chrome.cast.media.MetadataType.MOVIE;
if (item.ProductionYear) {
metadata.releaseYear = item.ProductionYear;
@ -617,6 +630,8 @@
return;
}
this.currentMediaOffset = startTimeTicks || 0;
var maxBitrate = 12000000;
var mediaInfo = getMediaSourceInfo(user, item, maxBitrate, mediaSourceId, audioStreamIndex, subtitleStreamIndex);
@ -653,40 +668,62 @@
console.log("chromecast new media session ID:" + mediaSession.mediaSessionId + ' (' + how + ')');
this.currentMediaSession = mediaSession;
this.currentMediaTime = this.session.media[0].currentTime;
if (how == 'loadMedia') {
this.castPlayerState = PLAYER_STATE.PLAYING;
clearInterval(this.timer);
this.startProgressTimer(this.incrementMediaTime);
}
if (how == 'activeSession') {
this.castPlayerState = this.session.media[0].playerState;
this.currentMediaTime = this.session.media[0].currentTime;
}
if (this.castPlayerState == PLAYER_STATE.PLAYING) {
// start progress timer
//this.startProgressTimer(this.incrementMediaTime);
this.startProgressTimer(this.incrementMediaTime);
}
this.currentMediaSession.addUpdateListener(this.onMediaStatusUpdate.bind(this));
this.currentMediaDuration = this.currentMediaSession.media.duration;
//this.currentMediaDuration = this.currentMediaSession.media.duration;
//var duration = this.currentMediaDuration;
//var hr = parseInt(duration / 3600);
//duration -= hr * 3600;
//var min = parseInt(duration / 60);
//var sec = parseInt(duration % 60);
//if (hr > 0) {
// duration = hr + ":" + min + ":" + sec;
//}
//else {
// if (min > 0) {
// duration = min + ":" + sec;
// }
// else {
// duration = sec;
// }
//}
//document.getElementById("duration").innerHTML = duration;
var playTime = document.getElementById(this.playback);
if (!playTime) {
// Set duration time
var totalTime = document.getElementById(this.duration);
totalTime.innerHTML = " / " + formatTime(this.currentMediaDuration);
// Set play time
playTime = document.createElement("div");
playTime.id = this.playback;
playTime.className = "currentTime";
playTime.style.marginRight = "5px";
totalTime.parentNode.insertBefore(playTime, totalTime);
playTime.innerHTML = formatTime(this.currentMediaTime);
}
};
function formatTime(duration) {
var hr = parseInt(duration / 3600);
duration -= hr * 3600;
var min = parseInt(duration / 60);
var sec = parseInt(duration % 60);
hr = "" + hr;
min = "" + min;
sec = "" + sec;
var hh = pad(hr);
var mm = pad(min);
var ss = pad(sec);
duration = hh + ":" + mm + ":" + ss;
return duration;
};
function pad(s) {
return "00".substring(0, 2 - s.length) + s;
};
/**
@ -707,7 +744,7 @@
this.castPlayerState = PLAYER_STATE.IDLE;
}
console.log("chromecast updating media");
//this.updateProgressBar(e);
this.updateProgressBarByTimer();
};
/**
@ -745,6 +782,7 @@
this.currentMediaSession.addUpdateListener(this.onMediaStatusUpdate.bind(this));
this.castPlayerState = PLAYER_STATE.PLAYING;
// start progress timer
clearInterval(this.timer);
this.startProgressTimer(this.incrementMediaTime);
break;
case PLAYER_STATE.IDLE:
@ -791,6 +829,10 @@
this.onError.bind(this));
this.castPlayerState = PLAYER_STATE.STOPPED;
clearInterval(this.timer);
var playTime = document.getElementById(this.playback);
if (playTime) {
playTime.parentNode.removeChild(playTime);
}
};
/**
@ -849,19 +891,10 @@
* @param {Event} e An event object from seek
*/
CastPlayer.prototype.seekMedia = function (event) {
var pos = parseInt(event.offsetX);
var pi = document.getElementById("progress_indicator");
var p = document.getElementById("progress");
if (event.currentTarget.id == 'progress_indicator') {
var curr = parseInt(this.currentMediaTime + this.currentMediaDuration * pos / PROGRESS_BAR_WIDTH);
var pp = parseInt(pi.style.marginLeft) + pos;
var pw = parseInt(p.style.width) + pos;
}
else {
var curr = parseInt(pos * this.currentMediaDuration / PROGRESS_BAR_WIDTH);
var pp = pos - 21 - PROGRESS_BAR_WIDTH;
var pw = pos;
}
var pos = parseInt(event);
var p = document.getElementById(this.progressBar);
var curr = parseInt(this.currentMediaTime + this.currentMediaDuration * pos);
var pw = parseInt(p.value) + pos;
if (this.castPlayerState != PLAYER_STATE.PLAYING && this.castPlayerState != PLAYER_STATE.PAUSED) {
return;
@ -899,20 +932,20 @@
* @param {Object} e An media status update object
*/
CastPlayer.prototype.updateProgressBar = function (e) {
var p = document.getElementById("progress");
var pi = document.getElementById("progress_indicator");
var p = document.getElementById(this.progressBar);
if (e.idleReason == 'FINISHED' && e.playerState == 'IDLE') {
p.style.width = '0px';
pi.style.marginLeft = -21 - PROGRESS_BAR_WIDTH + 'px';
p.value = 0;
clearInterval(this.timer);
this.castPlayerState = PLAYER_STATE.STOPPED;
if (e.idleReason == 'FINISHED') {
$.publish("/playback/complete", e);
console.log("playback complete", e);
}
}
else {
p.style.width = Math.ceil(PROGRESS_BAR_WIDTH * e.currentTime / this.currentMediaSession.media.duration + 1) + 'px';
p.value = Number(e.currentTime / this.currentMediaSession.media.duration + 1).toFixed(3);
this.progressFlag = false;
setTimeout(this.setProgressFlag.bind(this), 1000); // don't update progress in 1 second
var pp = Math.ceil(PROGRESS_BAR_WIDTH * e.currentTime / this.currentMediaSession.media.duration);
pi.style.marginLeft = -21 - PROGRESS_BAR_WIDTH + pp + 'px';
}
};
@ -928,47 +961,159 @@
* Update progress bar based on timer
*/
CastPlayer.prototype.updateProgressBarByTimer = function () {
var p = document.getElementById("progress");
if (isNaN(parseInt(p.style.width))) {
p.style.width = 0;
var p = document.getElementById(this.progressBar);
if (isNaN(parseInt(p.value))) {
p.value = 0;
}
if (this.currentMediaDuration > 0) {
var pp = Math.floor(PROGRESS_BAR_WIDTH * this.currentMediaTime / this.currentMediaDuration);
var pp = Number(this.currentMediaTime / this.currentMediaDuration).toFixed(3);
var startTime = this.currentMediaOffset / 10000000;
var playTime = document.getElementById(this.playback);
if (playTime) {
playTime.innerHTML = formatTime(startTime + this.currentMediaTime);
}
}
if (this.progressFlag) {
// don't update progress if it's been updated on media status update event
p.style.width = pp + 'px';
var pi = document.getElementById("progress_indicator");
pi.style.marginLeft = -21 - PROGRESS_BAR_WIDTH + pp + 'px';
p.value = pp;
}
if (pp > PROGRESS_BAR_WIDTH) {
if (pp > 100 || this.castPlayerState == PLAYER_STATE.IDLE) {
clearInterval(this.timer);
this.deviceState = DEVICE_STATE.IDLE;
this.castPlayerState = PLAYER_STATE.IDLE;
$.publish("/playback/complete", true);
console.log("playback complete");
}
};
/**
* @param {function} A callback function for the fucntion to start timer
*/
CastPlayer.prototype.startProgressTimer = function(callback) {
if(this.timer) {
clearInterval(this.timer);
this.timer = null;
}
// start progress timer
this.timer = setInterval(callback.bind(this), this.timerStep);
};
var castPlayer = new CastPlayer();
function chromecastPlayer() {
function chromecastPlayer(castPlayer) {
var self = this;
var isPositionSliderActive = false;
self.name = PlayerName;
self.play = function (options) {
self.isPaused = false;
if (options.items) {
self.playlist = [];
Dashboard.getCurrentUser().done(function (user) {
self.playlistIndex = 0;
castPlayer.loadMedia(user, options.items[0], options.startTimeTicks);
$.subscribe("/playback/complete", function (e) {
if (self.playlistIndex < (self.playlist.items || []).length) {
self.play(self.playlist);
}
});
} else {
////$(".positionSlider", "#footer").off("slidestart slidestop")
//// .on('slidestart', function (e) {
//// isPositionSliderActive = true;
////}).on('slidestop', positionSliderChange);
////function positionSliderChange() {
//// isPositionSliderActive = false;
//// var newPercent = parseInt(this.value);
//// self.changeStream(newPercent);
////}
function getItemsForPlayback(query) {
var userId = Dashboard.getCurrentUserId();
query.Limit = query.Limit || 100;
query.Fields = getItemFields;
query.ExcludeLocationTypes = "Virtual";
return ApiClient.getItems(userId, query);
};
function queueItems (items) {
for (var i = 0, length = items.length; i < length; i++) {
self.playlist.push(items[i]);
}
};
function queueItemsNext(items) {
var insertIndex = 1;
for (var i = 0, length = items.length; i < length; i++) {
self.playlist.splice(insertIndex, 0, items[i]);
insertIndex++;
}
};
function translateItemsForPlayback(items) {
var deferred = $.Deferred();
var firstItem = items[0];
var promise;
if (firstItem.IsFolder) {
promise = self.getItemsForPlayback({
ParentId: firstItem.Id,
Filters: "IsNotFolder",
Recursive: true,
SortBy: "SortName",
MediaTypes: "Audio,Video"
});
}
else if (firstItem.Type == "MusicArtist") {
promise = self.getItemsForPlayback({
Artists: firstItem.Name,
Filters: "IsNotFolder",
Recursive: true,
SortBy: "SortName",
MediaTypes: "Audio"
});
}
else if (firstItem.Type == "MusicGenre") {
promise = self.getItemsForPlayback({
Genres: firstItem.Name,
Filters: "IsNotFolder",
Recursive: true,
SortBy: "SortName",
MediaTypes: "Audio"
});
}
if (promise) {
promise.done(function (result) {
deferred.resolveWith(null, [result.Items]);
});
} else {
deferred.resolveWith(null, [items]);
}
return deferred.promise();
};
self.play = function (options) {
console.log("play", options);
$("#nowPlayingBar", "#footer").show();
if (self.isPaused) {
self.isPaused = !self.isPaused;
castPlayer.playMedia();
} else if (options.items) {
Dashboard.getCurrentUser().done(function (user) {
castPlayer.loadMedia(user, options.items[self.playlistIndex++], options.startPositionTicks);
});
} else {
var userId = Dashboard.getCurrentUserId();
var query = {};
@ -978,46 +1123,154 @@
query.Ids = options.ids.join(',');
ApiClient.getItems(userId, query).done(function (result) {
options.items = result.Items;
self.play(options);
});
}
};
self.unpause = function () {
console.log("unpause");
self.isPaused = !self.isPaused;
castPlayer.playMedia();
};
self.pause = function () {
console.log("pause");
self.isPaused = true;
castPlayer.pauseMedia();
};
self.shuffle = function (id) {
self.play({ ids: [id] });
var userId = Dashboard.getCurrentUserId();
ApiClient.getItem(userId, id).done(function (item) {
var query = {
UserId: userId,
Fields: getItemFields,
Limit: 50,
Filters: "IsNotFolder",
Recursive: true,
SortBy: "Random"
};
if (item.IsFolder) {
query.ParentId = id;
}
else if (item.Type == "MusicArtist") {
query.MediaTypes = "Audio";
query.Artists = item.Name;
}
else if (item.Type == "MusicGenre") {
query.MediaTypes = "Audio";
query.Genres = item.Name;
} else {
return;
}
self.getItemsForPlayback(query).done(function (result) {
self.playlist = { items: result.Items };
console.log("shuffle items", result.Items);
self.play(self.playlist);
});
});
};
self.instantMix = function (id) {
self.play({ ids: [id] });
};
var userId = Dashboard.getCurrentUserId();
ApiClient.getItem(userId, id).done(function (item) {
var promise;
var getItemFields = "MediaSources,Chapters";
var mixLimit = 3;
self.queue = function (options) {
if (item.Type == "MusicArtist") {
promise = ApiClient.getInstantMixFromArtist(name, {
UserId: userId,
Fields: getItemFields,
Limit: mixLimit
});
}
else if (item.Type == "MusicGenre") {
promise = ApiClient.getInstantMixFromMusicGenre(name, {
UserId: userId,
Fields: getItemFields,
Limit: mixLimit
});
}
else if (item.Type == "MusicAlbum") {
promise = ApiClient.getInstantMixFromAlbum(id, {
UserId: userId,
Fields: getItemFields,
Limit: mixLimit
});
}
else if (item.Type == "Audio") {
promise = ApiClient.getInstantMixFromSong(id, {
UserId: userId,
Fields: getItemFields,
Limit: mixLimit
});
}
else {
return;
}
};
self.queueNext = function (options) {
};
self.stop = function () {
castPlayer.stop();
promise.done(function (result) {
self.playlist = { items: result.Items };
console.log("instant mix items", result.Items);
self.play(self.playlist);
});
});
};
self.canQueueMediaType = function (mediaType) {
return mediaType == "Audio";
};
return false;
self.queue = function (options) {
Dashboard.getCurrentUser().done(function (user) {
if (options.items) {
translateItemsForPlayback(options.items).done(function (items) {
queueItems(items);
});
} else {
getItemsForPlayback({
Ids: options.ids.join(',')
}).done(function (result) {
translateItemsForPlayback(result.Items).done(function (items) {
queueItems(items);
});
});
}
});
};
self.queueNext = function (options) {
Dashboard.getCurrentUser().done(function (user) {
if (options.items) {
queueItemsNext(options.items);
} else {
self.getItemsForPlayback({
Ids: options.ids.join(',')
}).done(function (result) {
options.items = result.Items;
queueItemsNext(options.items);
});
}
});
};
self.stop = function () {
$("#nowPlayingBar", "#footer").hide();
self.playlist = [];
self.playlistIndex = 0;
castPlayer.stopMedia();
};
self.mute = function () {
castPlayer.mute();
};
self.unMute = function () {
self.unmute = function () {
castPlayer.unMute();
};
@ -1026,18 +1279,13 @@
};
self.getTargets = function () {
var targets = [];
targets.push(self.getCurrentTargetInfo());
return targets;
};
self.getCurrentTargetInfo = function () {
var appName = null;
if (castPlayer.session && castPlayer.session.receiver && castPlayer.session.friendlyName) {
appName = castPlayer.session.friendlyName;
}
@ -1051,9 +1299,80 @@
appName: appName
};
};
self.setCurrentTime = function (ticks, item, updateSlider) {
// Convert to ticks
ticks = Math.floor(ticks);
var timeText = Dashboard.getDisplayTime(ticks);
if (self.currentDurationTicks) {
timeText += " / " + Dashboard.getDisplayTime(self.currentDurationTicks);
if (updateSlider) {
var percent = ticks / self.currentDurationTicks;
percent *= 100;
self.positionSlider.val(percent).slider('enable').slider('refresh');
}
} else {
self.positionSlider.slider('disable').slider('refresh');
}
MediaController.registerPlayer(new chromecastPlayer());
self.currentTimeElement.html(timeText);
};
self.changeStream = function (position) {
console.log("seek", position);
////castPlayer.seekMedia(position);
};
self.removeFromPlaylist = function (i) {
self.playlist.remove(i);
};
self.currentPlaylistIndex = function (i) {
if (i == null) {
return currentPlaylistIndex;
}
var newItem = self.playlist[i];
Dashboard.getCurrentUser().done(function (user) {
self.playInternal(newItem, 0, user);
currentPlaylistIndex = i;
});
};
self.nextTrack = function () {
var newIndex = currentPlaylistIndex + 1;
var newItem = self.playlist[newIndex];
if (newItem) {
Dashboard.getCurrentUser().done(function (user) {
self.playInternal(newItem, 0, user);
currentPlaylistIndex = newIndex;
});
}
};
self.previousTrack = function () {
var newIndex = currentPlaylistIndex - 1;
if (newIndex >= 0) {
var newItem = self.playlist[newIndex];
if (newItem) {
Dashboard.getCurrentUser().done(function (user) {
self.playInternal(newItem, 0, user);
currentPlaylistIndex = newIndex;
});
}
}
};
self.volumeDown = function () {
};
self.volumeUp = function () {
};
}
MediaController.registerPlayer(new chromecastPlayer(castPlayer));
$(MediaController).on('playerchange', function () {

View file

@ -34,7 +34,8 @@
showTitle: true,
showParentTitle: true,
overlayText: true,
selectionPanel: true
selectionPanel: true,
lazy: true
});
$('.itemsContainer', page).removeClass('timelineItemsContainer');

View file

@ -432,6 +432,8 @@
options.shape = options.shape || "portrait";
options.lazy = options.lazy || false;
var html = "";
var primaryImageAspectRatio = options.shape == 'auto' ? LibraryBrowser.getAveragePrimaryImageAspectRatio(items) : null;
@ -667,7 +669,7 @@
var style = "";
if (imgUrl) {
if (imgUrl && !options.lazy) {
style += 'background-image:url(\'' + imgUrl + '\');';
}
@ -680,9 +682,16 @@
imageCssClass += " coveredPosterItemImage";
}
var dataSrc = "";
if (options.lazy) {
imageCssClass += " lazy";
dataSrc = ' data-src="' + imgUrl + '"';
}
var progressHtml = options.showProgress === false ? '' : LibraryBrowser.getItemProgressBarHtml(item);
html += '<div class="' + imageCssClass + '" style="' + style + '">';
html += '<div class="' + imageCssClass + '" style="' + style + '"' + dataSrc + '>';
html += '<div class="posterItemOverlayTarget"></div>';
@ -755,6 +764,10 @@
var itemCountHtml = LibraryBrowser.getItemCountsHtml(options, item);
if (item.Type == "Person" && !itemCountHtml) {
itemCountHtml = "&nbsp;";
}
if (itemCountHtml) {
html += "<div class='" + cssClass + "'>";
html += itemCountHtml;

View file

@ -174,6 +174,62 @@
return p.isDefaultPlayer;
})[0];
};
self.pause = function () {
currentPlayer.pause();
};
self.stop = function () {
currentPlayer.stop();
};
self.unpause = function () {
currentPlayer.unpause();
};
self.seek = function (position) {
currentPlayer.changeStream(position);
};
self.currentPlaylistIndex = function (i) {
currentPlayer.currentPlaylistIndex(i);
};
self.removeFromPlaylist = function (i) {
currentPlayer.removeFromPlaylist(i);
};
self.nextTrack = function () {
currentPlayer.nextTrack();
};
self.previousTrack = function () {
currentPlayer.previousTrack();
};
self.mute = function () {
currentPlayer.mute();
};
self.unmute = function () {
currentPlayer.unmute();
};
self.toggleMute = function () {
currentPlayer.toggleMute();
};
self.volumeDown = function () {
currentPlayer.volumeDown();
};
self.volumeUp = function () {
currentPlayer.volumeUp();
};
self.shuffle = function (id) {
currentPlayer.shuffle(id);
};
}
window.MediaController = new mediaController();

View file

@ -872,18 +872,18 @@
$('#video-fullscreenButton', videoControls).show();
}
var videoElement = $("video", videoElement);
var video = $("video", videoElement);
initialVolume = localStorage.getItem("volume") || 0.5;
videoElement.each(function () {
video.each(function () {
this.volume = initialVolume;
});
self.volumeSlider.val(initialVolume).slider('refresh');
self.updateVolumeButtons(initialVolume);
videoElement.on("volumechange", function (e) {
video.on("volumechange", function (e) {
var muted = this.muted;
@ -899,13 +899,13 @@
}).on("play.once", function () {
videoElement.off("play.once");
video.off("play.once");
}).on("playing.once", function () {
self.updateCanClientSeek(this);
videoElement.off("playing.once");
video.off("playing.once");
ApiClient.reportPlaybackStart(Dashboard.getCurrentUserId(), item.Id, mediaSource.Id, true, item.MediaType);
@ -1037,7 +1037,7 @@
currentItem = item;
currentMediaSource = mediaSource;
return videoElement[0];
return video[0];
}
};
})();

View file

@ -33,7 +33,8 @@
shape: "portrait",
context: 'movies',
showTitle: true,
centerText: true
centerText: true,
lazy: true
});
html += LibraryBrowser.getPagingHtml(query, result.TotalRecordCount);

View file

@ -34,7 +34,8 @@
context: 'movies',
showTitle: true,
showItemCounts: true,
coverImage: true
coverImage: true,
lazy: true
});
html += LibraryBrowser.getPagingHtml(query, result.TotalRecordCount, false, [], false);

View file

@ -35,7 +35,8 @@
shape: "backdrop",
preferThumb: true,
context: 'movies',
selectionPanel: true
selectionPanel: true,
lazy: true
});
$('.itemsContainer', page).removeClass('timelineItemsContainer');
}
@ -45,7 +46,8 @@
items: result.Items,
shape: "banner",
preferBanner: true,
context: 'movies'
context: 'movies',
lazy: true
});
$('.itemsContainer', page).removeClass('timelineItemsContainer');
}
@ -56,7 +58,8 @@
context: 'movies',
showTitle: true,
centerText: true,
selectionPanel: true
selectionPanel: true,
lazy: true
});
$('.itemsContainer', page).removeClass('timelineItemsContainer');
}
@ -68,7 +71,8 @@
showTitle: true,
timeline: true,
centerText: true,
selectionPanel: true
selectionPanel: true,
lazy: true
});
$('.itemsContainer', page).addClass('timelineItemsContainer');
}

View file

@ -32,7 +32,8 @@
context: 'music',
showTitle: true,
coverImage: true,
centerText: true
centerText: true,
lazy: true
});
html += LibraryBrowser.getPagingHtml(query, result.TotalRecordCount);

View file

@ -34,7 +34,8 @@
shape: "square",
context: 'music',
showTitle: true,
showParentTitle: true
showParentTitle: true,
lazy: true
});
$('.itemsContainer', page).removeClass('timelineItemsContainer');
}
@ -45,7 +46,8 @@
context: 'music',
showTitle: true,
showParentTitle: true,
timeline: true
timeline: true,
lazy: true
});
$('.itemsContainer', page).addClass('timelineItemsContainer');
}

View file

@ -31,7 +31,8 @@
context: 'music',
showTitle: true,
coverImage: true,
centerText: true
centerText: true,
lazy: true
});
html += LibraryBrowser.getPagingHtml(query, result.TotalRecordCount);
@ -119,4 +120,10 @@
updateFilterControls(this);
});
$(function () {
$("body").on("create", function () {
$(".lazy").unveil(200);
});
});
})(jQuery, document);

View file

@ -32,7 +32,8 @@
preferThumb: true,
context: 'music',
showItemCounts: true,
centerText: true
centerText: true,
lazy: true
});
html += LibraryBrowser.getPagingHtml(query, result.TotalRecordCount);

View file

@ -17,7 +17,7 @@
html += '<tbody>';
$.each(MediaPlayer.playlist, function (i, item) {
$.each(MediaController.playlist, function (i, item) {
var name = LibraryBrowser.getPosterViewDisplayName(item);
@ -65,14 +65,14 @@
var index = parseInt(this.getAttribute('data-index'));
MediaPlayer.currentPlaylistIndex(index);
MediaController.currentPlaylistIndex(index);
reloadPlaylist(page);
}).on('click', '.lnkRemove', function () {
var index = parseInt(this.getAttribute('data-index'));
MediaPlayer.removeFromPlaylist(index);
MediaController.removeFromPlaylist(index);
reloadPlaylist(page);
});

View file

@ -1330,42 +1330,42 @@ $(function () {
footerHtml += '<div class="barBackground ui-bar-b"></div>';
footerHtml += '<div style="display:inline-block;width:12px;"></div>';
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 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="pauseButton" class="mediaButton" title="Pause" type="button" onclick="MediaPlayer.pause();" data-icon="pause" data-iconpos="notext" data-inline="true">Pause</button>';
footerHtml += '<button id="previousTrackButton" class="mediaButton previousTrackButton" title="Previous Track" type="button" onclick="MediaController.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="MediaController.unpause();" data-icon="play" data-iconpos="notext" data-inline="true">Play</button>';
footerHtml += '<button id="pauseButton" class="mediaButton" title="Pause" type="button" onclick="MediaController.pause();" data-icon="pause" data-iconpos="notext" data-inline="true">Pause</button>';
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="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 += '<button id="stopButton" class="mediaButton" title="Stop" type="button" onclick="MediaController.stop();" data-icon="stop" data-iconpos="notext" data-inline="true">Stop</button>';
footerHtml += '<button id="nextTrackButton" class="mediaButton nextTrackButton" title="Next Track" type="button" onclick="MediaController.nextTrack();" data-icon="next-track" data-iconpos="notext" data-inline="true">Next Track</button>';
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 id="positionSlider" 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 += '</div>';
footerHtml += '<div class="currentTime"></div>';
footerHtml += '<div class="currentTime" id="currentTime"></div>';
footerHtml += '<div class="nowPlayingMediaInfo"></div>';
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 unmuteButton" title="Unmute" type="button" onclick="MediaPlayer.unMute();" data-icon="volume-off" data-iconpos="notext" data-inline="true">Unmute</button>';
footerHtml += '<button id="muteButton" class="mediaButton muteButton" title="Mute" type="button" onclick="MediaController.mute();" data-icon="audio" data-iconpos="notext" data-inline="true">Mute</button>';
footerHtml += '<button id="unmuteButton" class="mediaButton unmuteButton" title="Unmute" type="button" onclick="MediaController.unMute();" data-icon="volume-off" data-iconpos="notext" data-inline="true">Unmute</button>';
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 += '</div>';
footerHtml += '<button onclick="MediaPlayer.showQualityFlyout();" id="qualityButton" class="mediaButton qualityButton" title="Quality" type="button" data-icon="gear" data-iconpos="notext" data-inline="true">Quality</button>';
footerHtml += '<button onclick="MediaController.showQualityFlyout();" id="qualityButton" class="mediaButton qualityButton" title="Quality" type="button" data-icon="gear" data-iconpos="notext" data-inline="true">Quality</button>';
footerHtml += '<div class="mediaFlyoutContainer"><div id="qualityFlyout" style="display:none;" class="mediaPlayerFlyout"></div></div>';
footerHtml += '<button onclick="MediaPlayer.showAudioTracksFlyout();" id="audioTracksButton" class="imageButton mediaButton audioTracksButton" title="Audio tracks" type="button" data-icon="audiocd" data-iconpos="notext" data-inline="true">Audio Tracks</button>';
footerHtml += '<button onclick="MediaController.showAudioTracksFlyout();" id="audioTracksButton" class="imageButton mediaButton audioTracksButton" title="Audio tracks" type="button" data-icon="audiocd" data-iconpos="notext" data-inline="true">Audio Tracks</button>';
footerHtml += '<div class="mediaFlyoutContainer"><div id="audioTracksFlyout" style="display:none;" class="mediaPlayerFlyout audioTracksFlyout"></div></div>';
footerHtml += '<button onclick="MediaPlayer.showSubtitleMenu();" id="subtitleButton" class="imageButton mediaButton subtitleButton" title="Subtitles" type="button" data-icon="subtitles" data-iconpos="notext" data-inline="true">Subtitles</button>';
footerHtml += '<button onclick="MediaController.showSubtitleMenu();" id="subtitleButton" class="imageButton mediaButton subtitleButton" title="Subtitles" type="button" data-icon="subtitles" data-iconpos="notext" data-inline="true">Subtitles</button>';
footerHtml += '<div class="mediaFlyoutContainer"><div id="subtitleFlyout" style="display:none;" class="mediaPlayerFlyout subtitleFlyout"></div></div>';
footerHtml += '<button onclick="MediaPlayer.showChaptersFlyout();" id="chaptersButton" class="mediaButton chaptersButton" title="Scenes" type="button" data-icon="video" data-iconpos="notext" data-inline="true">Scenes</button>';
footerHtml += '<button onclick="MediaController.showChaptersFlyout();" id="chaptersButton" class="mediaButton chaptersButton" title="Scenes" type="button" data-icon="video" data-iconpos="notext" data-inline="true">Scenes</button>';
footerHtml += '<div class="mediaFlyoutContainer"><div id="chaptersFlyout" style="display:none;" class="mediaPlayerFlyout chaptersFlyout"></div></div>';
footerHtml += '<button onclick="MediaPlayer.toggleFullscreen();" id="fullscreenButton" class="mediaButton fullscreenButton" title="Fullscreen" type="button" data-icon="action" data-iconpos="notext" data-inline="true">Fullscreen</button>';
footerHtml += '<button onclick="MediaController.toggleFullscreen();" id="fullscreenButton" class="mediaButton fullscreenButton" title="Fullscreen" type="button" data-icon="action" data-iconpos="notext" data-inline="true">Fullscreen</button>';
footerHtml += '</div>';
@ -1386,6 +1386,10 @@ $(function () {
ApiClient.closeWebSocket();
}
});
$("body").on("create", function () {
$(".lazy").unveil(200);
});
});
Dashboard.jQueryMobileInit();
@ -1428,4 +1432,3 @@ $(document).on('pagebeforeshow', ".page", function () {
Dashboard.refreshSystemInfoFromServer();
}
});

View file

@ -34,7 +34,8 @@
context: 'tv',
showTitle: true,
showItemCounts: true,
coverImage: true
coverImage: true,
lazy: true
});
html += LibraryBrowser.getPagingHtml(query, result.TotalRecordCount, false, [], false);

View file

@ -34,7 +34,8 @@
items: result.Items,
shape: "backdrop",
preferThumb: true,
context: 'tv'
context: 'tv',
lazy: true
});
$('.itemsContainer', page).removeClass('timelineItemsContainer');
@ -45,7 +46,8 @@
items: result.Items,
shape: "banner",
preferBanner: true,
context: 'tv'
context: 'tv',
lazy: true
});
$('.itemsContainer', page).removeClass('timelineItemsContainer');
}
@ -56,7 +58,8 @@
shape: "portrait",
context: 'tv',
showTitle: true,
centerText: true
centerText: true,
lazy: true
});
$('.itemsContainer', page).removeClass('timelineItemsContainer');
}
@ -67,7 +70,8 @@
shape: "portrait",
context: 'tv',
timeline: true,
showTitle: true
showTitle: true,
lazy: true
});
$('.itemsContainer', page).addClass('timelineItemsContainer');

View file

@ -0,0 +1,4 @@
/* jQuery Tiny Pub/Sub - v0.7 - 10/27/2011
* http://benalman.com/
* Copyright (c) 2011 "Cowboy" Ben Alman; Licensed MIT, GPL */
(function (a) { var b = a({}); a.subscribe = function () { b.on.apply(b, arguments) }, a.unsubscribe = function () { b.off.apply(b, arguments) }, a.publish = function () { b.trigger.apply(b, arguments) } })(jQuery)

View file

@ -0,0 +1,62 @@
/**
* jQuery Unveil
* A very lightweight jQuery plugin to lazy load images
* http://luis-almeida.github.com/unveil
*
* Licensed under the MIT license.
* Copyright 2013 Luís Almeida
* https://github.com/luis-almeida
*/
; (function ($) {
$.fn.unveil = function (threshold, callback) {
var $w = $(window),
th = threshold || 0,
retina = window.devicePixelRatio > 1,
attrib = retina ? "data-src-retina" : "data-src",
images = this,
loaded;
this.one("unveil", function () {
var elemType = $(this).get(0).tagName;
var source = this.getAttribute(attrib);
source = source || this.getAttribute("data-src");
if (source) {
if (elemType === "DIV") {
this.style.backgroundImage = "url('" + source + "')";
} else {
this.setAttribute("src", source);
}
if (typeof callback === "function") callback.call(this);
}
});
function unveil() {
var inview = images.filter(function () {
var $e = $(this);
if ($e.is(":hidden")) return;
var wt = $w.scrollTop(),
wb = wt + $w.height(),
et = $e.offset().top,
eb = et + $e.height();
return eb >= wt - th && et <= wb + th;
});
loaded = inview.trigger("unveil");
images = images.not(loaded);
}
$w.scroll(unveil);
$w.resize(unveil);
unveil();
return this;
};
})(window.jQuery || window.Zepto);