summaryrefslogtreecommitdiffstats
path: root/debian/webinterface-default/js/MediaLibrary.js
diff options
context:
space:
mode:
Diffstat (limited to 'debian/webinterface-default/js/MediaLibrary.js')
-rwxr-xr-xdebian/webinterface-default/js/MediaLibrary.js1420
1 files changed, 1420 insertions, 0 deletions
diff --git a/debian/webinterface-default/js/MediaLibrary.js b/debian/webinterface-default/js/MediaLibrary.js
new file mode 100755
index 0000000..3c1a1bc
--- /dev/null
+++ b/debian/webinterface-default/js/MediaLibrary.js
@@ -0,0 +1,1420 @@
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+var MediaLibrary = function () {
+ this.init();
+};
+MediaLibrary.prototype = {
+ playlists: {},
+
+ init: function () {
+ this.bindControls();
+ this.getPlaylists();
+ },
+ bindControls: function () {
+ $('#musicLibrary').click(jQuery.proxy(this.musicLibraryOpen, this));
+ $('#movieLibrary').click(jQuery.proxy(this.movieLibraryOpen, this));
+ $('#tvshowLibrary').click(jQuery.proxy(this.tvshowLibraryOpen, this));
+ $('#pictureLibrary').click(jQuery.proxy(this.pictureLibraryOpen, this));
+ $('#remoteControl').click(jQuery.proxy(this.remoteControlOpen, this));
+ $('#profiles').click(jQuery.proxy(this.profilesOpen, this));
+ $('#overlay').click(jQuery.proxy(this.hideOverlay, this));
+ $(window).resize(jQuery.proxy(this.updatePlayButtonLocation, this));
+ $(document).on('keydown', jQuery.proxy(this.handleKeyPress, this));
+ $(document).on('contextmenu', jQuery.proxy(this.handleContextMenu, this));
+ },
+ resetPage: function () {
+ $('#musicLibrary').removeClass('selected');
+ $('#movieLibrary').removeClass('selected');
+ $('#tvshowLibrary').removeClass('selected');
+ $('#remoteControl').removeClass('selected');
+ $('#pictureLibrary').removeClass('selected');
+ $('#profiles').removeClass('selected');
+ this.hideOverlay();
+ },
+ replaceAll: function (haystack, needle, thread) {
+ return (haystack || '').split(needle || '').join(thread || '');
+ },
+ getPlaylists: function () {
+ xbmc.rpc.request({
+ 'context': this,
+ 'method': 'Playlist.GetPlaylists',
+ 'timeout': 3000,
+ 'success': function (data) {
+ if (data && data.result && data.result.length > 0) {
+ $.each($(data.result), jQuery.proxy(function (i, item) {
+ this.playlists[item.type] = item.playlistid;
+ }, this));
+ }
+ },
+ 'error': function (data, error) {
+ xbmc.core.displayCommunicationError();
+ setTimeout(jQuery.proxy(this.updateState, this), 2000);
+ }
+ });
+ },
+ remoteControlOpen: function (event) {
+ this.resetPage();
+ this.textBuffer = '';
+ $('#remoteControl').addClass('selected');
+ $('.contentContainer').hide();
+ var libraryContainer = $('#remoteContainer');
+ if (!libraryContainer || libraryContainer.length === 0) {
+ $('#spinner').show();
+ libraryContainer = $('<div>');
+ libraryContainer.attr('id', 'remoteContainer')
+ .addClass('contentContainer');
+ $('#content').append(libraryContainer);
+ var keys = [{
+ name: 'up',
+ width: '40px',
+ height: '30px',
+ top: '28px',
+ left: '58px'
+ },
+ {
+ name: 'down',
+ width: '40px',
+ height: '30px',
+ top: '122px',
+ left: '58px'
+ },
+ {
+ name: 'left',
+ width: '40px',
+ height: '30px',
+ top: '74px',
+ left: '15px'
+ },
+ {
+ name: 'right',
+ width: '40px',
+ height: '30px',
+ top: '74px',
+ left: '104px'
+ },
+ {
+ name: 'ok',
+ width: '40px',
+ height: '30px',
+ top: '74px',
+ left: '58px'
+ },
+ {
+ name: 'back',
+ width: '40px',
+ height: '30px',
+ top: '13px',
+ left: '161px'
+ },
+ {
+ name: 'home',
+ width: '40px',
+ height: '30px',
+ top: '154px',
+ left: '8px'
+ },
+ {
+ name: 'mute',
+ width: '40px',
+ height: '30px',
+ top: '107px',
+ left: '391px'
+ },
+ {
+ name: 'power',
+ width: '30px',
+ height: '30px',
+ top: '-3px',
+ left: '13px'
+ },
+ {
+ name: 'volumeup',
+ width: '30px',
+ height: '30px',
+ top: '49px',
+ left: '422px'
+ },
+ {
+ name: 'volumedown',
+ width: '30px',
+ height: '30px',
+ top: '49px',
+ left: '367px'
+ },
+ {
+ name: 'playpause',
+ width: '32px',
+ height: '23px',
+ top: '62px',
+ left: '260px'
+ },
+ {
+ name: 'stop',
+ width: '32px',
+ height: '23px',
+ top: '62px',
+ left: '211px'
+ },
+ {
+ name: 'next',
+ width: '38px',
+ height: '25px',
+ top: '102px',
+ left: '304px'
+ },
+ {
+ name: 'previous',
+ width: '38px',
+ height: '25px',
+ top: '101px',
+ left: '160px'
+ },
+ {
+ name: 'forward',
+ width: '32px',
+ height: '23px',
+ top: '102px',
+ left: '259px'
+ },
+ {
+ name: 'rewind',
+ width: '32px',
+ height: '23px',
+ top: '101px',
+ left: '211px'
+ },
+ {
+ name: 'cleanlib_a',
+ width: '46px',
+ height: '26px',
+ top: '47px',
+ left: '553px'
+ },
+ {
+ name: 'updatelib_a',
+ width: '46px',
+ height: '26px',
+ top: '47px',
+ left: '492px'
+ },
+ {
+ name: 'cleanlib_v',
+ width: '46px',
+ height: '26px',
+ top: '111px',
+ left: '553px'
+ },
+ {
+ name: 'updatelib_v',
+ width: '46px',
+ height: '26px',
+ top: '111px',
+ left: '492px'
+ }
+ ];
+ for (var akey in keys) {
+ var aremotekey = $('<p>').attr('id', keys[akey]['name']);
+ aremotekey.addClass('remote_key')
+ .css('height', keys[akey]['height'])
+ .css('width', keys[akey]['width'])
+ .css('top', keys[akey]['top'])
+ .css('left', keys[akey]['left'])
+ .bind('click', {
+ key: keys[akey]['name']
+ }, jQuery.proxy(this.pressRemoteKey, this));
+ libraryContainer.append(aremotekey);
+ }
+ } else {
+ libraryContainer.show();
+ libraryContainer.trigger('scroll');
+ }
+
+ $('#spinner').hide();
+ },
+ shouldHandleEvent: function (event) {
+ var inRemoteControl = $('#remoteControl').hasClass('selected');
+ return (!event.ctrlKey && !event.altKey && inRemoteControl);
+ },
+ handleKeyPress: function (event) {
+ if (!this.shouldHandleEvent(event)) {
+ return true;
+ }
+
+ var keys = {
+ 8: 'back', // Back space
+ 13: 'ok', // Enter
+ 27: 'home', // Escape
+ 32: 'playpause', // Space bar
+ 37: 'left', // Left
+ 38: 'up', // Up
+ 39: 'right', // Right
+ 40: 'down', // Down
+ 93: 'contextmenu', // "Right Click"
+ 107: 'volumeup', // + (num keypad)
+ 109: 'volumedown', // - (num keypad)
+ 187: 'volumeup', // + (alnum keypad)
+ 189: 'volumedown' // - (alnum keypad)
+ };
+ var which = event.which;
+ var key = keys[which];
+
+ event.data = {
+ key: key
+ };
+
+ if (!key) {
+ event.data.key = 'text';
+
+ if (event.key && event.key.length === 1) {
+ event.data.text = event.key;
+ } else {
+ // Letters
+ if (which >= 65 && which <= 90) {
+ var offset = event.shiftKey ? 0 : 32;
+ event.data.text = String.fromCharCode(which + offset);
+ }
+
+ // Digits
+ if (which >= 96 && which <= 105) {
+ event.data.text = (which - 96) + "";
+ }
+ }
+ }
+
+ if (event.data.key) {
+ this.pressRemoteKey(event);
+ return false;
+ }
+ },
+ handleContextMenu: function (event) {
+ if (!this.shouldHandleEvent(event)) {
+ return true;
+ }
+ if (
+ (event.target == document) || //Chrome/Opera
+ (event.clientX === event.clientY && event.clientX === 0) //FF/IE
+ ) {
+ return false;
+ } //keyboard event. cancel it.
+ return true;
+ },
+ rpcCall: function (method, params) {
+ var callObj = {
+ 'method': method
+ };
+ if (params) {
+ callObj.params = params;
+ }
+ return xbmc.rpc.request(callObj);
+ },
+ typeRemoteText: function (event) {
+ if (event.data.key === 'text' || ((event.data.key === 'playpause' || event.data.key === 'back') && this
+ .textBuffer.length)) {
+ if (event.data.key === 'back') {
+ this.textBuffer = this.textBuffer.substring(0, this.textBuffer.length - 1);
+ } else if (event.data.key === 'playpause') {
+ this.textBuffer += ' ';
+ } else if (event.data.text && event.data.text.length) {
+ this.textBuffer += event.data.text;
+ }
+ console.log(this.textBuffer);
+ return this.rpcCall('Input.SendText', {
+ 'text': this.textBuffer,
+ 'done': false
+ });
+ } else {
+ this.textBuffer = '';
+ }
+ },
+ pressRemoteKey: function (event) {
+ var player = -1,
+ keyPressed = event.data.key;
+ $('#spinner').show();
+ if (this.typeRemoteText(event)) {
+ return true;
+ }
+
+ switch (keyPressed) {
+ case 'up':
+ return this.rpcCall('Input.Up');
+ case 'down':
+ return this.rpcCall('Input.Down');
+ case 'left':
+ return this.rpcCall('Input.Left');
+ case 'right':
+ return this.rpcCall('Input.Right');
+ case 'ok':
+ return this.rpcCall('Input.Select');
+ case 'cleanlib_a':
+ return this.rpcCall('AudioLibrary.Clean');
+ case 'updatelib_a':
+ return this.rpcCall('AudioLibrary.Scan');
+ case 'cleanlib_v':
+ return this.rpcCall('VideoLibrary.Clean');
+ case 'updatelib_v':
+ return this.rpcCall('VideoLibrary.Scan');
+ case 'back':
+ return this.rpcCall('Input.Back');
+ case 'home':
+ return this.rpcCall('Input.Home');
+ case 'power':
+ return this.rpcCall('System.Shutdown');
+ case 'contextmenu':
+ return this.rpcCall('Input.ContextMenu');
+ case 'mute':
+ return this.rpcCall('Application.SetMute', {
+ 'mute': 'toggle'
+ });
+ case 'volumeup':
+ return this.rpcCall('Application.SetVolume', {
+ 'volume': 'increment'
+ });
+ case 'volumedown':
+ return this.rpcCall('Application.SetVolume', {
+ 'volume': 'decrement'
+ });
+ }
+
+ // TODO: Get active player
+ if ($('#videoDescription').is(':visible')) {
+ player = this.playlists["video"];
+ } else if ($('#audioDescription').is(':visible')) {
+ player = this.playlists["audio"];
+ }
+
+ if (player >= 0) {
+ switch (keyPressed) {
+ case 'playpause':
+ return this.rpcCall('Player.PlayPause', {
+ 'playerid': player
+ });
+ case 'stop':
+ return this.rpcCall('Player.Stop', {
+ 'playerid': player
+ });
+ case 'next':
+ return this.rpcCall('Player.GoTo', {
+ 'playerid': player,
+ 'to': 'next'
+ });
+ case 'previous':
+ return this.rpcCall('Player.GoTo', {
+ 'playerid': player,
+ 'to': 'previous'
+ });
+ case 'forward':
+ return this.rpcCall('Player.SetSpeed', {
+ 'playerid': player,
+ 'speed': 'increment'
+ });
+ case 'rewind':
+ return this.rpcCall('Player.SetSpeed', {
+ 'playerid': player,
+ 'speed': 'decrement'
+ });
+ }
+ }
+ },
+ musicLibraryOpen: function (event) {
+ this.resetPage();
+ $('#musicLibrary').addClass('selected');
+ $('.contentContainer').hide();
+ var libraryContainer = $('#libraryContainer');
+ if (!libraryContainer || libraryContainer.length === 0) {
+ $('#spinner').show();
+ libraryContainer = $('<div>');
+ libraryContainer.attr('id', 'libraryContainer')
+ .addClass('contentContainer');
+ $('#content').append(libraryContainer);
+ xbmc.rpc.request({
+ 'context': this,
+ 'method': 'AudioLibrary.GetAlbums',
+ 'params': {
+ 'limits': {
+ 'start': 0
+ },
+ 'properties': [
+ 'description',
+ 'theme',
+ 'mood',
+ 'style',
+ 'type',
+ 'albumlabel',
+ 'artist',
+ 'genre',
+ 'rating',
+ 'title',
+ 'year',
+ 'thumbnail'
+ ],
+ 'sort': {
+ 'method': 'artist'
+ }
+ },
+ 'success': function (data) {
+ if (data && data.result && data.result.albums) {
+ this.albumList = data.result.albums;
+ $.each($(this.albumList), jQuery.proxy(function (i, item) {
+ var floatableAlbum = this.generateThumb('album', item
+ .thumbnail, item.title, item.artist);
+ floatableAlbum.bind('click', {
+ album: item
+ }, jQuery.proxy(this.displayAlbumDetails, this));
+ libraryContainer.append(floatableAlbum);
+ }, this));
+ libraryContainer.append($('<div>').addClass('footerPadding'));
+ $('#spinner').hide();
+ libraryContainer.bind('scroll', {
+ activeLibrary: libraryContainer
+ }, jQuery.proxy(this.updateScrollEffects, this));
+ libraryContainer.trigger('scroll');
+ myScroll = new iScroll('libraryContainer');
+ } else {
+ libraryContainer.html('');
+ }
+ }
+ });
+ } else {
+ libraryContainer.show();
+ libraryContainer.trigger('scroll');
+ }
+ },
+ getThumbnailPath: function (thumbnail) {
+ return thumbnail ? ('image/' + encodeURI(thumbnail)) : xbmc.core.DEFAULT_ALBUM_COVER;
+ },
+ generateThumb: function (type, thumbnail, title, artist) {
+ title = title || '';
+ artist = artist || '';
+
+ var showTitle = title,
+ showArtist = artist;
+ var floatableAlbum = $('<div>');
+ var path = this.getThumbnailPath(thumbnail);
+ if (title.length > 21) {
+ showTitle = $.trim(title.substr(0, 18)) + '...';
+ }
+ if (artist.length > 22) {
+ showArtist = $.trim(artist.substr(0, 20)) + '...';
+ }
+ var className = '';
+ var code = '';
+ switch (type) {
+ case 'album':
+ className = 'floatableAlbum';
+ code = '<p class="album" title="' + title + '">' + showTitle + '</p><p class="artist" title="' +
+ artist + '">' + artist + '</p>';
+ break;
+ case 'movie':
+ className = 'floatableMovieCover';
+ code = '<p class="album" title="' + title + '">' + showTitle + '</p>';
+ break;
+ case 'tvshow':
+ className = 'floatableTVShowCover';
+ break;
+ case 'tvshowseason':
+ className = 'floatableTVShowCoverSeason';
+ break;
+ case 'image':
+ case 'directory':
+ className = 'floatableAlbum';
+ code = '<p class="album" title="' + title + '">' + showTitle + '</p>';
+ break;
+ case 'profile':
+ className = 'floatableProfileThumb';
+ code = '<p class="album" title="' + title + '">' + showTitle + '</p>';
+ break;
+ }
+ return floatableAlbum.addClass(className).html('<div class="imgWrapper"><div class="inner"><img src="' +
+ path + '" alt="' + title + '" /></div></div>' + code);
+ },
+ showAlbumSelectorBlock: function (album) {
+ if (album) {
+ var prevAlbum = null,
+ nextAlbum = null;
+ $.each($(this.albumList), jQuery.proxy(function (i, item) {
+ if (item.albumid == album.albumid) {
+ if (this.albumList.length > 1) {
+ prevAlbum = this.albumList[i <= 0 ? this.albumList.length - 1 : i - 1];
+ nextAlbum = this.albumList[i >= this.albumList.length ? 0 : i + 1];
+ }
+ return false; /* .each break */
+ }
+ }, this));
+ var albumSelectorBlock = $('#albumSelector');
+ if (!albumSelectorBlock || albumSelectorBlock.length === 0) {
+ albumSelectorBlock = $('<div>');
+ albumSelectorBlock.attr('id', 'albumSelector')
+ .html(
+ '<table><tr><td class="allAlbums">All Albums</td><td class="activeAlbumTitle"></td>' +
+ '<td class="prevAlbum">&nbsp;</td><td class="nextAlbum">&nbsp;</td></tr></table>'
+ );
+ $('#content').prepend(albumSelectorBlock);
+ $('#albumSelector .allAlbums').bind('click', jQuery.proxy(this.hideAlbumDetails, this));
+ }
+ $('#albumSelector .prevAlbum').unbind();
+ $('#albumSelector .nextAlbum').unbind();
+ if (prevAlbum) {
+ $('#albumSelector .prevAlbum').bind('click', {
+ album: prevAlbum
+ }, jQuery.proxy(this.displayAlbumDetails, this));
+ }
+ if (nextAlbum) {
+ $('#albumSelector .nextAlbum').bind('click', {
+ album: nextAlbum
+ }, jQuery.proxy(this.displayAlbumDetails, this));
+ }
+ $('#albumSelector .activeAlbumTitle').html(album.title || 'Unknown Album');
+ albumSelectorBlock.show();
+ }
+ },
+ hideAlbumDetails: function () {
+ $('.contentContainer').hide();
+ this.musicLibraryOpen();
+ },
+ displayAlbumDetails: function (event) {
+ this.showAlbumSelectorBlock(event.data.album);
+ var albumDetailsContainer = $('#albumDetails' + event.data.album.albumid);
+ $('#topScrollFade').hide();
+ if (!albumDetailsContainer || albumDetailsContainer.length === 0) {
+ $('#spinner').show();
+ xbmc.rpc.request({
+ 'context': this,
+ 'method': 'AudioLibrary.GetSongs',
+ 'params': {
+ 'properties': [
+ 'title',
+ 'artist',
+ 'genre',
+ 'track',
+ 'duration',
+ 'year',
+ 'rating',
+ 'playcount'
+ ],
+ 'sort': {
+ 'method': 'track'
+ },
+ 'filter': {
+ 'albumid': event.data.album.albumid
+ }
+ },
+ 'success': function (data) {
+ albumDetailsContainer = $('<div>');
+ albumDetailsContainer.attr('id', 'albumDetails' + event.data.album.albumid)
+ .addClass('contentContainer')
+ .addClass('albumContainer')
+ .html(
+ '<table class="albumView"><thead><tr class="headerRow"><th>Artwork</th><th>&nbsp;</th>' +
+ '<th>Name</th><th class="time">Time</th><th>Artist</th><th>Genre</th></tr></thead>' +
+ '<tbody class="resultSet"></tbody></table>'
+ );
+ $('.contentContainer').hide();
+ $('#content').append(albumDetailsContainer);
+ var albumThumbnail = event.data.album.thumbnail;
+ var albumTitle = event.data.album.title || 'Unknown Album';
+ var albumArtist = event.data.album.artist.join(', ') || 'Unknown Artist';
+ var trackCount = data.result.limits.total;
+ $.each($(data.result.songs), jQuery.proxy(function (i, item) {
+ var trackRow, trackNumberTD;
+ if (i === 0) {
+ trackRow = $('<tr>').addClass('trackRow').addClass('tr' +
+ i % 2);
+ trackRow.append($('<td>').attr('rowspan', ++trackCount + 1)
+ .addClass('albumThumb'));
+ for (var a = 0; a < 5; a++) {
+ trackRow.append($('<td>').html('&nbsp').attr('style',
+ 'display: none'));
+ }
+ $('#albumDetails' + event.data.album.albumid +
+ ' .resultSet').append(trackRow);
+ }
+ trackRow = $('<tr>').addClass('trackRow').addClass('tr' + i % 2)
+ .bind('click', {
+ album: event.data.album,
+ itmnbr: i
+ }, jQuery.proxy(this.playTrack, this));
+ trackNumberTD = $('<td>').html(item.track);
+
+ trackRow.append(trackNumberTD);
+ var trackTitleTD = $('<td>').html(item.title);
+
+ trackRow.append(trackTitleTD);
+ var trackDurationTD = $('<td>')
+ .addClass('time')
+ .html(xbmc.core.durationToString(item.duration));
+
+ trackRow.append(trackDurationTD);
+ var trackArtistTD = $('<td>').html(item.artist.join(', '));
+
+ trackRow.append(trackArtistTD);
+ var trackGenreTD = $('<td>').html(item.genre.join(', '));
+
+ trackRow.append(trackGenreTD);
+ $('#albumDetails' + event.data.album.albumid + ' .resultSet')
+ .append(trackRow);
+ }, this));
+ if (trackCount > 0) {
+ var trackRow = $('<tr>').addClass('fillerTrackRow'),
+ i;
+ for (i = 0; i < 5; i++) {
+ trackRow.append($('<td>').html('&nbsp'));
+ }
+ $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(
+ trackRow);
+
+ var trackRow2 = $('<tr>').addClass('fillerTrackRow2');
+ trackRow2.append($('<td>').addClass('albumBG').html('&nbsp'));
+ for (i = 0; i < 5; i++) {
+ trackRow2.append($('<td>').html('&nbsp'));
+ }
+ $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(
+ trackRow2);
+ }
+ $('#albumDetails' + event.data.album.albumid + ' .albumThumb')
+ .append(this.generateThumb('album', albumThumbnail, albumTitle,
+ albumArtist))
+ .append($('<div>').addClass('footerPadding'));
+ $('#spinner').hide();
+ myScroll = new iScroll('albumDetails' + event.data.album.albumid);
+ }
+ });
+ } else {
+ $('.contentContainer').hide();
+ $('#albumDetails' + event.data.album.albumid).show();
+ }
+ },
+ togglePosterView: function (event) {
+ var view = event.data.mode;
+ var wthumblist, hthumblist, hthumbdetails;
+ $("#toggleBanner").removeClass('activeMode');
+ $("#togglePoster").removeClass('activeMode');
+ $("#toggleLandscape").removeClass('activeMode');
+ switch (view) {
+ case 'landscape':
+ xbmc.core.setCookie('TVView', 'landscape');
+ wthumblist = '210px';
+ hthumblist = '118px';
+ hthumbdetails = '213px';
+ $("#toggleLandscape").addClass('activeMode');
+ break;
+ case 'banner':
+ xbmc.core.setCookie('TVView', 'banner');
+ wthumblist = '379px';
+ hthumblist = '70px';
+ hthumbdetails = '70px';
+ $("#toggleBanner").addClass('activeMode');
+ break;
+ default:
+ xbmc.core.setCookie('TVView', 'poster');
+ wthumblist = '135px';
+ hthumblist = '199px';
+ hthumbdetails = '559px';
+ $("#togglePoster").addClass('activeMode');
+ break;
+ }
+ $(".floatableTVShowCover, .floatableTVShowCover div.imgWrapper, .floatableTVShowCover img, " +
+ ".floatableTVShowCover div.imgWrapper div.inner")
+ .css('width', wthumblist).css('height', hthumblist);
+ $(".floatableTVShowCoverSeason div.imgWrapper, .floatableTVShowCoverSeason div.imgWrapper div.inner," +
+ ".floatableTVShowCoverSeason img, .floatableTVShowCoverSeason")
+ .css('height', hthumbdetails);
+ },
+ displayTVShowDetails: function (event) {
+ var tvshowDetailsContainer = $('#tvShowDetails' + event.data.tvshow.tvshowid);
+ $('#topScrollFade').hide();
+ toggle = this.toggle.detach();
+ if (!tvshowDetailsContainer || tvshowDetailsContainer.length === 0) {
+ $('#spinner').show();
+ xbmc.rpc.request({
+ 'context': this,
+ 'method': 'VideoLibrary.GetSeasons',
+ 'params': {
+ 'properties': [
+ 'season',
+ 'showtitle',
+ 'playcount',
+ 'episode',
+ 'thumbnail',
+ 'fanart'
+ ],
+ 'tvshowid': event.data.tvshow.tvshowid
+ },
+ 'success': function (data) {
+ tvshowDetailsContainer = $('<div>');
+ tvshowDetailsContainer.attr('id', 'tvShowDetails' + event.data.tvshow.tvshowid)
+ .css('display', 'none')
+ .addClass('contentContainer')
+ .addClass('tvshowContainer');
+ var showThumb = this.generateThumb('tvshowseason', event.data.tvshow.thumbnail,
+ event.data.tvshow.title);
+ if (data && data.result && data.result.seasons && data.result.seasons.length >
+ 0) {
+ var showDetails = $('<div>').addClass('showDetails');
+ showDetails.append(toggle);
+ showDetails.append($('<p>').html(data.result.seasons[0].showtitle).addClass(
+ 'showTitle'));
+ var seasonSelectionSelect = $('<select>').addClass('seasonPicker');
+ this.tvActiveShowContainer = tvshowDetailsContainer;
+ $.each($(data.result.seasons), function (i, item) {
+ var season = $('<option>').attr('value', i);
+ season.text(item.label);
+ seasonSelectionSelect.append(season);
+ });
+ seasonSelectionSelect.bind('change', {
+ tvshow: event.data.tvshow.tvshowid,
+ seasons: data.result.seasons,
+ element: seasonSelectionSelect
+ }, jQuery.proxy(this.displaySeasonListings, this));
+ showDetails.append(seasonSelectionSelect);
+ tvshowDetailsContainer.append(showDetails);
+ tvshowDetailsContainer.append(showThumb);
+ seasonSelectionSelect.trigger('change');
+ $('#content').append(tvshowDetailsContainer);
+ if (xbmc.core.getCookie('TVView') !== null &&
+ xbmc.core.getCookie('TVView') !== 'banner'
+ ) {
+ var view = xbmc.core.getCookie('TVView');
+ switch (view) {
+ case 'poster':
+ togglePoster.trigger('click');
+ break;
+ case 'landscape':
+ toggleLandscape.trigger('click');
+ break;
+ }
+ }
+ tvshowDetailsContainer.fadeIn();
+ }
+ $('#spinner').hide();
+ }
+ });
+ } else {
+ $('.contentContainer').hide();
+ $('#tvShowDetails' + event.data.tvshow.tvshowid).show();
+ $('#tvShowDetails' + event.data.tvshow.tvshowid + ' select').trigger('change');
+ }
+ },
+ displaySeasonListings: function (event) {
+ var selectedVal = event.data.element.val();
+ var seasons = event.data.seasons;
+ $('#topScrollFade').hide();
+ var oldListings = $('.episodeListingsContainer', this.tvActiveShowContainer).fadeOut();
+ this.tvActiveSeason = selectedVal;
+ xbmc.rpc.request({
+ 'context': this,
+ 'method': 'VideoLibrary.GetEpisodes',
+ 'params': {
+ 'properties': [
+ 'title',
+ 'thumbnail',
+ 'episode',
+ 'plot',
+ 'season'
+ ],
+ 'season': seasons[selectedVal].season,
+ 'tvshowid': event.data.tvshow
+ },
+ 'success': function (data) {
+ var episodeListingsContainer = $('<div>').addClass('episodeListingsContainer');
+ var episodeTable = $('<table>').addClass('seasonView').html(
+ '<thead><tr class="headerRow"><th class="thumbHeader">N&deg;</th><th>Title</th>' +
+ '<th class="thumbHeader">Thumb</th><th class="thumbHeader">Details</th></tr></thead>' +
+ '<tbody class="resultSet"></tbody>'
+ );
+ $.each($(data.result.episodes), jQuery.proxy(function (i, item) {
+ var episodeRow = $('<tr>').addClass('episodeRow').addClass('tr' +
+ i % 2);
+ var episodePictureImg = $('<img>').bind('click', {
+ episode: item
+ }, jQuery.proxy(this.playTVShow, this)).css('cursor', 'pointer');
+ episodePictureImg.attr('src', this.getThumbnailPath(item
+ .thumbnail));
+ var episodePicture = $('<td>').addClass('episodeThumb').append(
+ episodePictureImg).bind('click', {
+ episode: item
+ }, jQuery.proxy(this.playTVShow, this));
+ var episodeNumber = $('<td>').addClass('episodeNumber').html(item
+ .episode).bind('click', {
+ episode: item
+ }, jQuery.proxy(this.playTVShow, this));
+ var episodeTitle = $('<td>').html(item.title).bind('click', {
+ episode: item
+ }, jQuery.proxy(this.playTVShow, this));
+ var episodeDetails = $('<td class="info">').html('').bind('click', {
+ episode: item
+ }, jQuery.proxy(this.displayEpisodeDetails, this)).css('cursor',
+ 'pointer');
+ episodeRow.append(episodeNumber).append(episodeTitle).append(
+ episodePicture).append(episodeDetails);
+ episodeTable.append(episodeRow);
+ }, this));
+ episodeListingsContainer.append(episodeTable);
+ $(this.tvActiveShowContainer).append(episodeListingsContainer);
+ }
+ });
+ },
+ displayEpisodeDetails: function (event) {
+ var episodeDetails = $('<div>').attr('id', 'episode-' + event.data.episode.episodeid).addClass(
+ 'episodePopoverContainer');
+ episodeDetails.append($('<img>').attr('src', 'images/close-button.png').addClass('closeButton').bind(
+ 'click', jQuery.proxy(this.hideOverlay, this)));
+ episodeDetails.append($('<img>').attr('src', this.getThumbnailPath(event.data.episode.thumbnail))
+ .addClass('episodeCover'));
+ episodeDetails.append($('<div>').addClass('playIcon').bind('click', {
+ episode: event.data.episode
+ }, jQuery.proxy(this.playTVShow, this)));
+ var episodeTitle = $('<p>').addClass('episodeTitle');
+ var yearText = event.data.episode.year ? ' <span class="year">(' + event.data.episode.year +
+ ')</span>' : '';
+ episodeTitle.html(event.data.episode.title + yearText);
+ episodeDetails.append(episodeTitle);
+ if (event.data.episode.runtime) {
+ episodeDetails.append($('<p>').addClass('runtime').html('<strong>Runtime:</strong> ' + Math.ceil(
+ event.data.episode.runtime / 60) + ' minutes'));
+ }
+ if (event.data.episode.season) {
+ episodeDetails.append($('<p>').addClass('season').html('<strong>Season:</strong> ' + event.data
+ .episode.season));
+ }
+ if (event.data.episode.episode) {
+ episodeDetails.append($('<p>').addClass('episode').html('<strong>Episode:</strong> ' + event.data
+ .episode.episode));
+ }
+ if (event.data.episode.plot) {
+ episodeDetails.append($('<p>').addClass('plot').html('<strong>Plot:</strong> <br/><br/>' + event
+ .data.episode.plot));
+ }
+ if (event.data.episode.genre) {
+ episodeDetails.append($('<p>').addClass('genre').html('<strong>Genre:</strong> ' + event.data
+ .episode.genre));
+ }
+ if (event.data.episode.director) {
+ episodeDetails.append($('<p>').addClass('director').html('<strong>Directed By:</strong> ' + event
+ .data.episode.director));
+ }
+ this.activeCover = episodeDetails;
+ $('body').append(episodeDetails);
+ $('#overlay').show();
+ this.updatePlayButtonLocation();
+ },
+ playTVShow: function (event) {
+ xbmc.rpc.request({
+ 'context': this,
+ 'method': 'Player.Open',
+ 'params': {
+ 'item': {
+ 'episodeid': event.data.episode.episodeid
+ }
+ },
+ 'success': function (data) {
+ this.hideOverlay();
+ }
+ });
+ },
+ hideOverlay: function (event) {
+ if (this.activeCover) {
+ $(this.activeCover).remove();
+ this.activeCover = null;
+ }
+ $('#overlay').hide();
+ },
+ updatePlayButtonLocation: function (event) {
+ var movieContainer = $('.movieCover'),
+ playIcon;
+ if (movieContainer.length > 0) {
+ playIcon = $('.playIcon');
+ if (playIcon.length > 0) {
+ var heightpi = $(movieContainer[0]).height();
+ playIcon.width(Math.floor(0.65 * heightpi));
+ playIcon.height(heightpi);
+ }
+ }
+ var episodeContainer = $('.episodeCover');
+ if (episodeContainer.length > 0) {
+ playIcon = $('.playIcon');
+ if (playIcon.length > 0) {
+ var widthpi = $(episodeContainer[0]).width();
+ playIcon.width(widthpi);
+ //assume 16/9 thumb
+ playIcon.height(Math.floor(widthpi * 9 / 16));
+ }
+ }
+ },
+ playMovie: function (event) {
+ xbmc.rpc.request({
+ 'context': this,
+ 'method': 'Player.Open',
+ 'params': {
+ 'item': {
+ 'movieid': event.data.movie.movieid
+ }
+ },
+ 'success': function (data) {
+ this.hideOverlay();
+ }
+ });
+ },
+ displayMovieDetails: function (event) {
+ var movieDetails = $('<div>').attr('id', 'movie-' + event.data.movie.movieid).addClass(
+ 'moviePopoverContainer');
+ movieDetails.append($('<img>').attr('src', 'images/close-button.png').addClass('closeButton').bind(
+ 'click', jQuery.proxy(this.hideOverlay, this)));
+ movieDetails.append($('<img>').attr('src', this.getThumbnailPath(event.data.movie.thumbnail)).addClass(
+ 'movieCover'));
+ movieDetails.append($('<div>').addClass('playIcon').bind('click', {
+ movie: event.data.movie
+ }, jQuery.proxy(this.playMovie, this)));
+ var movieTitle = $('<p>').addClass('movieTitle');
+ var yearText = event.data.movie.year ? ' <span class="year">(' + event.data.movie.year + ')</span>' :
+ '';
+ movieTitle.html(event.data.movie.title + yearText);
+ movieDetails.append(movieTitle);
+ if (event.data.movie.runtime) {
+ movieDetails.append($('<p>').addClass('runtime').html('<strong>Runtime:</strong> ' + Math.ceil(event
+ .data.movie.runtime / 60) + ' minutes'));
+ }
+ if (event.data.movie.plot) {
+ movieDetails.append($('<p>').addClass('plot').html(event.data.movie.plot));
+ }
+ if (event.data.movie.genre) {
+ movieDetails.append($('<p>').addClass('genre').html('<strong>Genre:</strong> ' + event.data.movie
+ .genre));
+ }
+ if (event.data.movie.director) {
+ movieDetails.append($('<p>').addClass('director').html('<strong>Directed By:</strong> ' + event.data
+ .movie.director));
+ }
+ this.activeCover = movieDetails;
+ $('body').append(movieDetails);
+ $('#overlay').show();
+ this.updatePlayButtonLocation();
+ },
+ playTrack: function (event) {
+ xbmc.rpc.request({
+ 'context': this,
+ 'method': 'Playlist.Clear',
+ 'params': {
+ 'playlistid': this.playlists["audio"]
+ },
+ 'success': function (data) {
+ xbmc.rpc.request({
+ 'context': this,
+ 'method': 'Playlist.Add',
+ 'params': {
+ 'playlistid': this.playlists["audio"],
+ 'item': {
+ 'albumid': event.data.album.albumid
+ }
+ },
+ 'success': function (data) {
+ xbmc.rpc.request({
+ 'method': 'Player.Open',
+ 'params': {
+ 'item': {
+ 'playlistid': this.playlists["audio"],
+ 'position': event.data.itmnbr
+ }
+ },
+ 'success': function () {}
+ });
+ }
+ });
+ }
+ });
+ },
+ loadProfile: function (event) {
+ return xbmc.rpc.request({
+ 'context': this,
+ 'method': 'Profiles.LoadProfile',
+ 'params': {
+ 'profile': event.data.profile.label
+ }
+ });
+ },
+ movieLibraryOpen: function () {
+ this.resetPage();
+ $('#movieLibrary').addClass('selected');
+ $('.contentContainer').hide();
+ var libraryContainer = $('#movieLibraryContainer');
+ if (!libraryContainer || libraryContainer.length === 0) {
+ $('#spinner').show();
+ xbmc.rpc.request({
+ 'context': this,
+ 'method': 'VideoLibrary.GetMovies',
+ 'params': {
+ 'limits': {
+ 'start': 0
+ },
+ 'properties': [
+ 'genre',
+ 'director',
+ 'trailer',
+ 'tagline',
+ 'plot',
+ 'plotoutline',
+ 'title',
+ 'originaltitle',
+ 'lastplayed',
+ 'runtime',
+ 'year',
+ 'playcount',
+ 'rating',
+ 'thumbnail',
+ 'file'
+ ],
+ 'sort': {
+ 'method': 'sorttitle',
+ 'ignorearticle': true
+ }
+ },
+ 'success': function (data) {
+ if (data && data.result && data.result.movies) {
+ libraryContainer = $('<div>');
+ libraryContainer.attr('id', 'movieLibraryContainer')
+ .addClass('contentContainer');
+ $('#content').append(libraryContainer);
+ } else {
+ libraryContainer.html('');
+ }
+ $.each($(data.result.movies), jQuery.proxy(function (i, item) {
+ var floatableMovieCover = this.generateThumb('movie', item
+ .thumbnail, item.title);
+ floatableMovieCover.bind('click', {
+ movie: item
+ }, jQuery.proxy(this.displayMovieDetails, this));
+ libraryContainer.append(floatableMovieCover);
+ }, this));
+ libraryContainer.append($('<div>').addClass('footerPadding'));
+ $('#spinner').hide();
+ libraryContainer.bind('scroll', {
+ activeLibrary: libraryContainer
+ }, jQuery.proxy(this.updateScrollEffects, this));
+ libraryContainer.trigger('scroll');
+ myScroll = new iScroll('movieLibraryContainer');
+ }
+ });
+ } else {
+ libraryContainer.show();
+ libraryContainer.trigger('scroll');
+ }
+ },
+ tvshowLibraryOpen: function () {
+ this.resetPage();
+ $('#tvshowLibrary').addClass('selected');
+ $('.contentContainer').hide();
+ var libraryContainer = $('#tvshowLibraryContainer');
+ if (!libraryContainer || libraryContainer.length === 0) {
+ $('#spinner').show();
+ toggle = $('<p>').addClass('toggle');
+ togglePoster = $('<span>Poster</span>');
+ togglePoster.attr('id', 'togglePoster')
+ .css('cursor', 'pointer')
+ .bind('click', {
+ mode: 'poster'
+ }, jQuery.proxy(this.togglePosterView, this));
+ toggleBanner = $('<span>Banner</span>');
+ toggleBanner.attr('id', 'toggleBanner')
+ .css('cursor', 'pointer')
+ .addClass('activeMode')
+ .bind('click', {
+ mode: 'banner'
+ }, jQuery.proxy(this.togglePosterView, this));
+ toggleLandscape = $('<span>Landscape</span>');
+ toggleLandscape.attr('id', 'toggleLandscape')
+ .css('cursor', 'pointer')
+ .bind('click', {
+ mode: 'landscape'
+ }, jQuery.proxy(this.togglePosterView, this));
+ toggle.append(toggleBanner).append(' | ').append(togglePoster).append(' | ').append(
+ toggleLandscape);
+ this.toggle = toggle;
+ xbmc.rpc.request({
+ 'context': this,
+ 'method': 'VideoLibrary.GetTVShows',
+ 'params': {
+ 'properties': [
+ 'genre',
+ 'plot',
+ 'title',
+ 'lastplayed',
+ 'episode',
+ 'year',
+ 'playcount',
+ 'rating',
+ 'thumbnail',
+ 'studio',
+ 'mpaa',
+ 'premiered'
+ ],
+ 'sort': {
+ 'method': 'sorttitle',
+ 'ignorearticle': true
+ }
+ },
+ 'success': function (data) {
+ if (data && data.result && data.result.tvshows) {
+ libraryContainer = $('<div>');
+ libraryContainer.append(toggle);
+ libraryContainer.attr('id', 'tvshowLibraryContainer')
+ .addClass('contentContainer');
+ $('#content').append(libraryContainer);
+ } else {
+ libraryContainer.html('');
+ }
+ $.each($(data.result.tvshows), jQuery.proxy(function (i, item) {
+ var floatableTVShowCover = this.generateThumb('tvshow', item
+ .thumbnail, item.title);
+ floatableTVShowCover.bind('click', {
+ tvshow: item
+ }, jQuery.proxy(this.displayTVShowDetails, this));
+ libraryContainer.append(floatableTVShowCover);
+ }, this));
+ libraryContainer.append($('<div>').addClass('footerPadding'));
+ $('#spinner').hide();
+ libraryContainer.bind('scroll', {
+ activeLibrary: libraryContainer
+ }, jQuery.proxy(this.updateScrollEffects, this));
+ libraryContainer.trigger('scroll');
+ myScroll = new iScroll('tvshowLibraryContainer');
+ if (xbmc.core.getCookie('TVView') !== null &&
+ xbmc.core.getCookie('TVView') !== 'banner'
+ ) {
+ var view = xbmc.core.getCookie('TVView');
+ switch (view) {
+ case 'poster':
+ togglePoster.trigger('click');
+ break;
+ case 'landscape':
+ toggleLandscape.trigger('click');
+ break;
+ }
+ }
+ }
+ });
+ } else {
+ libraryContainer.prepend($(".toggle").detach()).show();
+ libraryContainer.trigger('scroll');
+ }
+ },
+ profilesOpen: function () {
+ this.resetPage();
+ $('#profiles').addClass('selected');
+ $('.contentContainer').hide();
+ var libraryContainer = $('#profilesContainer');
+ if (!libraryContainer || libraryContainer.length == 0) {
+ $('#spinner').show();
+ var currentProfile = "";
+ xbmc.rpc.request({
+ 'method': 'Profiles.GetCurrentProfile',
+ 'params': {
+ 'properties': [
+ 'lockmode'
+ ]
+ },
+ 'success': function (data) {
+ if (data)
+ if (data.result)
+ currentProfile = data.result.label;
+ }
+ });
+ xbmc.rpc.request({
+ 'context': this,
+ 'method': 'Profiles.GetProfiles',
+ 'params': {
+ 'limits': {
+ 'start': 0
+ },
+ 'properties': [
+ 'thumbnail'
+ ],
+ 'sort': {
+ 'method': 'sorttitle',
+ 'ignorearticle': true
+ }
+ },
+ 'success': function (data) {
+ if (data && data.result && data.result.profiles) {
+ libraryContainer = $('<div>');
+ libraryContainer.attr('id', 'profilesContainer')
+ .addClass('contentContainer');
+ $('#content').append(libraryContainer);
+ } else {
+ libraryContainer.html('');
+ }
+ $.each($(data.result.profiles), jQuery.proxy(function (i, item) {
+ var itemLabel = item.label;
+ if (currentProfile == itemLabel) {
+ itemLabel = itemLabel + "*";
+ }
+ var floatableProfileThumb = this.generateThumb('profile', item
+ .thumbnail, itemLabel);
+ floatableProfileThumb.bind('click', {
+ profile: item
+ }, jQuery.proxy(this.loadProfile, this));
+ libraryContainer.append(floatableProfileThumb);
+ }, this));
+ libraryContainer.append($('<div>').addClass('footerPadding'));
+ $('#spinner').hide();
+ libraryContainer.bind('scroll', {
+ activeLibrary: libraryContainer
+ }, jQuery.proxy(this.updateScrollEffects, this));
+ libraryContainer.trigger('scroll');
+ myScroll = new iScroll('profilesContainer');
+ }
+ });
+ } else {
+ libraryContainer.show();
+ libraryContainer.trigger('scroll');
+ }
+ },
+ updateScrollEffects: function (event) {
+ if (event.data.activeLibrary && $(event.data.activeLibrary).scrollTop() > 0) {
+ $('#topScrollFade').fadeIn();
+ } else {
+ $('#topScrollFade').fadeOut();
+ }
+ },
+ startSlideshow: function (event) {
+ xbmc.rpc.request({
+ 'method': 'Player.Open',
+ 'params': {
+ 'item': {
+ 'recursive': 'true',
+ 'random': 'true',
+ 'path': this.replaceAll(event.data.directory.file, "\\", "\\\\")
+ }
+ },
+ 'success': function () {}
+ });
+ },
+ showDirectory: function (event) {
+ var directory = event.data.directory.file;
+ var jsonDirectory = this.replaceAll(directory, "\\", "\\\\");
+ this.resetPage();
+ $('#pictureLibrary').addClass('selected');
+ $('.contentContainer').hide();
+ var libraryContainer = $('#pictureLibraryDirContainer' + directory);
+ if (!libraryContainer || libraryContainer.length === 0) {
+ $('#spinner').show();
+ xbmc.rpc.request({
+ 'context': this,
+ 'method': 'Files.GetDirectory',
+ 'params': {
+ 'media': 'pictures',
+ 'directory': jsonDirectory
+ },
+ 'success': function (data) {
+ if (data && data.result && (data.result.directories || data.result.files)) {
+ libraryContainer = $('<div>');
+ libraryContainer.attr('id', 'pictureLibraryDirContainer' + directory)
+ .addClass('contentContainer');
+ $('#content').append(libraryContainer);
+ var breadcrumb = $('<div>');
+ var seperator = '/';
+ var item = '';
+ var directoryArray = directory.split(seperator);
+ jQuery.each(directoryArray, function (i, v) {
+ if (v !== '') {
+ item += v + seperator;
+ breadcrumb.append($('<div>').text(' > ' + v).css('float',
+ 'left').addClass('breadcrumb'));
+ }
+ });
+ libraryContainer.append(breadcrumb);
+ libraryContainer.append($('<div>').css('clear', 'both'));
+ if (data.result.files) {
+ $.each($(data.result.files), jQuery.proxy(function (i, item) {
+ if (item.filetype == "file") {
+ var floatableImage = this.generateThumb('image',
+ item.file, item.label);
+ libraryContainer.append(floatableImage);
+ } else if (item.filetype == "directory") {
+ var floatableShare = this.generateThumb('directory',
+ item.thumbnail, item.label);
+ floatableShare.bind('click', {
+ directory: item
+ }, jQuery.proxy(this.showDirectory, this));
+ libraryContainer.append(floatableShare);
+ }
+ }, this));
+ }
+ libraryContainer.append($('<div>').addClass('footerPadding'));
+ } else {
+ libraryContainer.html('');
+ }
+ $('#spinner').hide();
+ libraryContainer.bind('scroll', {
+ activeLibrary: libraryContainer
+ }, jQuery.proxy(this.updateScrollEffects, this));
+ libraryContainer.trigger('scroll');
+ myScroll = new iScroll('#pictureLibraryDirContainer' + directory);
+ }
+ });
+ } else {
+ libraryContainer.show();
+ libraryContainer.trigger('scroll');
+ }
+ },
+ pictureLibraryOpen: function () {
+ this.resetPage();
+ $('#pictureLibrary').addClass('selected');
+ $('.contentContainer').hide();
+ var libraryContainer = $('#pictureLibraryContainer');
+ if (!libraryContainer || libraryContainer.length === 0) {
+ $('#spinner').show();
+ xbmc.rpc.request({
+ 'context': this,
+ 'method': 'Files.GetSources',
+ 'params': {
+ 'media': 'pictures'
+ },
+ 'success': function (data) {
+ if (data && data.result && data.result.shares) {
+ libraryContainer = $('<div>');
+ libraryContainer.attr('id', 'pictureLibraryContainer')
+ .addClass('contentContainer');
+ $('#content').append(libraryContainer);
+ } else {
+ libraryContainer.html('');
+ }
+ $.each($(data.result.shares), jQuery.proxy(function (i, item) {
+ var floatableShare = this.generateThumb('directory', item
+ .thumbnail, item.label);
+ floatableShare.bind('click', {
+ directory: item
+ }, jQuery.proxy(this.showDirectory, this));
+ libraryContainer.append(floatableShare);
+ }, this));
+ libraryContainer.append($('<div>').addClass('footerPadding'));
+ $('#spinner').hide();
+ libraryContainer.bind('scroll', {
+ activeLibrary: libraryContainer
+ }, jQuery.proxy(this.updateScrollEffects, this));
+ libraryContainer.trigger('scroll');
+ myScroll = new iScroll('#pictureLibraryContainer');
+ }
+ });
+ } else {
+ libraryContainer.show();
+ libraryContainer.trigger('scroll');
+ }
+ }
+};