(function (window, document, $) { function sendPlayFolderCommand(item, sessionId, popup) { ApiClient.getItems(Dashboard.getCurrentUserId(), { ParentId: item.Id, Filters: "IsNotFolder", SortBy: "SortName", Recursive: true, Limit: 100 }).done(function (result) { ApiClient.sendPlayCommand(sessionId, { ItemIds: result.Items.map(function (i) { return i.Id; }).join(','), PlayCommand: $('#fldPlayCommand', popup).val() }); popup.popup("close"); }); } function sendPlayArtistCommand(item, sessionId, popup) { ApiClient.getItems(Dashboard.getCurrentUserId(), { Artists: item.Name, SortBy: "SortName", IncludeItemTypes: "Audio", Recursive: true, Limit: 100 }).done(function (result) { ApiClient.sendPlayCommand(sessionId, { ItemIds: result.Items.map(function (i) { return i.Id; }).join(','), PlayCommand: $('#fldPlayCommand', popup).val() }); popup.popup("close"); }); } function showMenuForItem(options, sessionsPromise) { var playFromRendered; var trailersRendered; var specialFeaturesRendered; var themeVideosRendered; var themeSongsRendered; var item = options.item; var html = '
'; html += 'Close'; html += '
'; html += '
Remote Control
'; html += '
'; html += '
'; html += '
'; html += ''; html += '
'; html += '
'; html += '
'; html += '

'; html += ''; html += ''; html += ''; html += ''; html += '

'; html += '
'; html += '
'; $(document.body).append(html); var popup = $('.remoteControlFlyout').popup({ history: false, tolerance: 0, corners: false }).trigger('create').popup("open").on("popupafterclose", function () { if (ApiClient.isWebSocketOpen()) { ApiClient.sendWebSocketMessage("SessionsStop"); } $(ApiClient).off("websocketmessage.remotecontrol"); $(this).off("popupafterclose").remove(); $('.remoteControlFlyout').popup("destroy").remove(); }); popup.on('click', '.trSession', function () { $('input', this).checked(true); }).on('click', '.trSelectPlayTime', function () { $('input', this).checked(true); }).on('click', '.trItem', function () { $('input', this).checked(true); }); $('#sendToForm', popup).on('submit', function () { var checkboxes = $('.chkClient', popup); if (!checkboxes.length) { $('.remoteControlFlyout').popup("close"); return false; } checkboxes = $('.chkClient:checked', popup); if (!checkboxes.length) { Dashboard.alert('Please select a device to control.'); return false; } var sessionIds = []; checkboxes.parents('.trSession').each(function () { sessionIds.push(this.getAttribute('data-sessionid')); }); var command = $('#selectCommand', popup).val(); var promise; var showRemoteControlMenuAfterCommand = true; if (command == "Play") { if (item.IsFolder) { sendPlayFolderCommand(item, sessionIds[0], popup); return false; } if (item.Type == "MusicArtist") { sendPlayArtistCommand(item, sessionIds[0], popup); return false; } var playCommand = $('#fldPlayCommand', popup).val(); if (playCommand == "Resume") { promise = ApiClient.sendPlayCommand(sessionIds[0], { ItemIds: [item.Id].join(','), PlayCommand: 'PlayNow', StartPositionTicks: item.UserData.PlaybackPositionTicks }); } else if (playCommand == "Browse") { promise = ApiClient.sendBrowseCommand(sessionIds[0], { ItemId: item.Id, ItemName: item.Name, ItemType: item.Type, Context: options.context }); showRemoteControlMenuAfterCommand = false; } else { promise = ApiClient.sendPlayCommand(sessionIds[0], { ItemIds: [item.Id].join(','), PlayCommand: playCommand }); } } else if (command == "PlayFromChapter") { var checkedChapter = $('.chkSelectPlayTime:checked', popup); var ticks = checkedChapter.length ? checkedChapter.parents('.trSelectPlayTime').attr('data-ticks') : 0; promise = ApiClient.sendPlayCommand(sessionIds[0], { ItemIds: [item.Id].join(','), PlayCommand: $('#fldPlayCommand', popup).val(), StartPositionTicks: ticks }); } else if (command == "Trailer" || command == "SpecialFeature" || command == "ThemeSong" || command == "ThemeVideo") { var id = $('.chkSelectItem:checked', popup).parents('.trItem').attr('data-id'); if (!id) { Dashboard.alert('Please select an item.'); return false; } promise = ApiClient.sendPlayCommand(sessionIds[0], { ItemIds: [id].join(','), PlayCommand: $('#fldPlayCommand', popup).val() }); } promise.done(function () { popup.popup("close"); if (showRemoteControlMenuAfterCommand) { RemoteControl.showMenu(); } }); return false; }); var elem = $('.sessionsPopupContent'); sessionsPromise.done(function (sessions) { var deviceId = ApiClient.deviceId(); // don't display the current session sessions = sessions.filter(function (s) { return s.DeviceId != deviceId; }); renderSessionsInPlayMenu(sessions, options, elem, popup); if (ApiClient.isWebSocketOpen()) { ApiClient.sendWebSocketMessage("SessionsStart", "1000,1000"); $(ApiClient).on("websocketmessage.remotecontrol", function (e, msg) { if (msg.MessageType === "Sessions") { updateSessionsInPlayMenu(msg.Data, elem); } }); } $('#selectCommand', popup).on('change', function () { var playFromMenu = $('.playFromMenu', popup).hide(); var trailersElem = $('.trailers', popup).hide(); var specialFeaturesElem = $('.specialFeatures', popup).hide(); var themeSongsElem = $('.themeSongs', popup).hide(); var themeVideosElem = $('.themeVideos', popup).hide(); var playButtonContainer = $('#playButtonContainer', popup).hide(); var queueButtonContainer = $('#queueButtonContainer', popup).hide(); var resumeButtonContainer = $('#resumeButtonContainer', popup).hide(); var browseButtonContainer = $('#browseButtonContainer', popup).hide(); var value = this.value; if (value == "Play") { browseButtonContainer.show(); if (item.Type != 'Person' && item.Type != 'Genre' && item.Type != 'Studio' && item.Type != 'GameGenre' && item.Type != 'MusicGenre' && item.LocationType != 'Virtual') { playButtonContainer.show(); queueButtonContainer.show(); } if (!item.IsFolder && item.UserData && item.UserData.PlaybackPositionTicks) { resumeButtonContainer.show(); } } else if (value == "PlayFromChapter" && item.Chapters && item.Chapters.length) { playFromMenu.show(); playButtonContainer.show(); if (!playFromRendered) { playFromRendered = true; renderPlayFromOptions(playFromMenu, item); } popup.popup("reposition", { tolerance: 0 }); } else if (value == "Trailer") { trailersElem.show(); playButtonContainer.show(); queueButtonContainer.show(); if (!trailersRendered) { trailersRendered = true; ApiClient.getLocalTrailers(Dashboard.getCurrentUserId(), item.Id).done(function (trailers) { renderVideos(trailersElem, trailers, 'Trailers'); popup.popup("reposition", { tolerance: 0 }); }); } } else if (value == "SpecialFeature") { specialFeaturesElem.show(); playButtonContainer.show(); queueButtonContainer.show(); if (!specialFeaturesRendered) { specialFeaturesRendered = true; ApiClient.getSpecialFeatures(Dashboard.getCurrentUserId(), item.Id).done(function (videos) { renderVideos(specialFeaturesElem, videos, 'Special Features'); popup.popup("reposition", { tolerance: 0 }); }); } } else if (value == "ThemeSong") { themeSongsElem.show(); playButtonContainer.show(); queueButtonContainer.show(); if (!themeSongsRendered) { themeSongsRendered = true; ApiClient.getThemeSongs(Dashboard.getCurrentUserId(), item.Id).done(function (result) { renderVideos(themeSongsElem, result.Items, 'Theme Songs'); $('.remoteControlFlyout').popup("reposition", { tolerance: 0 }); }); } } else if (value == "ThemeVideo") { themeVideosElem.show(); playButtonContainer.show(); queueButtonContainer.show(); if (!themeVideosRendered) { themeVideosRendered = true; ApiClient.getThemeVideos(Dashboard.getCurrentUserId(), item.Id).done(function (result) { renderVideos(themeVideosElem, result.Items, 'Theme Videos'); popup.popup("reposition", { tolerance: 0 }); }); } } }).trigger('change'); }); } function renderPlayFromOptions(elem, item) { var html = ''; html += '

Play from scene

'; html += '
'; html += ''; html += ''; for (var i = 0, length = item.Chapters.length; i < length; i++) { var chapter = item.Chapters[i]; html += ''; var name = chapter.Name || ("Chapter " + (i + 1)); html += ''; html += ''; html += ''; html += ''; } html += ''; html += '
'; var imgUrl; if (chapter.ImageTag) { imgUrl = ApiClient.getImageUrl(item.Id, { maxheight: 80, tag: chapter.ImageTag, type: "Chapter", index: i }); } else { imgUrl = "css/images/media/chapterflyout.png"; } html += ''; html += '' + name + '
' + Dashboard.getDisplayTime(chapter.StartPositionTicks) + '
'; html += '
'; elem.html(html); $('.tdSelectPlayTime', elem).html(''); $('.chkSelectPlayTime:first', elem).checked(true); } function renderSessionsInPlayMenu(sessions, options, elem, popup) { if (!sessions.length) { elem.html('

There are currently no available media browser sessions to control.

'); $('.remoteControlFlyout').popup("reposition", {}); return; } var item = options.item; var html = ''; html += '
'; html += ''; html += '
'; html += ''; html += ''; html += ''; html += ''; html += ''; html += '

Select Device

'; html += ''; html += ''; html += ''; html += ''; html += ''; html += ''; for (var i = 0, length = sessions.length; i < length; i++) { var session = sessions[i]; html += ''; html += ''; html += ''; html += ''; } html += ''; html += '
Device
' + session.DeviceName; if (session.UserName) { html += ' - ' + session.UserName; } html += '
'; html += ''; elem.html(html).trigger('create'); $('.tdSelectSession', elem).html(''); $('.chkClient:first', elem).checked(true); } function getSessionNowPlayingTime(session) { var html = ''; if (session.NowPlayingItem) { html += Dashboard.getDisplayTime(session.NowPlayingPositionTicks || 0); if (session.NowPlayingItem.RunTimeTicks) { html += " / "; html += Dashboard.getDisplayTime(session.NowPlayingItem.RunTimeTicks); } } return html; } function updateSessionsInPlayMenu(sessions, elem) { for (var i = 0, length = sessions.length; i < length; i++) { var session = sessions[i]; var sessionElem = $('.trSession[data-sessionid=' + session.Id + ']', elem); $('.tdUserName', sessionElem).html(session.UserName || ''); $('.tdNowPlayingTime', sessionElem).html(getSessionNowPlayingTime(session)); $('.tdNowPlayingName', sessionElem).html(session.NowPlayingItem ? session.NowPlayingItem.Name : ''); } } function renderVideos(elem, videos, header) { var html = ''; html += '

' + header + '

'; html += '
'; html += ''; html += ''; for (var i = 0, length = videos.length; i < length; i++) { var video = videos[i]; html += ''; html += ''; html += ''; html += ''; html += ''; } html += ''; html += '
'; var imgUrl; if (video.ImageTags && video.ImageTags.Primary) { imgUrl = ApiClient.getImageUrl(video.Id, { maxheight: 80, tag: video.ImageTags.Primary, type: "Primary" }); html += ''; } html += '' + video.Name; if (video.RunTimeTicks) { html += '
' + Dashboard.getDisplayTime(video.RunTimeTicks); } html += '
'; html += '
'; elem.html(html); $('.tdSelectItem', elem).html(''); $('.chkSelectItem:first', elem).checked(true); } function showMenu(sessions, options) { var html = '
'; html += 'Close'; html += '
'; html += '
Remote Control
'; html += '
'; html += '
'; html += '
'; // Add controls here html += '
'; html += '
'; html += '
'; html += '
'; html += ''; html += ''; html += '
'; html += ''; html += '
'; html += '
'; $(document.body).append(html); var popup = $('.remoteControlFlyout').popup({ history: false, tolerance: 0, corners: false }).trigger('create').popup("open").on("popupafterclose", function () { if (ApiClient.isWebSocketOpen()) { ApiClient.sendWebSocketMessage("SessionsStop"); } $(ApiClient).off("websocketmessage.remotecontrol"); $(this).off("popupafterclose").remove(); $('.remoteControlFlyout').popup("destroy").remove(); }); renderSessionsInControlMenu(popup, sessions, options); updateSessionInfo(popup, sessions, options); if (ApiClient.isWebSocketOpen()) { ApiClient.sendWebSocketMessage("SessionsStart", "1000,1000"); $(ApiClient).on("websocketmessage.remotecontrol", function (e, msg) { if (msg.MessageType === "Sessions") { // Update existing data updateSessionInfo(popup, msg.Data); } }); } $('.btnGoHome', popup).on('click', function () { var id = $('#selectSession', popup).val(); ApiClient.sendSystemCommand(id, 'GoHome'); }); $('.btnGoToSettings', popup).on('click', function () { var id = $('#selectSession', popup).val(); ApiClient.sendSystemCommand(id, 'GoToSettings'); }); $('.btnSendMessage', popup).on('click', function () { var id = $('#selectSession', popup).val(); var messageText = $('#txtMessage', popup).val(); if (messageText) { Dashboard.getCurrentUser().done(function (user) { ApiClient.sendMessageCommand(id, { Header: "Message from " + user.Name, Text: messageText }); }); } else { $('#txtMessage', popup)[0].focus(); } }); $('.btnVolumeDown', popup).on('click', function () { var id = $('#selectSession', popup).val(); ApiClient.sendSystemCommand(id, 'VolumeDown'); }); $('.btnVolumeUp', popup).on('click', function () { var id = $('#selectSession', popup).val(); ApiClient.sendSystemCommand(id, 'VolumeUp'); }); $('.btnToggleMute', popup).on('click', function () { var id = $('#selectSession', popup).val(); ApiClient.sendSystemCommand(id, 'ToggleMute'); }); $('.btnStop', popup).on('click', function () { var id = $('#selectSession', popup).val(); ApiClient.sendPlayStateCommand(id, 'Stop'); }); $('.btnPause', popup).on('click', function () { var id = $('#selectSession', popup).val(); ApiClient.sendPlayStateCommand(id, 'Pause'); }); $('.btnPlay', popup).on('click', function () { var id = $('#selectSession', popup).val(); ApiClient.sendPlayStateCommand(id, 'Unpause'); }); $('.btnNextTrack', popup).on('click', function () { var id = $('#selectSession', popup).val(); ApiClient.sendPlayStateCommand(id, 'NextTrack'); }); $('.btnPreviousTrack', popup).on('click', function () { var id = $('#selectSession', popup).val(); ApiClient.sendPlayStateCommand(id, 'PreviousTrack'); }); $("#positionSlider", popup).on("slidestart", function () { this.isSliding = true; }).on("slidestop", function () { var id = $('#selectSession', popup).val(); var percent = $(this).val(); var duration = parseInt($(this).attr('data-duration')); var position = duration * percent / 100; ApiClient.sendPlayStateCommand(id, 'Seek', { SeekPositionTicks: parseInt(position) }); this.isSliding = false; }); } function getPlaybackHtml() { var html = ''; html += '

'; html += '

'; html += '
'; html += '
'; html += ''; html += ' / '; html += ''; html += '
'; html += '
'; html += '
'; html += '
'; html += ''; html += ''; html += ''; html += ''; html += ''; html += ''; html += ''; html += ''; html += '
'; return html; } function updateSessionInfo(popup, sessions) { var id = $('#selectSession', popup).val(); // don't display the current session var session = sessions.filter(function (s) { return s.Id == id; })[0]; if (!session) { $('.nothingPlaying', popup).hide(); $('.nowPlaying', popup).hide(); $('.commandsCollapsible', popup).hide(); } else if (session.NowPlayingItem) { $('.commandsCollapsible', popup).show(); $('.nothingPlaying', popup).hide(); var elem = $('.nowPlaying', popup).show(); updateNowPlaying(elem, session); } else { $('.commandsCollapsible', popup).show(); $('.nothingPlaying', popup).show(); $('.nowPlaying', popup).hide(); } } function updateNowPlaying(elem, session) { var item = session.NowPlayingItem; $('.nowPlayingTitle', elem).html(item.Name); var imageContainer = $('.nowPlayingImage', elem); if (item.PrimaryImageTag) { imageContainer.show(); var img = $('img', imageContainer)[0]; var imgUrl = ApiClient.getImageUrl(item.Id, { maxheight: 300, type: 'Primary', tag: item.PrimaryImageTag }); if (!img || img.src.toLowerCase().indexOf(imgUrl.toLowerCase()) == -1) { imageContainer.html(''); } } else { imageContainer.hide(); } if (session.CanSeek) { $('.remotePositionSliderContainer', elem).show(); } else { $('.remotePositionSliderContainer', elem).hide(); } var time = session.NowPlayingPositionTicks || 0; var duration = item.RunTimeTicks || 0; var percent = duration ? 100 * time / duration : 0; var slider = $('#positionSlider', elem); if (!slider[0].isSliding) { slider.val(percent).slider('refresh'); } slider.attr('data-duration', duration); $('.nowPlayingTime', elem).html(Dashboard.getDisplayTime(time)); $('.duration', elem).html(Dashboard.getDisplayTime(duration)); if (session.IsPaused) { $('.btnPauseParent', elem).hide(); $('.btnPlayParent', elem).show(); } else { $('.btnPauseParent', elem).show(); $('.btnPlayParent', elem).hide(); } } function renderSessionsInControlMenu(popup, sessions, options) { options = options || {}; var deviceId = ApiClient.deviceId(); // don't display the current session sessions = sessions.filter(function (s) { return s.DeviceId != deviceId && s.SupportsRemoteControl; }); var elem = $('#selectSession', popup); var currentValue = options.sessionId || elem.val(); if (currentValue) { // Make sure the session is still active var currentSession = sessions.filter(function (s) { return s.Id == currentValue; })[0]; if (!currentSession) { currentValue = null; } } if (!currentValue && sessions.length) { currentValue = sessions[0].Id; } var html = ''; for (var i = 0, length = sessions.length; i < length; i++) { var session = sessions[i]; var text = session.DeviceName; if (session.UserName) { text += ' - ' + session.UserName; } html += ''; } elem.html(html).val(currentValue).selectmenu('refresh'); } function remoteControl() { var self = this; var sessionQuery = { SupportsRemoteControl: true, ControllableByUserId: Dashboard.getCurrentUserId() }; self.showMenuForItem = function (options) { showMenuForItem(options, ApiClient.getSessions(sessionQuery)); }; self.showMenu = function (options) { ApiClient.getSessions(sessionQuery).done(function (sessions) { showMenu(sessions, options); }); }; } window.RemoteControl = new remoteControl(); })(window, document, jQuery);