(function (window, document, $, setTimeout, clearTimeout) {
var currentPlayer;
var lastPlayerState;
function populateChapters(elem, chapters, itemId, runtimeTicks) {
var html = '';
for (var i = 0, length = chapters.length; i < length; i++) {
var chapter = chapters[i];
html += '
';
var imgUrl;
if (chapter.ImageTag) {
imgUrl = ApiClient.getScaledImageUrl(itemId, {
width: 240,
tag: chapter.ImageTag,
type: "Chapter",
index: i
});
} else {
imgUrl = "css/images/items/list/chapter.png";
}
var dataSrc = ' data-src="' + imgUrl + '"';
// TODO: This markup needs to be converted to the newer card layout pattern
html += '
';
html += '
';
if (chapter.Name) {
html += "
";
html += chapter.Name;
html += "
";
}
html += "
";
var pct = 100 * (chapter.StartPositionTicks / runtimeTicks);
html += '
';
html += "
";
html += "
";
html += "
";
html += "
";
}
elem.innerHTML = html;
ImageLoader.lazyChildren(elem);
$(elem).trigger('create');
}
function selectCurrentChapter(elem, positionTicks) {
var elems = $('.chapterPosterItem', elem).removeClass('currentChapter');
var matches = elems.get().filter(function (i) {
var ticks = i.getAttribute('data-positionticks');
return positionTicks >= ticks;
});
var chapterElem = matches[matches.length - 1];
chapterElem.classList.add('currentChapter');
chapterElem.scrollIntoView();
elem.scrollLeft += 50;
}
function showChapterMenu(page, item, currentPositionTicks) {
$('.chapterMenuOverlay', page).show();
var elem = page.querySelector('.chapterMenu');
$(elem).show();
if (item.Id == elem.getAttribute('data-itemid')) {
selectCurrentChapter(elem, currentPositionTicks);
return;
}
var innerElem = elem.querySelector('.chapterMenuInner');
populateChapters(innerElem, item.Chapters, item.Id, item.RunTimeTicks);
elem.setAttribute('data-itemid', item.Id);
selectCurrentChapter(elem, currentPositionTicks);
}
function hideChapterMenu(page) {
$('.chapterMenuOverlay', page).hide();
$('.chapterMenu', page).hide();
}
function showAudioMenu(page, button, item, currentIndex) {
var streams = (item.MediaStreams || []).filter(function (i) {
return i.Type == 'Audio';
});
var menuItems = streams.map(function (s) {
var name = (s.Codec || '').toUpperCase();
if (s.Profile) {
name += ' ' + s.Profile;
}
if (s.Language) {
name += ' · ' + s.Language;
}
if (s.Layout) {
name += ' · ' + s.Layout;
}
else if (s.Channels) {
name += ' · ' + s.Channels + ' ch';
}
var menuItem = {
name: name,
id: s.Index
};
if (s.Index == currentIndex) {
menuItem.ironIcon = 'check';
}
return menuItem;
});
require(['actionsheet'], function () {
ActionSheetElement.show({
items: menuItems,
positionTo: button,
callback: function (id) {
currentPlayer.setAudioStreamIndex(parseInt(id));
}
});
});
}
function showSubtitleMenu(page, button, item, currentIndex) {
var streams = (item.MediaStreams || []).filter(function (i) {
return i.Type == 'Subtitle';
});
var menuItems = streams.map(function (s) {
var name = (s.Language || Globalize.translate('LabelUnknownLanguage'));
if (s.IsDefault && s.IsForced) {
name += ' · ' + Globalize.translate('LabelDefaultForcedStream');
}
else if (s.IsDefault) {
name += ' · ' + Globalize.translate('LabelDefaultStream');
}
else if (s.IsForced) {
name += ' · ' + Globalize.translate('LabelForcedStream');
}
if (s.Codec) {
name += ' · ' + s.Codec.toUpperCase();
}
var menuItem = {
name: name,
id: s.Index
};
if (s.Index == currentIndex) {
menuItem.ironIcon = 'check';
}
return menuItem;
});
require(['actionsheet'], function () {
ActionSheetElement.show({
items: menuItems,
positionTo: button,
callback: function (id) {
currentPlayer.setSubtitleStreamIndex(parseInt(id));
}
});
});
}
function bindEvents(page) {
$('.tabButton', page).on('click', function () {
var elem = $('.' + this.getAttribute('data-tab'), page);
elem.siblings('.tabContent').hide();
elem.show();
$('.tabButton', page).removeClass('ui-btn-active');
$(this).addClass('ui-btn-active');
});
$('.chapterMenuOverlay', page).on('click', function () {
hideChapterMenu(page);
});
$('.chapterMenu', page).on('click', '.chapterPosterItem', function () {
if (currentPlayer) {
var ticks = this.getAttribute('data-positionticks') || '0';
currentPlayer.seek(parseInt(ticks));
}
hideChapterMenu(page);
});
$('.btnCommand,.btnToggleFullscreen', page).on('click', function () {
if (currentPlayer) {
MediaController.sendCommand({
Name: this.getAttribute('data-command')
}, currentPlayer);
}
});
$('.btnAudioTracks', page).on('click', function () {
if (currentPlayer && lastPlayerState && lastPlayerState.PlayState) {
var currentIndex = lastPlayerState.PlayState.AudioStreamIndex;
showAudioMenu(page, this, lastPlayerState.NowPlayingItem, currentIndex);
}
});
$('.btnSubtitles', page).on('click', function () {
if (currentPlayer && lastPlayerState && lastPlayerState.PlayState) {
var currentIndex = lastPlayerState.PlayState.SubtitleStreamIndex;
showSubtitleMenu(page, this, lastPlayerState.NowPlayingItem, currentIndex);
}
});
$('.btnChapters', page).on('click', function () {
if (currentPlayer && lastPlayerState) {
var currentPositionTicks = lastPlayerState.PlayState.PositionTicks;
showChapterMenu(page, lastPlayerState.NowPlayingItem, currentPositionTicks);
}
});
$('.btnStop', page).on('click', function () {
if (currentPlayer) {
currentPlayer.stop();
}
});
$('.btnPlay', page).on('click', function () {
if (currentPlayer) {
currentPlayer.unpause();
}
});
$('.btnPause', page).on('click', function () {
if (currentPlayer) {
currentPlayer.pause();
}
});
$('.btnNextTrack', page).on('click', function () {
if (currentPlayer) {
currentPlayer.nextTrack();
}
});
$('.btnPreviousTrack', page).on('click', function () {
if (currentPlayer) {
currentPlayer.previousTrack();
}
});
$('.nowPlayingPositionSlider', page).on('change', function () {
var value = this.value;
if (currentPlayer && lastPlayerState) {
var newPercent = parseFloat(value);
var newPositionTicks = (newPercent / 100) * lastPlayerState.NowPlayingItem.RunTimeTicks;
currentPlayer.seek(Math.floor(newPositionTicks));
}
});
$('.nowPlayingPositionSlider', page)[0]._setPinValue = function (value) {
var state = lastPlayerState;
if (!state || !state.NowPlayingItem || !state.NowPlayingItem.RunTimeTicks) {
this.pinValue = '--:--';
return;
}
var ticks = state.NowPlayingItem.RunTimeTicks;
ticks /= 100;
ticks *= value;
this.pinValue = Dashboard.getDisplayTime(ticks);
};
$(page).on('click', '.lnkPlayFromIndex', function () {
var index = parseInt(this.getAttribute('data-index'));
MediaController.currentPlaylistIndex(index);
loadPlaylist(page);
}).on('click', '.lnkRemoveFromPlaylist', function () {
var index = parseInt(this.getAttribute('data-index'));
MediaController.removeFromPlaylist(index);
loadPlaylist(page);
});
Events.on(page, 'click', '.mediaItem', onListItemClick);
}
function onPlaybackStart(e, state) {
var player = this;
player.beginPlayerUpdates();
onStateChanged.call(player, e, state);
loadPlaylist($($.mobile.activePage)[0]);
}
function onPlaybackStopped(e, state) {
var player = this;
player.endPlayerUpdates();
onStateChanged.call(player, e, {});
loadPlaylist($($.mobile.activePage)[0]);
}
var lastUpdateTime = 0;
function onStateChanged(e, state) {
if (e.type == 'positionchange') {
// Try to avoid hammering the document with changes
var now = new Date().getTime();
if ((now - lastUpdateTime) < 700) {
return;
}
lastUpdateTime = now;
}
updatePlayerState($($.mobile.activePage)[0], state);
}
function showButton(button) {
button.removeClass('hide');
}
function hideButton(button) {
button.addClass('hide');
}
function hasStreams(item, type) {
return item && item.MediaStreams && item.MediaStreams.filter(function (i) {
return i.Type == type;
}).length > 0;
}
function updatePlayerState(page, state) {
lastPlayerState = state;
var item = state.NowPlayingItem;
var playerInfo = MediaController.getPlayerInfo();
var supportedCommands = playerInfo.supportedCommands;
var playState = state.PlayState || {};
$('.btnToggleFullscreen', page).buttonEnabled(item && item.MediaType == 'Video' && supportedCommands.indexOf('ToggleFullscreen') != -1);
$('.btnAudioTracks', page).buttonEnabled(hasStreams(item, 'Audio') && supportedCommands.indexOf('SetAudioStreamIndex') != -1);
$('.btnSubtitles', page).buttonEnabled(hasStreams(item, 'Subtitle') && supportedCommands.indexOf('SetSubtitleStreamIndex') != -1);
if (item && item.Chapters && item.Chapters.length && playState.CanSeek) {
$('.btnChapters', page).buttonEnabled(true);
} else {
$('.btnChapters', page).buttonEnabled(false);
hideChapterMenu(page);
}
$('.sendMessageElement', page).buttonEnabled(supportedCommands.indexOf('DisplayMessage') != -1);
$('.typeTextElement', page).buttonEnabled(supportedCommands.indexOf('SendString') != -1);
$('.btnStop', page).buttonEnabled(item != null);
$('.btnNextTrack', page).buttonEnabled(item != null);
$('.btnPreviousTrack', page).buttonEnabled(item != null);
var btnPause = $('.btnPause', page).buttonEnabled(item != null);
var btnPlay = $('.btnPlay', page).buttonEnabled(item != null);
if (playState.IsPaused) {
hideButton(btnPause);
showButton(btnPlay);
} else {
showButton(btnPause);
hideButton(btnPlay);
}
var positionSlider = $('.nowPlayingPositionSlider', page)[0];
if (!positionSlider.dragging) {
if (item && item.RunTimeTicks) {
var pct = playState.PositionTicks / item.RunTimeTicks;
pct *= 100;
positionSlider.value = pct;
} else {
positionSlider.value = 0;
}
positionSlider.disabled = !playState.CanSeek;
}
if (playState.PositionTicks == null) {
$('.positionTime', page).html('--:--');
} else {
$('.positionTime', page).html(Dashboard.getDisplayTime(playState.PositionTicks));
}
if (item && item.RunTimeTicks != null) {
$('.runtime', page).html(Dashboard.getDisplayTime(item.RunTimeTicks));
} else {
$('.runtime', page).html('--:--');
}
if (item && item.MediaType == 'Video') {
$('.videoButton', page).css('visibility', 'visible');
} else {
$('.videoButton', page).css('visibility', 'hidden');
}
if (playerInfo.isLocalPlayer && AppInfo.hasPhysicalVolumeButtons) {
$('.volumeButton', page).css('visibility', 'hidden');
} else {
$('.volumeButton', page).css('visibility', 'visible');
}
if (playerInfo.isLocalPlayer && AppInfo.hasPhysicalVolumeButtons && item && item.MediaType == 'Audio') {
$('.buttonsRow2', page).hide();
$('.buttonsRow3', page).hide();
} else {
$('.buttonsRow2', page).show();
$('.buttonsRow3', page).show();
}
updateNowPlayingInfo(page, state);
}
var currentImgUrl;
function updateNowPlayingInfo(page, state) {
var item = state.NowPlayingItem;
var displayName = item ? MediaController.getNowPlayingNameHtml(item).replace('