diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:25 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:25 +0000 |
commit | d2c5a3255ca77b59775a54ecb70fabc86335296a (patch) | |
tree | 348ae3ff176c7c9c9ebe9624e45a7e12bae61155 /debian/webinterface-default/js/MediaLibrary.js | |
parent | Adding upstream version 2:20.4+dfsg. (diff) | |
download | kodi-d2c5a3255ca77b59775a54ecb70fabc86335296a.tar.xz kodi-d2c5a3255ca77b59775a54ecb70fabc86335296a.zip |
Adding debian version 2:20.4+dfsg-1.debian/2%20.4+dfsg-1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/webinterface-default/js/MediaLibrary.js')
-rwxr-xr-x | debian/webinterface-default/js/MediaLibrary.js | 1420 |
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"> </td><td class="nextAlbum"> </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> </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(' ').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(' ')); + } + $('#albumDetails' + event.data.album.albumid + ' .resultSet').append( + trackRow); + + var trackRow2 = $('<tr>').addClass('fillerTrackRow2'); + trackRow2.append($('<td>').addClass('albumBG').html(' ')); + for (i = 0; i < 5; i++) { + trackRow2.append($('<td>').html(' ')); + } + $('#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°</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'); + } + } +}; |