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

Merging in latest dev

This commit is contained in:
T. Adams 2015-04-03 11:04:25 -07:00
commit 717b58d43c
95 changed files with 1007 additions and 959 deletions

View file

@ -15,9 +15,14 @@
</div> </div>
<div data-role="controlgroup" data-type="horizontal" class="localnav syncTabs" data-mini="true" style="display:none;"> <div data-role="controlgroup" data-type="horizontal" class="localnav syncTabs" data-mini="true" style="display:none;">
<a href="syncactivity.html" data-role="button">${TabActivity}</a> <a href="syncactivity.html" data-role="button">${TabActivity}</a>
<a href="syncservices.html" data-role="button" class="ui-btn-active">${TabServices}</a> <a href="appservices.html?context=sync" data-role="button" class="ui-btn-active">${TabServices}</a>
<a href="syncsettings.html" data-role="button">${TabSettings}</a> <a href="syncsettings.html" data-role="button">${TabSettings}</a>
</div> </div>
<div data-role="controlgroup" data-type="horizontal" class="localnav livetvTabs" data-mini="true" style="display:none;">
<a href="livetvstatus.html" data-role="button">${TabStatus}</a>
<a href="#" data-role="button" class="ui-btn-active">${TabServices}</a>
<a href="livetvsettings.html" data-role="button">${TabSettings}</a>
</div>
<div class="readOnlyContent"> <div class="readOnlyContent">

View file

@ -0,0 +1,52 @@
<!DOCTYPE html>
<html>
<head>
<title>Emby</title>
</head>
<body>
<div id="appServicesPage" data-role="page" class="page type-interior appServicesPage" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Sync">
<div data-role="content">
<div class="content-primary">
<div class="sectionTabs syncSectionTabs" style="display:none;">
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
<a href="syncactivity.html" data-role="button">${TabActivity}</a>
<a href="#" data-role="button" class="ui-btn-active">${TabServices}</a>
<a href="syncsettings.html" data-role="button">${TabSettings}</a>
</div>
</div>
<div class="sectionTabs livetvSectionTabs" style="display:none;">
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
<a href="livetvstatus.html" data-role="button">${TabStatus}</a>
<a href="#" data-role="button" class="ui-btn-active">${TabServices}</a>
<a href="livetvsettings.html" data-role="button">${TabSettings}</a>
</div>
</div>
<div class="detailSectionHeader">${HeaderInstalledServices}</div>
<div class="installedPlugins"></div>
<br />
<br />
<br />
<div class="detailSectionHeader">${HeaderAvailableServices}</div>
<div class="catalog"></div>
<div class="staticSupporterPromotion supporterPromotion syncPromotion" style="display:none;">
<a class="btn btnActionAccent" href="supporter.html" style="font-size:14px;">
<div>
${HeaderSyncRequiresSupporterMembership}
</div>
<div>
${HeaderEnjoyDayTrial}
</div>
<div style="font-weight:normal;font-size:90%;margin-top:5px;">
${ButtonLearnMore}
</div>
</a>
</div>
</div>
</div>
</div>
</body>
</html>

View file

@ -18,8 +18,8 @@
<div class="listTopPaging" style="float: left; position: relative; top: 15px;"> <div class="listTopPaging" style="float: left; position: relative; top: 15px;">
</div> </div>
<!--<button style="display: none;" class="btnClearLog" type="button" data-inline="true" data-icon="forbidden" data-mini="true">Clear</button>-->
<div style="float: right; position: relative; top: 15px;margin-top: -5px;display:none;" class="organizeTaskPanel"> <div style="float: right; position: relative; top: 15px;margin-top: -5px;display:none;" class="organizeTaskPanel">
<button style="display: none;" class="btnClearLog" type="button" data-inline="true" data-icon="forbidden" data-mini="true">Clear</button>
<button type="button" class="btnOrganize" data-icon="action" data-mini="true" data-inline="true">${ButtonOrganize}</button> <button type="button" class="btnOrganize" data-icon="action" data-mini="true" data-inline="true">${ButtonOrganize}</button>
<progress max="100" min="0" style="width:100px;display:none;" class="organizeProgress"></progress> <progress max="100" min="0" style="width:100px;display:none;" class="organizeProgress"></progress>
</div> </div>

View file

@ -7,8 +7,7 @@
<div id="boxsetsPage" data-role="page" class="page libraryPage backdropPage collectionEditorPage" data-backdroptype="movie,boxset"> <div id="boxsetsPage" data-role="page" class="page libraryPage backdropPage collectionEditorPage" data-backdroptype="movie,boxset">
<div class="libraryViewNav scopedLibraryViewNav movieTabs"> <div class="libraryViewNav scopedLibraryViewNav movieTabs">
<a href="movieslatest.html">${TabLatest}</a> <a href="moviesrecommended.html">${TabSuggestions}</a>
<a href="moviesrecommended.html">${TabSuggested}</a>
<a href="movies.html">${TabMovies}</a> <a href="movies.html">${TabMovies}</a>
<a href="movietrailers.html">${TabTrailers}</a> <a href="movietrailers.html">${TabTrailers}</a>
<a href="#" class="ui-btn-active">${TabCollections}</a> <a href="#" class="ui-btn-active">${TabCollections}</a>
@ -52,6 +51,7 @@
<select id="selectView"> <select id="selectView">
<option value="Poster">${OptionPoster}</option> <option value="Poster">${OptionPoster}</option>
<option value="List">${OptionList}</option> <option value="List">${OptionList}</option>
<option value="Thumb">${OptionThumb}</option>
</select> </select>
</div> </div>
<br /> <br />

View file

@ -14,16 +14,6 @@
<a href="dashboardgeneral.html" data-role="button">${TabSettings}</a> <a href="dashboardgeneral.html" data-role="button">${TabSettings}</a>
</div> </div>
<div class="dashboardContent"> <div class="dashboardContent">
<div class="supporterPromotion" style="display:none;">
<a class="btn btnActionAccent" href="supporter.html" style="font-size:14px;">
<div>
${HeaderSupportTheTeam}
</div>
<div style="font-weight:normal;font-size:90%;margin-top:5px;">
${TextEnjoyBonusFeatures}
</div>
</a>
</div>
<div class="ui-bar-a welcomeMessage" style="display: none; padding: 2em; border-radius: 10px; margin: 2em 0; font-weight: normal; max-width: 800px;"> <div class="ui-bar-a welcomeMessage" style="display: none; padding: 2em; border-radius: 10px; margin: 2em 0; font-weight: normal; max-width: 800px;">
<h1 style="margin-top: 0;" class="tourHeader"></h1> <h1 style="margin-top: 0;" class="tourHeader"></h1>
<p> <p>
@ -141,6 +131,7 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -43,6 +43,11 @@
<br /> <br />
<ul data-role="listview" class="ulForm"> <ul data-role="listview" class="ulForm">
<li>
<input type="checkbox" id="chkEnableThrottle" data-mini="true" />
<label for="chkEnableThrottle">${OptionEnableTranscodingThrottle}</label>
<div class="fieldDescription">${OptionEnableTranscodingThrottleHelp}</div>
</li>
<li> <li>
<label for="txtTranscodingTempPath">${LabelTranscodingTempPath}</label> <label for="txtTranscodingTempPath">${LabelTranscodingTempPath}</label>
<div style="display: inline-block; width: 92%;"> <div style="display: inline-block; width: 92%;">

View file

@ -7,7 +7,7 @@
<div id="episodesPage" data-role="page" class="page libraryPage"> <div id="episodesPage" data-role="page" class="page libraryPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="tvrecommended.html">${TabSuggested}</a> <a href="tvrecommended.html">${TabSuggestions}</a>
<a href="tvlatest.html">${TabLatest}</a> <a href="tvlatest.html">${TabLatest}</a>
<a href="tvupcoming.html">${TabUpcoming}</a> <a href="tvupcoming.html">${TabUpcoming}</a>
<a href="tvshows.html">${TabShows}</a> <a href="tvshows.html">${TabShows}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="gameGenresPage" data-role="page" class="page libraryPage listPage"> <div id="gameGenresPage" data-role="page" class="page libraryPage listPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="gamesrecommended.html">${TabSuggested}</a> <a href="gamesrecommended.html">${TabSuggestions}</a>
<a href="games.html">${TabGames}</a> <a href="games.html">${TabGames}</a>
<a href="gamesystems.html">${TabGameSystems}</a> <a href="gamesystems.html">${TabGameSystems}</a>
<a href="#" class="ui-btn-active">${TabGenres}</a> <a href="#" class="ui-btn-active">${TabGenres}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="gamesPage" data-role="page" class="page libraryPage listPage"> <div id="gamesPage" data-role="page" class="page libraryPage listPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="gamesrecommended.html">${TabSuggested}</a> <a href="gamesrecommended.html">${TabSuggestions}</a>
<a href="#" class="ui-btn-active">${TabGames}</a> <a href="#" class="ui-btn-active">${TabGames}</a>
<a href="gamesystems.html">${TabGameSystems}</a> <a href="gamesystems.html">${TabGameSystems}</a>
<a href="gamegenres.html">${TabGenres}</a> <a href="gamegenres.html">${TabGenres}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="gamesRecommendedPage" data-role="page" class="page libraryPage backdropPage" data-backdroptype="game"> <div id="gamesRecommendedPage" data-role="page" class="page libraryPage backdropPage" data-backdroptype="game">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="#" class="ui-btn-active">${TabSuggested}</a> <a href="#" class="ui-btn-active">${TabSuggestions}</a>
<a href="games.html">${TabGames}</a> <a href="games.html">${TabGames}</a>
<a href="gamesystems.html">Game Systems</a> <a href="gamesystems.html">Game Systems</a>
<a href="gamegenres.html">${TabGenres}</a> <a href="gamegenres.html">${TabGenres}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="gameStudiosPage" data-role="page" class="page libraryPage listPage"> <div id="gameStudiosPage" data-role="page" class="page libraryPage listPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="gamesrecommended.html">${TabSuggested}</a> <a href="gamesrecommended.html">${TabSuggestions}</a>
<a href="games.html">${TabGames}</a> <a href="games.html">${TabGames}</a>
<a href="gamesystems.html">${TabGameSystems}</a> <a href="gamesystems.html">${TabGameSystems}</a>
<a href="gamegenres.html">${TabGenres}</a> <a href="gamegenres.html">${TabGenres}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="gamesystemsPage" data-role="page" class="page libraryPage backdropPage" data-backdroptype="gamesystem"> <div id="gamesystemsPage" data-role="page" class="page libraryPage backdropPage" data-backdroptype="gamesystem">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="gamesrecommended.html">${TabSuggested}</a> <a href="gamesrecommended.html">${TabSuggestions}</a>
<a href="games.html">${TabGames}</a> <a href="games.html">${TabGames}</a>
<a href="#" class="ui-btn-active">${TabGameSystems}</a> <a href="#" class="ui-btn-active">${TabGameSystems}</a>
<a href="gamegenres.html">${TabGenres}</a> <a href="gamegenres.html">${TabGenres}</a>

View file

@ -8,8 +8,7 @@
<div id="itemByNameDetailPage" data-role="page" class="page libraryPage itemDetailPage lightBackdropPage"> <div id="itemByNameDetailPage" data-role="page" class="page libraryPage itemDetailPage lightBackdropPage">
<div id="movieGenreTabs" class="itemTabs" style="display: none;"> <div id="movieGenreTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="movieslatest.html">${TabLatest}</a> <a href="moviesrecommended.html">${TabSuggestions}</a>
<a href="moviesrecommended.html">${TabSuggested}</a>
<a href="movies.html">${TabMovies}</a> <a href="movies.html">${TabMovies}</a>
<a href="movietrailers.html">${TabTrailers}</a> <a href="movietrailers.html">${TabTrailers}</a>
<a href="collections.html?context=movies">${TabCollections}</a> <a href="collections.html?context=movies">${TabCollections}</a>
@ -20,8 +19,7 @@
</div> </div>
<div id="moviePeopleTabs" class="itemTabs" style="display: none;"> <div id="moviePeopleTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="movieslatest.html">${TabLatest}</a> <a href="moviesrecommended.html">${TabSuggestions}</a>
<a href="moviesrecommended.html">${TabSuggested}</a>
<a href="movies.html">${TabMovies}</a> <a href="movies.html">${TabMovies}</a>
<a href="movietrailers.html">${TabTrailers}</a> <a href="movietrailers.html">${TabTrailers}</a>
<a href="collections.html?context=movies">${TabCollections}</a> <a href="collections.html?context=movies">${TabCollections}</a>
@ -32,8 +30,7 @@
</div> </div>
<div id="movieStudioTabs" class="itemTabs" style="display: none;"> <div id="movieStudioTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="movieslatest.html">${TabLatest}</a> <a href="moviesrecommended.html">${TabSuggestions}</a>
<a href="moviesrecommended.html">${TabSuggested}</a>
<a href="movies.html">${TabMovies}</a> <a href="movies.html">${TabMovies}</a>
<a href="movietrailers.html">${TabTrailers}</a> <a href="movietrailers.html">${TabTrailers}</a>
<a href="collections.html?context=movies">${TabCollections}</a> <a href="collections.html?context=movies">${TabCollections}</a>
@ -44,7 +41,7 @@
</div> </div>
<div id="tvGenreTabs" class="itemTabs" style="display: none;"> <div id="tvGenreTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="tvrecommended.html">${TabSuggested}</a> <a href="tvrecommended.html">${TabSuggestions}</a>
<a href="tvlatest.html">${TabLatest}</a> <a href="tvlatest.html">${TabLatest}</a>
<a href="tvupcoming.html">${TabUpcoming}</a> <a href="tvupcoming.html">${TabUpcoming}</a>
<a href="tvshows.html">${TabShows}</a> <a href="tvshows.html">${TabShows}</a>
@ -56,7 +53,7 @@
</div> </div>
<div id="tvPeopleTabs" class="itemTabs" style="display: none;"> <div id="tvPeopleTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="tvrecommended.html">${TabSuggested}</a> <a href="tvrecommended.html">${TabSuggestions}</a>
<a href="tvlatest.html">${TabLatest}</a> <a href="tvlatest.html">${TabLatest}</a>
<a href="tvupcoming.html">${TabUpcoming}</a> <a href="tvupcoming.html">${TabUpcoming}</a>
<a href="tvshows.html">${TabShows}</a> <a href="tvshows.html">${TabShows}</a>
@ -68,7 +65,7 @@
</div> </div>
<div id="tvStudioTabs" class="itemTabs" style="display: none;"> <div id="tvStudioTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="tvrecommended.html">${TabSuggested}</a> <a href="tvrecommended.html">${TabSuggestions}</a>
<a href="tvlatest.html">${TabLatest}</a> <a href="tvlatest.html">${TabLatest}</a>
<a href="tvupcoming.html">${TabUpcoming}</a> <a href="tvupcoming.html">${TabUpcoming}</a>
<a href="tvshows.html">${TabShows}</a> <a href="tvshows.html">${TabShows}</a>
@ -80,7 +77,7 @@
</div> </div>
<div id="musicGenreTabs" class="itemTabs" style="display: none;"> <div id="musicGenreTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="musicrecommended.html">${TabSuggested}</a> <a href="musicrecommended.html">${TabSuggestions}</a>
<a href="songs.html">${TabSongs}</a> <a href="songs.html">${TabSongs}</a>
<a href="musicalbums.html">${TabAlbums}</a> <a href="musicalbums.html">${TabAlbums}</a>
<a href="musicalbumartists.html">${TabAlbumArtists}</a> <a href="musicalbumartists.html">${TabAlbumArtists}</a>
@ -91,7 +88,7 @@
</div> </div>
<div id="artistTabs" class="itemTabs" style="display: none;"> <div id="artistTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="musicrecommended.html">${TabSuggested}</a> <a href="musicrecommended.html">${TabSuggestions}</a>
<a href="songs.html">${TabSongs}</a> <a href="songs.html">${TabSongs}</a>
<a href="musicalbums.html">${TabAlbums}</a> <a href="musicalbums.html">${TabAlbums}</a>
<a href="musicalbumartists.html">${TabAlbumArtists}</a> <a href="musicalbumartists.html">${TabAlbumArtists}</a>
@ -102,7 +99,7 @@
</div> </div>
<div id="gameGenreTabs" class="itemTabs" style="display: none;"> <div id="gameGenreTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="gamesrecommended.html">${TabSuggested}</a> <a href="gamesrecommended.html">${TabSuggestions}</a>
<a href="games.html">${TabGames}</a> <a href="games.html">${TabGames}</a>
<a href="gamesystems.html">Game Systems</a> <a href="gamesystems.html">Game Systems</a>
<a href="gamegenres.html" class="ui-btn-active">${TabGenres}</a> <a href="gamegenres.html" class="ui-btn-active">${TabGenres}</a>
@ -111,7 +108,7 @@
</div> </div>
<div id="gameStudioTabs" class="itemTabs" style="display: none;"> <div id="gameStudioTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="gamesrecommended.html">${TabSuggested}</a> <a href="gamesrecommended.html">${TabSuggestions}</a>
<a href="games.html">${TabGames}</a> <a href="games.html">${TabGames}</a>
<a href="gamesystems.html">Game Systems</a> <a href="gamesystems.html">Game Systems</a>
<a href="gamegenres.html">${TabGenres}</a> <a href="gamegenres.html">${TabGenres}</a>

View file

@ -31,8 +31,7 @@
<div id="movieTabs" class="itemTabs" style="display: none;"> <div id="movieTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="movieslatest.html">${TabLatest}</a> <a href="moviesrecommended.html">${TabSuggestions}</a>
<a href="moviesrecommended.html">${TabSuggested}</a>
<a href="movies.html" class="lnkMovies">${TabMovies}</a> <a href="movies.html" class="lnkMovies">${TabMovies}</a>
<a href="movietrailers.html" class="lnkMovieTrailers">${TabTrailers}</a> <a href="movietrailers.html" class="lnkMovieTrailers">${TabTrailers}</a>
<a href="collections.html?context=movies" class="lnkCollections">${TabCollections}</a> <a href="collections.html?context=movies" class="lnkCollections">${TabCollections}</a>
@ -43,7 +42,7 @@
</div> </div>
<div id="tvShowsTabs" class="itemTabs" style="display: none;"> <div id="tvShowsTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="tvrecommended.html">${TabSuggested}</a> <a href="tvrecommended.html">${TabSuggestions}</a>
<a href="tvlatest.html">${TabLatest}</a> <a href="tvlatest.html">${TabLatest}</a>
<a href="tvupcoming.html">${TabUpcoming}</a> <a href="tvupcoming.html">${TabUpcoming}</a>
<a href="tvshows.html" class="ui-btn-active">${TabShows}</a> <a href="tvshows.html" class="ui-btn-active">${TabShows}</a>
@ -55,7 +54,7 @@
</div> </div>
<div id="songTabs" class="itemTabs" style="display: none;"> <div id="songTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="musicrecommended.html">${TabSuggested}</a> <a href="musicrecommended.html">${TabSuggestions}</a>
<a href="songs.html" class="ui-btn-active">${TabSongs}</a> <a href="songs.html" class="ui-btn-active">${TabSongs}</a>
<a href="musicalbums.html">${TabAlbums}</a> <a href="musicalbums.html">${TabAlbums}</a>
<a href="musicalbumartists.html">${TabAlbumArtists}</a> <a href="musicalbumartists.html">${TabAlbumArtists}</a>
@ -66,7 +65,7 @@
</div> </div>
<div id="albumTabs" class="itemTabs" style="display: none;"> <div id="albumTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="musicrecommended.html">${TabSuggested}</a> <a href="musicrecommended.html">${TabSuggestions}</a>
<a href="songs.html">${TabSongs}</a> <a href="songs.html">${TabSongs}</a>
<a href="musicalbums.html" class="ui-btn-active">${TabAlbums}</a> <a href="musicalbums.html" class="ui-btn-active">${TabAlbums}</a>
<a href="musicalbumartists.html">${TabAlbumArtists}</a> <a href="musicalbumartists.html">${TabAlbumArtists}</a>
@ -77,7 +76,7 @@
</div> </div>
<div id="musicVideoTabs" class="itemTabs" style="display: none;"> <div id="musicVideoTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="musicrecommended.html">${TabSuggested}</a> <a href="musicrecommended.html">${TabSuggestions}</a>
<a href="songs.html">${TabSongs}</a> <a href="songs.html">${TabSongs}</a>
<a href="musicalbums.html">${TabAlbums}</a> <a href="musicalbums.html">${TabAlbums}</a>
<a href="musicalbumartists.html">${TabAlbumArtists}</a> <a href="musicalbumartists.html">${TabAlbumArtists}</a>
@ -88,7 +87,7 @@
</div> </div>
<div id="gameTabs" class="itemTabs" style="display: none;"> <div id="gameTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="gamesrecommended.html">${TabSuggested}</a> <a href="gamesrecommended.html">${TabSuggestions}</a>
<a href="games.html" class="ui-btn-active">${TabGames}</a> <a href="games.html" class="ui-btn-active">${TabGames}</a>
<a href="gamesystems.html">Game Systems</a> <a href="gamesystems.html">Game Systems</a>
<a href="gamegenres.html">${TabGenres}</a> <a href="gamegenres.html">${TabGenres}</a>
@ -97,7 +96,7 @@
</div> </div>
<div id="gameSystemTabs" class="itemTabs" style="display: none;"> <div id="gameSystemTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="gamesrecommended.html">${TabSuggested}</a> <a href="gamesrecommended.html">${TabSuggestions}</a>
<a href="games.html">${TabGames}</a> <a href="games.html">${TabGames}</a>
<a href="gamesystems.html" class="ui-btn-active">${TabGameSystems}</a> <a href="gamesystems.html" class="ui-btn-active">${TabGameSystems}</a>
<a href="gamegenres.html">${TabGenres}</a> <a href="gamegenres.html">${TabGenres}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="liveTvChannelPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}"> <div id="liveTvChannelPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}">
<div class="libraryViewNav"> <div class="libraryViewNav">
<a href="livetvsuggested.html">${TabSuggested}</a> <a href="livetvsuggested.html">${TabSuggestions}</a>
<a href="livetvguide.html">${TabGuide}</a> <a href="livetvguide.html">${TabGuide}</a>
<a href="livetvchannels.html" class="ui-btn-active">${TabChannels}</a> <a href="livetvchannels.html" class="ui-btn-active">${TabChannels}</a>
<a href="livetvrecordings.html">${TabRecordings}</a> <a href="livetvrecordings.html">${TabRecordings}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="liveTvChannelsPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}"> <div id="liveTvChannelsPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}">
<div class="libraryViewNav"> <div class="libraryViewNav">
<a href="livetvsuggested.html">${TabSuggested}</a> <a href="livetvsuggested.html">${TabSuggestions}</a>
<a href="livetvguide.html">${TabGuide}</a> <a href="livetvguide.html">${TabGuide}</a>
<a href="livetvchannels.html" class="ui-btn-active">${TabChannels}</a> <a href="livetvchannels.html" class="ui-btn-active">${TabChannels}</a>
<a href="livetvrecordings.html">${TabRecordings}</a> <a href="livetvrecordings.html">${TabRecordings}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="liveTvGuidePage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}"> <div id="liveTvGuidePage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}">
<div class="libraryViewNav"> <div class="libraryViewNav">
<a href="livetvsuggested.html">${TabSuggested}</a> <a href="livetvsuggested.html">${TabSuggestions}</a>
<a href="livetvguide.html" class="ui-btn-active">${TabGuide}</a> <a href="livetvguide.html" class="ui-btn-active">${TabGuide}</a>
<a href="livetvchannels.html">${TabChannels}</a> <a href="livetvchannels.html">${TabChannels}</a>
<a href="livetvrecordings.html">${TabRecordings}</a> <a href="livetvrecordings.html">${TabRecordings}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="liveTvItemsPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}"> <div id="liveTvItemsPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}">
<div class="libraryViewNav"> <div class="libraryViewNav">
<a href="livetvsuggested.html" class="ui-btn-active">${TabSuggested}</a> <a href="livetvsuggested.html" class="ui-btn-active">${TabSuggestions}</a>
<a href="livetvguide.html">${TabGuide}</a> <a href="livetvguide.html">${TabGuide}</a>
<a href="livetvchannels.html">${TabChannels}</a> <a href="livetvchannels.html">${TabChannels}</a>
<a href="livetvrecordings.html">${TabRecordings}</a> <a href="livetvrecordings.html">${TabRecordings}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="liveTvNewRecordingPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}"> <div id="liveTvNewRecordingPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}">
<div class="libraryViewNav"> <div class="libraryViewNav">
<a href="livetvsuggested.html">${TabSuggested}</a> <a href="livetvsuggested.html">${TabSuggestions}</a>
<a href="livetvguide.html">${TabGuide}</a> <a href="livetvguide.html">${TabGuide}</a>
<a href="livetvchannels.html">${TabChannels}</a> <a href="livetvchannels.html">${TabChannels}</a>
<a href="livetvrecordings.html" class="ui-btn-active">${TabRecordings}</a> <a href="livetvrecordings.html" class="ui-btn-active">${TabRecordings}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="liveTvProgramPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}"> <div id="liveTvProgramPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}">
<div class="libraryViewNav"> <div class="libraryViewNav">
<a href="livetvsuggested.html">${TabSuggested}</a> <a href="livetvsuggested.html">${TabSuggestions}</a>
<a href="livetvguide.html">${TabGuide}</a> <a href="livetvguide.html">${TabGuide}</a>
<a href="livetvchannels.html" class="ui-btn-active">${TabChannels}</a> <a href="livetvchannels.html" class="ui-btn-active">${TabChannels}</a>
<a href="livetvrecordings.html">${TabRecordings}</a> <a href="livetvrecordings.html">${TabRecordings}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="liveTvRecordingPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}"> <div id="liveTvRecordingPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}">
<div class="libraryViewNav"> <div class="libraryViewNav">
<a href="livetvsuggested.html">${TabSuggested}</a> <a href="livetvsuggested.html">${TabSuggestions}</a>
<a href="livetvguide.html">${TabGuide}</a> <a href="livetvguide.html">${TabGuide}</a>
<a href="livetvchannels.html">${TabChannels}</a> <a href="livetvchannels.html">${TabChannels}</a>
<a href="livetvrecordings.html" class="ui-btn-active">${TabRecordings}</a> <a href="livetvrecordings.html" class="ui-btn-active">${TabRecordings}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="liveTvRecordingListPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}"> <div id="liveTvRecordingListPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}">
<div class="libraryViewNav"> <div class="libraryViewNav">
<a href="livetvsuggested.html">${TabSuggested}</a> <a href="livetvsuggested.html">${TabSuggestions}</a>
<a href="livetvguide.html">${TabGuide}</a> <a href="livetvguide.html">${TabGuide}</a>
<a href="livetvchannels.html">${TabChannels}</a> <a href="livetvchannels.html">${TabChannels}</a>
<a href="livetvrecordings.html" class="ui-btn-active">${TabRecordings}</a> <a href="livetvrecordings.html" class="ui-btn-active">${TabRecordings}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="liveTvRecordingsPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}"> <div id="liveTvRecordingsPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}">
<div class="libraryViewNav"> <div class="libraryViewNav">
<a href="livetvsuggested.html">${TabSuggested}</a> <a href="livetvsuggested.html">${TabSuggestions}</a>
<a href="livetvguide.html">${TabGuide}</a> <a href="livetvguide.html">${TabGuide}</a>
<a href="livetvchannels.html">${TabChannels}</a> <a href="livetvchannels.html">${TabChannels}</a>
<a href="livetvrecordings.html" class="ui-btn-active">${TabRecordings}</a> <a href="livetvrecordings.html" class="ui-btn-active">${TabRecordings}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="liveTvSeriesTimerPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}"> <div id="liveTvSeriesTimerPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}">
<div class="libraryViewNav"> <div class="libraryViewNav">
<a href="livetvsuggested.html">${TabSuggested}</a> <a href="livetvsuggested.html">${TabSuggestions}</a>
<a href="livetvguide.html">${TabGuide}</a> <a href="livetvguide.html">${TabGuide}</a>
<a href="livetvchannels.html">${TabChannels}</a> <a href="livetvchannels.html">${TabChannels}</a>
<a href="livetvrecordings.html">${TabRecordings}</a> <a href="livetvrecordings.html">${TabRecordings}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="liveTvSeriesTimersPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}"> <div id="liveTvSeriesTimersPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}">
<div class="libraryViewNav"> <div class="libraryViewNav">
<a href="livetvsuggested.html">${TabSuggested}</a> <a href="livetvsuggested.html">${TabSuggestions}</a>
<a href="livetvguide.html">${TabGuide}</a> <a href="livetvguide.html">${TabGuide}</a>
<a href="livetvchannels.html">${TabChannels}</a> <a href="livetvchannels.html">${TabChannels}</a>
<a href="livetvrecordings.html">${TabRecordings}</a> <a href="livetvrecordings.html">${TabRecordings}</a>

View file

@ -11,6 +11,7 @@
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
<a href="livetvstatus.html" data-role="button">${TabStatus}</a> <a href="livetvstatus.html" data-role="button">${TabStatus}</a>
<a href="appservices.html?context=livetv" data-role="button">${TabServices}</a>
<a href="#" data-role="button" class="ui-btn-active">${TabSettings}</a> <a href="#" data-role="button" class="ui-btn-active">${TabSettings}</a>
</div> </div>

View file

@ -11,6 +11,7 @@
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
<a href="#" data-role="button" class="ui-btn-active">${TabStatus}</a> <a href="#" data-role="button" class="ui-btn-active">${TabStatus}</a>
<a href="appservices.html?context=livetv" data-role="button">${TabServices}</a>
<a href="livetvsettings.html" data-role="button">${TabSettings}</a> <a href="livetvsettings.html" data-role="button">${TabSettings}</a>
</div> </div>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="liveTvSuggestedPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}"> <div id="liveTvSuggestedPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}">
<div class="libraryViewNav"> <div class="libraryViewNav">
<a href="#" class="ui-btn-active">${TabSuggested}</a> <a href="#" class="ui-btn-active">${TabSuggestions}</a>
<a href="livetvguide.html">${TabGuide}</a> <a href="livetvguide.html">${TabGuide}</a>
<a href="livetvchannels.html">${TabChannels}</a> <a href="livetvchannels.html">${TabChannels}</a>
<a href="livetvrecordings.html">${TabRecordings}</a> <a href="livetvrecordings.html">${TabRecordings}</a>
@ -33,6 +33,14 @@
</div> </div>
<br /> <br />
</div> </div>
<div id="upcomingSports">
<h1 class="listHeader">${HeaderUpcomingSports}</h1>
<div class="upcomingSportsItems itemsContainer"></div>
<div>
<a data-role="button" href="livetvitems.html?type=sports" data-inline="true" data-mini="true">${ButtonMoreItems}</a>
</div>
<br />
</div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="liveTvTimerPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}"> <div id="liveTvTimerPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}">
<div class="libraryViewNav"> <div class="libraryViewNav">
<a href="livetvsuggested.html">${TabSuggested}</a> <a href="livetvsuggested.html">${TabSuggestions}</a>
<a href="livetvguide.html">${TabGuide}</a> <a href="livetvguide.html">${TabGuide}</a>
<a href="livetvchannels.html">${TabChannels}</a> <a href="livetvchannels.html">${TabChannels}</a>
<a href="livetvrecordings.html">${TabRecordings}</a> <a href="livetvrecordings.html">${TabRecordings}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="liveTvTimersPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}"> <div id="liveTvTimersPage" data-role="page" class="page libraryPage liveTvPage" data-contextname="${HeaderLiveTv}">
<div class="libraryViewNav"> <div class="libraryViewNav">
<a href="livetvsuggested.html">${TabSuggested}</a> <a href="livetvsuggested.html">${TabSuggestions}</a>
<a href="livetvguide.html">${TabGuide}</a> <a href="livetvguide.html">${TabGuide}</a>
<a href="livetvchannels.html">${TabChannels}</a> <a href="livetvchannels.html">${TabChannels}</a>
<a href="livetvrecordings.html">${TabRecordings}</a> <a href="livetvrecordings.html">${TabRecordings}</a>

View file

@ -7,8 +7,7 @@
<div id="movieGenresPage" data-role="page" class="page libraryPage"> <div id="movieGenresPage" data-role="page" class="page libraryPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="movieslatest.html">${TabLatest}</a> <a href="moviesrecommended.html">${TabSuggestions}</a>
<a href="moviesrecommended.html">${TabSuggested}</a>
<a href="movies.html">${TabMovies}</a> <a href="movies.html">${TabMovies}</a>
<a href="movietrailers.html">${TabTrailers}</a> <a href="movietrailers.html">${TabTrailers}</a>
<a href="collections.html?context=movies">${TabCollections}</a> <a href="collections.html?context=movies">${TabCollections}</a>

View file

@ -7,8 +7,7 @@
<div id="moviePeoplePage" data-role="page" class="page libraryPage"> <div id="moviePeoplePage" data-role="page" class="page libraryPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="movieslatest.html">${TabLatest}</a> <a href="moviesrecommended.html">${TabSuggestions}</a>
<a href="moviesrecommended.html">${TabSuggested}</a>
<a href="movies.html">${TabMovies}</a> <a href="movies.html">${TabMovies}</a>
<a href="movietrailers.html">${TabTrailers}</a> <a href="movietrailers.html">${TabTrailers}</a>
<a href="collections.html?context=movies">${TabCollections}</a> <a href="collections.html?context=movies">${TabCollections}</a>

View file

@ -7,8 +7,7 @@
<div id="moviesPage" data-role="page" class="page libraryPage collectionEditorPage"> <div id="moviesPage" data-role="page" class="page libraryPage collectionEditorPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="movieslatest.html">${TabLatest}</a> <a href="moviesrecommended.html">${TabSuggestions}</a>
<a href="moviesrecommended.html">${TabSuggested}</a>
<a href="#" class="ui-btn-active">${TabMovies}</a> <a href="#" class="ui-btn-active">${TabMovies}</a>
<a href="movietrailers.html">${TabTrailers}</a> <a href="movietrailers.html">${TabTrailers}</a>
<a href="collections.html?context=movies">${TabCollections}</a> <a href="collections.html?context=movies">${TabCollections}</a>

View file

@ -1,34 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Emby</title>
</head>
<body>
<div id="moviesLatestPage" data-role="page" class="page libraryPage backdropPage" data-backdroptype="movie">
<div class="libraryViewNav scopedLibraryViewNav">
<a href="#" class="ui-btn-active">${TabLatest}</a>
<a href="moviesrecommended.html">${TabSuggested}</a>
<a href="movies.html">${TabMovies}</a>
<a href="movietrailers.html">${TabTrailers}</a>
<a href="collections.html?context=movies">${TabCollections}</a>
<a href="moviegenres.html">${TabGenres}</a>
<a href="moviepeople.html">${TabPeople}</a>
<a href="moviestudios.html">${TabStudios}</a>
</div>
<div data-role="content">
<div class="ehsContent portraitEhsContent">
<div>
<h1 class="listHeader" style="display:inline-block;vertical-align:middle;">${HeaderLatestMovies}</h1>
<a href="#" class="accentButton categorySyncButton" data-category="Latest"><i class="fa fa-cloud"></i>${ButtonSync}</a>
</div>
<div id="recentlyAddedItems" class="itemsContainer">
</div>
</div>
</div>
</div>
</body>
</html>

View file

@ -7,8 +7,7 @@
<div id="moviesRecommendedPage" data-role="page" class="page libraryPage backdropPage" data-backdroptype="movie"> <div id="moviesRecommendedPage" data-role="page" class="page libraryPage backdropPage" data-backdroptype="movie">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="movieslatest.html">${TabLatest}</a> <a href="#" class="ui-btn-active">${TabSuggestions}</a>
<a href="#" class="ui-btn-active">${TabSuggested}</a>
<a href="movies.html">${TabMovies}</a> <a href="movies.html">${TabMovies}</a>
<a href="movietrailers.html">${TabTrailers}</a> <a href="movietrailers.html">${TabTrailers}</a>
<a href="collections.html?context=movies">${TabCollections}</a> <a href="collections.html?context=movies">${TabCollections}</a>
@ -29,6 +28,14 @@
</div> </div>
</div> </div>
<div>
<h1 class="listHeader" style="display:inline-block;vertical-align:middle;">${HeaderLatestMovies}</h1>
<a href="#" class="accentButton categorySyncButton" data-category="Latest"><i class="fa fa-cloud"></i>${ButtonSync}</a>
</div>
<div id="recentlyAddedItems" class="itemsContainer">
</div>
<div class="recommendations"> <div class="recommendations">
</div> </div>
<div class="noItemsMessage" style="display: none;"> <div class="noItemsMessage" style="display: none;">

View file

@ -7,8 +7,7 @@
<div id="movieStudiosPage" data-role="page" class="page libraryPage"> <div id="movieStudiosPage" data-role="page" class="page libraryPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="movieslatest.html">${TabLatest}</a> <a href="moviesrecommended.html">${TabSuggestions}</a>
<a href="moviesrecommended.html">${TabSuggested}</a>
<a href="movies.html">${TabMovies}</a> <a href="movies.html">${TabMovies}</a>
<a href="movietrailers.html">${TabTrailers}</a> <a href="movietrailers.html">${TabTrailers}</a>
<a href="collections.html?context=movies">${TabCollections}</a> <a href="collections.html?context=movies">${TabCollections}</a>
@ -22,7 +21,7 @@
<div class="listTopPaging"> <div class="listTopPaging">
</div> </div>
</div> </div>
<div id="items" class="itemsContainer paddedItemsContainer"></div> <div id="items" class="itemsContainer paddedItemsContainer" style="text-align:center;"></div>
</div> </div>
<div data-role="panel" class="viewPanel" data-theme="a" data-position="right" data-display="overlay" data-position-fixed="true"> <div data-role="panel" class="viewPanel" data-theme="a" data-position="right" data-display="overlay" data-position-fixed="true">

View file

@ -7,8 +7,7 @@
<div id="movieTrailersPage" data-role="page" class="page libraryPage"> <div id="movieTrailersPage" data-role="page" class="page libraryPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="movieslatest.html">${TabLatest}</a> <a href="moviesrecommended.html">${TabSuggestions}</a>
<a href="moviesrecommended.html">${TabSuggested}</a>
<a href="movies.html">${TabMovies}</a> <a href="movies.html">${TabMovies}</a>
<a href="#" class="ui-btn-active">${TabTrailers}</a> <a href="#" class="ui-btn-active">${TabTrailers}</a>
<a href="collections.html?context=movies">${TabCollections}</a> <a href="collections.html?context=movies">${TabCollections}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="musicAlbumArtistsPage" data-role="page" class="page libraryPage"> <div id="musicAlbumArtistsPage" data-role="page" class="page libraryPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="musicrecommended.html">${TabSuggested}</a> <a href="musicrecommended.html">${TabSuggestions}</a>
<a href="songs.html">${TabSongs}</a> <a href="songs.html">${TabSongs}</a>
<a href="musicalbums.html">${TabAlbums}</a> <a href="musicalbums.html">${TabAlbums}</a>
<a href="#" class="ui-btn-active">${TabAlbumArtists}</a> <a href="#" class="ui-btn-active">${TabAlbumArtists}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="musicAlbumsPage" data-role="page" class="page libraryPage"> <div id="musicAlbumsPage" data-role="page" class="page libraryPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="musicrecommended.html">${TabSuggested}</a> <a href="musicrecommended.html">${TabSuggestions}</a>
<a href="songs.html">${TabSongs}</a> <a href="songs.html">${TabSongs}</a>
<a href="#" class="ui-btn-active">${TabAlbums}</a> <a href="#" class="ui-btn-active">${TabAlbums}</a>
<a href="musicalbumartists.html">${TabAlbumArtists}</a> <a href="musicalbumartists.html">${TabAlbumArtists}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="musicArtistsPage" data-role="page" class="page libraryPage"> <div id="musicArtistsPage" data-role="page" class="page libraryPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="musicrecommended.html">${TabSuggested}</a> <a href="musicrecommended.html">${TabSuggestions}</a>
<a href="songs.html">${TabSongs}</a> <a href="songs.html">${TabSongs}</a>
<a href="musicalbums.html">${TabAlbums}</a> <a href="musicalbums.html">${TabAlbums}</a>
<a href="musicalbumartists.html">${TabAlbumArtists}</a> <a href="musicalbumartists.html">${TabAlbumArtists}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="musicGenresPage" data-role="page" class="page libraryPage"> <div id="musicGenresPage" data-role="page" class="page libraryPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="musicrecommended.html">${TabSuggested}</a> <a href="musicrecommended.html">${TabSuggestions}</a>
<a href="songs.html">${TabSongs}</a> <a href="songs.html">${TabSongs}</a>
<a href="musicalbums.html">${TabAlbums}</a> <a href="musicalbums.html">${TabAlbums}</a>
<a href="musicalbumartists.html">${TabAlbumArtists}</a> <a href="musicalbumartists.html">${TabAlbumArtists}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="musicRecommendedPage" data-role="page" class="page libraryPage backdropPage" data-backdroptype="musicartist"> <div id="musicRecommendedPage" data-role="page" class="page libraryPage backdropPage" data-backdroptype="musicartist">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="#" class="ui-btn-active">${TabSuggested}</a> <a href="#" class="ui-btn-active">${TabSuggestions}</a>
<a href="songs.html">${TabSongs}</a> <a href="songs.html">${TabSongs}</a>
<a href="musicalbums.html">${TabAlbums}</a> <a href="musicalbums.html">${TabAlbums}</a>
<a href="musicalbumartists.html">${TabAlbumArtists}</a> <a href="musicalbumartists.html">${TabAlbumArtists}</a>

View file

@ -7,7 +7,7 @@
<div id="musicVideosPage" data-role="page" class="page libraryPage"> <div id="musicVideosPage" data-role="page" class="page libraryPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="musicrecommended.html">${TabSuggested}</a> <a href="musicrecommended.html">${TabSuggestions}</a>
<a href="songs.html">${TabSongs}</a> <a href="songs.html">${TabSongs}</a>
<a href="musicalbums.html">${TabAlbums}</a> <a href="musicalbums.html">${TabAlbums}</a>
<a href="musicalbumartists.html">${TabAlbumArtists}</a> <a href="musicalbumartists.html">${TabAlbumArtists}</a>

View file

@ -76,6 +76,12 @@
<div class="latestItemsList"> <div class="latestItemsList">
</div> </div>
<br />
<div data-role="controlgroup">
<label for="chkHidePlayedFromLatest">${OptionHideWatchedContentFromLatestMedia}</label>
<input id="chkHidePlayedFromLatest" type="checkbox" />
</div>
</div> </div>
</div> </div>

View file

@ -121,6 +121,7 @@
<option value="420000">420kbps</option> <option value="420000">420kbps</option>
<option value="400000">400kbps</option> <option value="400000">400kbps</option>
<option value="320000">320kbps</option> <option value="320000">320kbps</option>
<option value="192000">192kbps</option>
</select> </select>
</div> </div>
<br /> <br />

View file

@ -265,7 +265,10 @@
}); });
}).on('pagebeforeshow pageinit', "#addPluginPage", function () {
}).on('pagebeforeshow pageinit pageshow', "#addPluginPage", function () {
// This needs both events for the helpurl to get done at the right time
var page = this; var page = this;
@ -274,12 +277,24 @@
if (context == 'sync') { if (context == 'sync') {
$('.syncTabs', page).show(); $('.syncTabs', page).show();
$('.pluginTabs', page).hide(); $('.pluginTabs', page).hide();
$('.livetvTabs', page).hide();
page.setAttribute('data-helpurl', 'https://github.com/MediaBrowser/Wiki/wiki/Sync'); page.setAttribute('data-helpurl', 'https://github.com/MediaBrowser/Wiki/wiki/Sync');
Dashboard.setPageTitle(Globalize.translate('TitleSync')); Dashboard.setPageTitle(Globalize.translate('TitleSync'));
} else { }
else if (context == 'livetv') {
$('.syncTabs', page).hide();
$('.pluginTabs', page).hide();
$('.livetvTabs', page).show();
Dashboard.setPageTitle(Globalize.translate('TitleLiveTV'));
page.setAttribute('data-helpurl', 'https://github.com/MediaBrowser/Wiki/wiki/Live%20TV');
}
else {
$('.syncTabs', page).hide(); $('.syncTabs', page).hide();
$('.pluginTabs', page).show(); $('.pluginTabs', page).show();
$('.livetvTabs', page).hide();
page.setAttribute('data-helpurl', 'https://github.com/MediaBrowser/Wiki/wiki/Plugins'); page.setAttribute('data-helpurl', 'https://github.com/MediaBrowser/Wiki/wiki/Plugins');
Dashboard.setPageTitle(Globalize.translate('TitlePlugins')); Dashboard.setPageTitle(Globalize.translate('TitlePlugins'));

View file

@ -0,0 +1,110 @@
(function ($, document) {
function reloadList(page) {
Dashboard.showLoadingMsg();
var promise1 = ApiClient.getAvailablePlugins({
TargetSystems: 'Server'
});
var promise2 = ApiClient.getInstalledPlugins();
$.when(promise1, promise2).done(function (response1, response2) {
renderInstalled(page, response1[0], response2[0]);
renderCatalog(page, response1[0], response2[0]);
});
}
function getCategories() {
var context = getParameterByName('context');
var categories = [];
if (context == 'sync') {
categories.push('Sync');
}
else if (context == 'livetv') {
categories.push('Live TV');
}
return categories;
}
function renderInstalled(page, availablePlugins, installedPlugins) {
var category = getCategories()[0];
installedPlugins = installedPlugins.filter(function (i) {
var catalogEntry = availablePlugins.filter(function (a) {
return a.guid == i.Id;
})[0];
return catalogEntry && catalogEntry.category == category;
});
PluginsPage.renderPlugins(page, installedPlugins);
}
function renderCatalog(page, availablePlugins, installedPlugins) {
var categories = getCategories();
PluginCatalog.renderCatalog({
catalogElement: $('.catalog', page),
availablePlugins: availablePlugins,
installedPlugins: installedPlugins,
categories: categories,
showCategory: false,
context: getParameterByName('context'),
targetSystem: 'Server'
});
}
$(document).on('pagebeforeshow pageinit pageshow', "#appServicesPage", function () {
// This needs both events for the helpurl to get done at the right time
var page = this;
var context = getParameterByName('context');
$('.sectionTabs', page).hide();
$('.' + context + 'SectionTabs', page).show();
if (context == 'sync') {
Dashboard.setPageTitle(Globalize.translate('TitleSync'));
page.setAttribute('data-helpurl', 'https://github.com/MediaBrowser/Wiki/wiki/Sync');
}
else if (context == 'livetv') {
Dashboard.setPageTitle(Globalize.translate('TitleLiveTV'));
page.setAttribute('data-helpurl', 'https://github.com/MediaBrowser/Wiki/wiki/Live%20TV');
}
}).on('pageshow', "#appServicesPage", function () {
// This needs both events for the helpurl to get done at the right time
var page = this;
reloadList(page);
var context = getParameterByName('context');
Dashboard.getPluginSecurityInfo().done(function (pluginSecurityInfo) {
if (pluginSecurityInfo.IsMBSupporter || context != 'sync') {
$('.syncPromotion', page).hide();
} else {
$('.syncPromotion', page).show();
}
});
});
})(jQuery, document);

View file

@ -24,12 +24,6 @@
Dashboard.getPluginSecurityInfo().done(function (pluginSecurityInfo) { Dashboard.getPluginSecurityInfo().done(function (pluginSecurityInfo) {
if (pluginSecurityInfo.IsMBSupporter) {
$('.supporterPromotion', page).hide();
} else {
$('.supporterPromotion', page).show();
}
DashboardPage.renderSupporterIcon(page, pluginSecurityInfo); DashboardPage.renderSupporterIcon(page, pluginSecurityInfo);
}); });
@ -625,7 +619,7 @@
return "<img src='css/images/clients/mbc.png' />"; return "<img src='css/images/clients/mbc.png' />";
} }
if (clientLowered == "media browser theater") { if (clientLowered == "emby theater") {
return "<img src='css/images/clients/mb.png' />"; return "<img src='css/images/clients/mb.png' />";
} }
@ -1339,3 +1333,25 @@ $(document).on('pagebeforeshow', "#dashboardPage", DashboardPage.onPageShow)
}); });
})(jQuery, document, window); })(jQuery, document, window);
(function () {
$(document).on('pagebeforeshow', ".type-interior", function () {
var page = this;
Dashboard.getPluginSecurityInfo().done(function (pluginSecurityInfo) {
if (!$('.staticSupporterPromotion', page).length) {
$('.supporterPromotion', page).remove();
if (!pluginSecurityInfo.IsMBSupporter) {
$('.content-primary', page).append('<div class="supporterPromotion"><a class="btn btnActionAccent" href="supporter.html" style="font-size:14px;"><div>' + Globalize.translate('HeaderSupportTheTeam') + '</div><div style="font-weight:normal;font-size:90%;margin-top:5px;">' + Globalize.translate('TextEnjoyBonusFeatures') + '</div></a></div>');
}
}
});
});
})();

View file

@ -3,6 +3,7 @@
function loadPage(page, config) { function loadPage(page, config) {
$('#chkEnableDebugEncodingLogging', page).checked(config.EnableDebugLogging).checkboxradio('refresh'); $('#chkEnableDebugEncodingLogging', page).checked(config.EnableDebugLogging).checkboxradio('refresh');
$('#chkEnableThrottle', page).checked(config.EnableThrottling).checkboxradio('refresh');
$('.radioEncodingQuality', page).each(function() { $('.radioEncodingQuality', page).each(function() {
@ -67,6 +68,7 @@
config.EncodingQuality = $('.radioEncodingQuality:checked', form).val(); config.EncodingQuality = $('.radioEncodingQuality:checked', form).val();
config.DownMixAudioBoost = $('#txtDownMixAudioBoost', form).val(); config.DownMixAudioBoost = $('#txtDownMixAudioBoost', form).val();
config.TranscodingTempPath = $('#txtTranscodingTempPath', form).val(); config.TranscodingTempPath = $('#txtTranscodingTempPath', form).val();
config.EnableThrottling = $('#chkEnableThrottle', form).checked();
ApiClient.updateNamedConfiguration("encoding", config).done(Dashboard.processServerConfigurationUpdateResult); ApiClient.updateNamedConfiguration("encoding", config).done(Dashboard.processServerConfigurationUpdateResult);
}); });

View file

@ -6,7 +6,7 @@
SortBy: "SortName", SortBy: "SortName",
SortOrder: "Ascending", SortOrder: "Ascending",
Recursive: true, Recursive: true,
Fields: "DateCreated", Fields: "DateCreated,ItemCounts",
StartIndex: 0 StartIndex: 0
}; };

View file

@ -7,7 +7,7 @@
SortOrder: "Ascending", SortOrder: "Ascending",
MediaTypes: "Game", MediaTypes: "Game",
Recursive: true, Recursive: true,
Fields: "UserData", Fields: "ItemCounts",
StartIndex: 0 StartIndex: 0
}; };

View file

@ -125,7 +125,6 @@
Limit: 24, Limit: 24,
Fields: "PrimaryImageAspectRatio,SyncInfo", Fields: "PrimaryImageAspectRatio,SyncInfo",
IsPlayed: false,
ImageTypeLimit: 1, ImageTypeLimit: 1,
EnableImageTypes: "Primary,Backdrop,Banner,Thumb" EnableImageTypes: "Primary,Backdrop,Banner,Thumb"
}; };
@ -470,7 +469,7 @@
switch (index) { switch (index) {
case 0: case 0:
return 'smalllibrarytiles-automobile'; return 'librarytiles-automobile';
case 1: case 1:
return 'resume'; return 'resume';
case 2: case 2:

View file

@ -477,7 +477,7 @@
if (context != 'folders') { if (context != 'folders') {
if (item.CollectionType == 'movies') { if (item.CollectionType == 'movies') {
return 'movieslatest.html?topParentId=' + item.Id; return 'moviesrecommended.html?topParentId=' + item.Id;
} }
if (item.CollectionType == 'boxsets') { if (item.CollectionType == 'boxsets') {
@ -1257,10 +1257,6 @@
if (options.showChildCountIndicator && item.ChildCount) { if (options.showChildCountIndicator && item.ChildCount) {
cssClass += ' groupedCard'; cssClass += ' groupedCard';
if (item.Type == 'Series') {
cssClass += ' unplayedGroupings';
}
} }
if (options.showTitle && !options.overlayText) { if (options.showTitle && !options.overlayText) {

View file

@ -512,10 +512,6 @@
GroupItems: false GroupItems: false
}; };
if ($(card).hasClass('unplayedGroupings')) {
options.IsPlayed = false;
}
var promise2 = ApiClient.getJSON(ApiClient.getUrl('Users/' + userId + '/Items/Latest', options)); var promise2 = ApiClient.getJSON(ApiClient.getUrl('Users/' + userId + '/Items/Latest', options));
$.when(promise1, promise2).done(function (response1, response2) { $.when(promise1, promise2).done(function (response1, response2) {

View file

@ -8,7 +8,7 @@
// The base query options // The base query options
var query = { var query = {
UserId: Dashboard.getCurrentUserId(), UserId: Dashboard.getCurrentUserId(),
SortBy: "PremiereDate,SortName", SortBy: "StartDate,SortName",
SortOrder: "Ascending", SortOrder: "Ascending",
StartIndex: 0 StartIndex: 0
}; };
@ -19,19 +19,6 @@
function updateFilterControls(page) { function updateFilterControls(page) {
// Reset form values using the last used query
$('.radioSortBy', page).each(function () {
this.checked = (query.SortBy || '').toLowerCase() == this.getAttribute('data-sortby').toLowerCase();
}).checkboxradio('refresh');
$('.radioSortOrder', page).each(function () {
this.checked = (query.SortOrder || '').toLowerCase() == this.getAttribute('data-sortorder').toLowerCase();
}).checkboxradio('refresh');
$('#selectView', page).val(view).selectmenu('refresh'); $('#selectView', page).val(view).selectmenu('refresh');
$('.alphabetPicker', page).alphaValue(query.NameStartsWithOrGreater); $('.alphabetPicker', page).alphaValue(query.NameStartsWithOrGreater);
$('#selectPageSize', page).val(query.Limit).selectmenu('refresh'); $('#selectPageSize', page).val(query.Limit).selectmenu('refresh');
@ -58,7 +45,6 @@
$('.listTopPaging', page).html(pagingHtml).trigger('create'); $('.listTopPaging', page).html(pagingHtml).trigger('create');
updateFilterControls(page); updateFilterControls(page);
var trigger = false;
if (view == "Poster") { if (view == "Poster") {
html = LibraryBrowser.getPosterViewHtml({ html = LibraryBrowser.getPosterViewHtml({
@ -112,18 +98,6 @@
var page = this; var page = this;
$('.radioSortBy', this).on('click', function () {
query.StartIndex = 0;
query.SortBy = this.getAttribute('data-sortby');
reloadItems(page);
});
$('.radioSortOrder', this).on('click', function () {
query.StartIndex = 0;
query.SortOrder = this.getAttribute('data-sortorder');
reloadItems(page);
});
$('#selectView', this).on('change', function () { $('#selectView', this).on('change', function () {
view = this.value; view = this.value;
@ -179,6 +153,7 @@
} }
query.IsMovie = getParameterByName('type') == 'movies' ? true : null; query.IsMovie = getParameterByName('type') == 'movies' ? true : null;
query.IsSports = getParameterByName('type') == 'sports' ? true : null;
var viewkey = getSavedQueryKey(); var viewkey = getSavedQueryKey();

View file

@ -33,7 +33,8 @@
IsAiring: false, IsAiring: false,
HasAired: false, HasAired: false,
limit: 10, limit: 10,
IsMovie: false IsMovie: false,
IsSports: false
}).done(function (result) { }).done(function (result) {
@ -73,6 +74,28 @@
$('.upcomingTvMovieItems', page).html(html).lazyChildren(); $('.upcomingTvMovieItems', page).html(html).lazyChildren();
}); });
ApiClient.getLiveTvRecommendedPrograms({
userId: Dashboard.getCurrentUserId(),
IsAiring: false,
HasAired: false,
limit: 10,
IsSports: true
}).done(function (result) {
var html = LibraryBrowser.getPosterViewHtml({
items: result.Items,
shape: "auto",
showTitle: true,
coverImage: true,
overlayText: false,
lazy: true
});
$('.upcomingSportsItems', page).html(html).lazyChildren();
});
} }
$(document).on('pagebeforeshow', "#liveTvSuggestedPage", function () { $(document).on('pagebeforeshow', "#liveTvSuggestedPage", function () {

View file

@ -53,13 +53,21 @@
}).on('playbackstop.mediacontroller', function (e, state) { }).on('playbackstop.mediacontroller', function (e, state) {
ApiClient.reportPlaybackStopped({ var stopInfo = {
itemId: state.NowPlayingItem.Id, itemId: state.NowPlayingItem.Id,
mediaSourceId: state.PlayState.MediaSourceId, mediaSourceId: state.PlayState.MediaSourceId,
positionTicks: state.PlayState.PositionTicks positionTicks: state.PlayState.PositionTicks
};
}); if (state.PlayState.LiveStreamId) {
stopInfo.LiveStreamId = state.PlayState.LiveStreamId;
}
if (state.PlayState.PlaySessionId) {
stopInfo.PlaySessionId = state.PlayState.PlaySessionId;
}
ApiClient.reportPlaybackStopped(stopInfo);
}).on('positionchange.mediacontroller', function (e, state) { }).on('positionchange.mediacontroller', function (e, state) {

View file

@ -143,10 +143,6 @@
self.changeStream(self.getCurrentTicks(), { AudioStreamIndex: index }); self.changeStream(self.getCurrentTicks(), { AudioStreamIndex: index });
}; };
self.supportsSubtitleStreamExternally = function (stream) {
return stream.Type == 'Subtitle' && stream.IsTextSubtitleStream && stream.SupportsExternalStream;
}
self.setSubtitleStreamIndex = function (index) { self.setSubtitleStreamIndex = function (index) {
if (!self.supportsTextTracks()) { if (!self.supportsTextTracks()) {
@ -166,7 +162,7 @@
if (currentStream && !newStream) { if (currentStream && !newStream) {
if (!self.supportsSubtitleStreamExternally(currentStream)) { if (currentStream.DeliveryMethod != 'External') {
// Need to change the transcoded stream to remove subs // Need to change the transcoded stream to remove subs
self.changeStream(self.getCurrentTicks(), { SubtitleStreamIndex: -1 }); self.changeStream(self.getCurrentTicks(), { SubtitleStreamIndex: -1 });
@ -174,7 +170,7 @@
} }
else if (!currentStream && newStream) { else if (!currentStream && newStream) {
if (self.supportsSubtitleStreamExternally(newStream)) { if (newStream.DeliveryMethod == 'External') {
selectedTrackElementIndex = index; selectedTrackElementIndex = index;
} else { } else {
@ -184,10 +180,10 @@
} }
else if (currentStream && newStream) { else if (currentStream && newStream) {
if (self.supportsSubtitleStreamExternally(newStream)) { if (newStream.DeliveryMethod == 'External') {
selectedTrackElementIndex = index; selectedTrackElementIndex = index;
if (!self.supportsSubtitleStreamExternally(currentStream)) { if (currentStream.DeliveryMethod != 'External') {
self.changeStream(self.getCurrentTicks(), { SubtitleStreamIndex: -1 }); self.changeStream(self.getCurrentTicks(), { SubtitleStreamIndex: -1 });
} }
} else { } else {
@ -207,7 +203,7 @@
var modes = ['disabled', 'showing', 'hidden']; var modes = ['disabled', 'showing', 'hidden'];
var textStreams = self.currentMediaSource.MediaStreams.filter(function (s) { var textStreams = self.currentMediaSource.MediaStreams.filter(function (s) {
return self.supportsSubtitleStreamExternally(s); return s.DeliveryMethod == 'External';
}); });
var newStream = textStreams.filter(function (s) { var newStream = textStreams.filter(function (s) {
@ -428,14 +424,12 @@
if (!$(this).hasClass('selectedMediaPopupOption')) { if (!$(this).hasClass('selectedMediaPopupOption')) {
var maxWidth = parseInt(this.getAttribute('data-maxwidth'));
var bitrate = parseInt(this.getAttribute('data-bitrate')); var bitrate = parseInt(this.getAttribute('data-bitrate'));
AppSettings.maxStreamingBitrate(bitrate); AppSettings.maxStreamingBitrate(bitrate);
self.changeStream(self.getCurrentTicks(), { self.changeStream(self.getCurrentTicks(), {
MaxWidth: maxWidth,
Bitrate: bitrate Bitrate: bitrate
}); });
} }
@ -796,7 +790,12 @@
var currentSrc = self.getCurrentSrc(self.currentMediaElement).toLowerCase(); var currentSrc = self.getCurrentSrc(self.currentMediaElement).toLowerCase();
var isStatic = currentSrc.indexOf('static=true') != -1; var isStatic = currentSrc.indexOf('static=true') != -1;
var options = getVideoQualityOptions(self.currentMediaSource.MediaStreams); var videoStream = self.currentMediaSource.MediaStreams.filter(function (stream) {
return stream.Type == "Video";
})[0];
var videoWidth = videoStream ? videoStream.Width : null;
var options = self.getVideoQualityOptions(videoWidth);
if (isStatic) { if (isStatic) {
options[0].name = "Direct"; options[0].name = "Direct";
@ -819,7 +818,7 @@
cssClass += ' selectedMediaPopupOption'; cssClass += ' selectedMediaPopupOption';
} }
var optionHtml = '<li><a data-maxwidth="' + option.maxWidth + '" data-bitrate="' + option.bitrate + '" class="' + cssClass + '" href="#">'; var optionHtml = '<li><a data-bitrate="' + option.bitrate + '" class="' + cssClass + '" href="#">';
optionHtml += '<p style="margin:0;">'; optionHtml += '<p style="margin:0;">';
@ -845,85 +844,6 @@
return html; return html;
} }
function getVideoQualityOptions(mediaStreams) {
var videoStream = mediaStreams.filter(function (stream) {
return stream.Type == "Video";
})[0];
var bitrateSetting = AppSettings.maxStreamingBitrate();
var maxAllowedWidth = self.getMaxPlayableWidth();
var options = [];
// We have media info
if (videoStream && videoStream.Width) {
maxAllowedWidth = videoStream.Width;
}
// Some 1080- videos are reported as 1912?
if (maxAllowedWidth >= 1900) {
options.push({ name: '1080p - 30Mbps', maxWidth: 1920, bitrate: 30000000 });
options.push({ name: '1080p - 25Mbps', maxWidth: 1920, bitrate: 25000000 });
options.push({ name: '1080p - 20Mbps', maxWidth: 1920, bitrate: 20000000 });
options.push({ name: '1080p - 15Mbps', maxWidth: 1920, bitrate: 15000000 });
options.push({ name: '1080p - 10Mbps', maxWidth: 1920, bitrate: 10000000 });
options.push({ name: '1080p - 8Mbps', maxWidth: 1920, bitrate: 8000000 });
options.push({ name: '1080p - 6Mbps', maxWidth: 1920, bitrate: 6000000 });
options.push({ name: '1080p - 5Mbps', maxWidth: 1920, bitrate: 5000000 });
}
else if (maxAllowedWidth >= 1260) {
options.push({ name: '720p - 10Mbps', maxWidth: 1280, bitrate: 10000000 });
options.push({ name: '720p - 8Mbps', maxWidth: 1280, bitrate: 8000000 });
options.push({ name: '720p - 6Mbps', maxWidth: 1280, bitrate: 6000000 });
options.push({ name: '720p - 5Mbps', maxWidth: 1280, bitrate: 5000000 });
}
else if (maxAllowedWidth >= 460) {
options.push({ name: '480p - 4Mbps', maxWidth: 720, bitrate: 4000000 });
options.push({ name: '480p - 3Mbps', maxWidth: 720, bitrate: 3000000 });
options.push({ name: '480p - 2.5Mbps', maxWidth: 720, bitrate: 2500000 });
options.push({ name: '480p - 2Mbps', maxWidth: 720, bitrate: 2000000 });
options.push({ name: '480p - 1.5Mbps', maxWidth: 720, bitrate: 1500000 });
}
if (maxAllowedWidth >= 1260) {
options.push({ name: '720p - 4Mbps', maxWidth: 1280, bitrate: 4000000 });
options.push({ name: '720p - 3Mbps', maxWidth: 1280, bitrate: 3000000 });
options.push({ name: '720p - 2Mbps', maxWidth: 1280, bitrate: 2000000 });
// The extra 1 is because they're keyed off the bitrate value
options.push({ name: '720p - 1Mbps', maxWidth: 1280, bitrate: 1000001 });
}
options.push({ name: '480p - 1.0Mbps', maxWidth: 720, bitrate: 1000000 });
options.push({ name: '480p - 720kbps', maxWidth: 720, bitrate: 720000 });
options.push({ name: '480p - 420kbps', maxWidth: 720, bitrate: 420000 });
options.push({ name: '360p', maxWidth: 640, bitrate: 400000 });
options.push({ name: '240p', maxWidth: 426, bitrate: 320000 });
var i, length, option;
var selectedIndex = -1;
for (i = 0, length = options.length; i < length; i++) {
option = options[i];
if (selectedIndex == -1 && option.bitrate <= bitrateSetting) {
selectedIndex = i;
}
}
if (selectedIndex == -1) {
selectedIndex = options.length - 1;
}
options[selectedIndex].selected = true;
return options;
}
function bindEventsForPlayback() { function bindEventsForPlayback() {
var hideElementsOnIdle = !$.browser.mobile; var hideElementsOnIdle = !$.browser.mobile;
@ -1007,101 +927,20 @@
} }
}; };
self.playVideo = function (playbackInfo, item, mediaSource, startPosition) { self.playVideo = function (item, mediaSource, startPosition) {
var streamInfo = self.createStreamInfo('video', item, mediaSource, startPosition);
var videoUrl = streamInfo.url;
var contentType = streamInfo.contentType;
var startPositionInSeekParam = streamInfo.startPositionInSeekParam;
self.startTimeTicksOffset = streamInfo.startTimeTicksOffset;
var mediaStreams = mediaSource.MediaStreams || []; var mediaStreams = mediaSource.MediaStreams || [];
var subtitleStreams = mediaStreams.filter(function (s) { var subtitleStreams = mediaStreams.filter(function (s) {
return s.Type == 'Subtitle'; return s.Type == 'Subtitle';
}); });
var selectedSubtitleStream = subtitleStreams.filter(function (s) {
return s.Index == mediaSource.DefaultSubtitleStreamIndex;
})[0];
var baseParams = {
audioChannels: 2,
StartTimeTicks: startPosition,
AudioStreamIndex: mediaSource.DefaultAudioStreamIndex,
deviceId: ApiClient.deviceId(),
Static: false,
mediaSourceId: mediaSource.Id,
api_key: ApiClient.accessToken(),
StreamId: playbackInfo.StreamId
};
if (selectedSubtitleStream && (!self.supportsSubtitleStreamExternally(selectedSubtitleStream) || !self.supportsTextTracks())) {
baseParams.SubtitleStreamIndex = mediaSource.DefaultSubtitleStreamIndex;
}
var mp4Quality = getVideoQualityOptions(mediaStreams).filter(function (opt) {
return opt.selected;
})[0];
mp4Quality = $.extend(mp4Quality, self.getFinalVideoParams(mediaSource, mp4Quality.maxWidth, mp4Quality.bitrate, baseParams.AudioStreamIndex, baseParams.SubtitleStreamIndex, '.mp4'));
var webmQuality = getVideoQualityOptions(mediaStreams).filter(function (opt) {
return opt.selected;
})[0];
webmQuality = $.extend(webmQuality, self.getFinalVideoParams(mediaSource, webmQuality.maxWidth, webmQuality.bitrate, baseParams.AudioStreamIndex, baseParams.SubtitleStreamIndex, '.webm'));
var m3U8Quality = getVideoQualityOptions(mediaStreams).filter(function (opt) {
return opt.selected;
})[0];
m3U8Quality = $.extend(m3U8Quality, self.getFinalVideoParams(mediaSource, mp4Quality.maxWidth, mp4Quality.bitrate, baseParams.AudioStreamIndex, baseParams.SubtitleStreamIndex, '.mp4'));
var isStatic = mp4Quality.isStatic;
self.startTimeTicksOffset = isStatic ? 0 : startPosition || 0;
var startPositionInSeekParam = startPosition ? (startPosition / 10000000) : 0;
var seekParam = startPositionInSeekParam ? '#t=' + startPositionInSeekParam : '';
var mp4VideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.mp4', $.extend({}, baseParams, {
Static: isStatic,
maxWidth: mp4Quality.maxWidth,
videoBitrate: mp4Quality.videoBitrate,
audioBitrate: mp4Quality.audioBitrate,
VideoCodec: mp4Quality.videoCodec,
AudioCodec: mp4Quality.audioCodec,
profile: 'high',
//EnableAutoStreamCopy: false,
level: '41'
}));
if (isStatic && mediaSource.Protocol == 'Http' && !mediaSource.RequiredHttpHeaders.length) {
mp4VideoUrl = mediaSource.Path;
}
if (isStatic) {
mp4VideoUrl += seekParam;
} else {
mp4VideoUrl += "&StreamId=" + new Date().getTime();
}
var webmVideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.webm', $.extend({}, baseParams, {
VideoCodec: 'vpx',
AudioCodec: 'Vorbis',
maxWidth: webmQuality.maxWidth,
videoBitrate: webmQuality.videoBitrate,
audioBitrate: webmQuality.audioBitrate,
EnableAutoStreamCopy: false,
StreamId: new Date().getTime()
}));
var hlsVideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/master.m3u8', $.extend({}, baseParams, {
maxWidth: m3U8Quality.maxWidth,
videoBitrate: m3U8Quality.videoBitrate,
audioBitrate: m3U8Quality.audioBitrate,
VideoCodec: m3U8Quality.videoCodec,
AudioCodec: m3U8Quality.audioCodec,
profile: 'high',
level: '41',
StartTimeTicks: 0,
StreamId: new Date().getTime()
})) + seekParam;
// Get Video Poster (Code from librarybrowser.js) // Get Video Poster (Code from librarybrowser.js)
var screenWidth = Math.max(screen.height, screen.width), var screenWidth = Math.max(screen.height, screen.width),
posterCode = ''; posterCode = '';
@ -1136,53 +975,27 @@
// Can't autoplay in these browsers so we need to use the full controls // Can't autoplay in these browsers so we need to use the full controls
if (requiresNativeControls) { if (requiresNativeControls) {
html += '<video class="itemVideo" id="itemVideo" preload="none" autoplay="autoplay" controls="controls"' + posterCode + '>'; html += '<video class="itemVideo" id="itemVideo" preload="none" autoplay="autoplay" crossorigin="anonymous" controls="controls"' + posterCode + '>';
} else { } else {
// Chrome 35 won't play with preload none // Chrome 35 won't play with preload none
html += '<video class="itemVideo" id="itemVideo" preload="metadata" autoplay' + posterCode + '>'; html += '<video class="itemVideo" id="itemVideo" preload="metadata" crossorigin="anonymous" autoplay' + posterCode + '>';
} }
if (!isStatic) { html += '<source type="' + contentType + '" src="' + videoUrl + '" />';
// HLS must be at the top for safari
html += '<source type="application/x-mpegURL" src="' + hlsVideoUrl + '" />';
}
var mp4BeforeWebm = self.getVideoTranscodingExtension() != '.webm';
if (mp4BeforeWebm) {
html += '<source type="video/mp4" src="' + mp4VideoUrl + '" />';
}
// Have to put webm ahead of mp4 because it will play in fast forward in chrome
// And firefox doesn't like fragmented mp4
if (!isStatic) {
html += '<source type="video/webm" src="' + webmVideoUrl + '" />';
}
if (!mp4BeforeWebm) {
html += '<source type="video/mp4" src="' + mp4VideoUrl + '" />';
}
if (self.supportsTextTracks()) {
var textStreams = subtitleStreams.filter(function (s) { var textStreams = subtitleStreams.filter(function (s) {
return self.supportsSubtitleStreamExternally(s); return s.DeliveryMethod == 'External';
}); });
for (var i = 0, length = textStreams.length; i < length; i++) { for (var i = 0, length = textStreams.length; i < length; i++) {
var textStream = textStreams[i]; var textStream = textStreams[i];
var textStreamUrl = ApiClient.getUrl('Videos/' + item.Id + '/' + mediaSource.Id + '/Subtitles/' + textStream.Index + '/Stream.vtt', { var textStreamUrl = !textStream.IsExternalUrl ? ApiClient.getUrl(textStream.DeliveryUrl) : textStream.DeliveryUrl;
startPositionTicks: (startPosition || 0),
api_key: ApiClient.accessToken()
});
var defaultAttribute = textStream.Index == mediaSource.DefaultSubtitleStreamIndex ? ' default' : ''; var defaultAttribute = textStream.Index == mediaSource.DefaultSubtitleStreamIndex ? ' default' : '';
html += '<track kind="subtitles" src="' + textStreamUrl + '" srclang="' + (textStream.Language || 'und') + '"' + defaultAttribute + '></track>'; html += '<track kind="subtitles" src="' + textStreamUrl + '" srclang="' + (textStream.Language || 'und') + '"' + defaultAttribute + '></track>';
} }
}
html += '</video>'; html += '</video>';
@ -1303,8 +1116,6 @@
self.stop(); self.stop();
console.dir(this);
var errorCode = this.error ? this.error.code : ''; var errorCode = this.error ? this.error.code : '';
console.log('Html5 Video error code: ' + errorCode); console.log('Html5 Video error code: ' + errorCode);
@ -1329,7 +1140,6 @@
message: errorMsg message: errorMsg
}); });
}).on("click.mediaplayerevent", function (e) { }).on("click.mediaplayerevent", function (e) {
if (this.paused) { if (this.paused) {

View file

@ -37,6 +37,258 @@
return targets; return targets;
}; };
var supportsAac = document.createElement('audio').canPlayType('audio/aac').replace(/no/, '');
self.getVideoQualityOptions = function (videoWidth) {
var bitrateSetting = AppSettings.maxStreamingBitrate();
var maxAllowedWidth = videoWidth || 4096;
var options = [];
// Some 1080- videos are reported as 1912?
if (maxAllowedWidth >= 1900) {
options.push({ name: '1080p - 30Mbps', maxWidth: 1920, bitrate: 30000000 });
options.push({ name: '1080p - 25Mbps', maxWidth: 1920, bitrate: 25000000 });
options.push({ name: '1080p - 20Mbps', maxWidth: 1920, bitrate: 20000000 });
options.push({ name: '1080p - 15Mbps', maxWidth: 1920, bitrate: 15000000 });
options.push({ name: '1080p - 10Mbps', maxWidth: 1920, bitrate: 10000000 });
options.push({ name: '1080p - 8Mbps', maxWidth: 1920, bitrate: 8000000 });
options.push({ name: '1080p - 6Mbps', maxWidth: 1920, bitrate: 6000000 });
options.push({ name: '1080p - 5Mbps', maxWidth: 1920, bitrate: 5000000 });
} else if (maxAllowedWidth >= 1260) {
options.push({ name: '720p - 10Mbps', maxWidth: 1280, bitrate: 10000000 });
options.push({ name: '720p - 8Mbps', maxWidth: 1280, bitrate: 8000000 });
options.push({ name: '720p - 6Mbps', maxWidth: 1280, bitrate: 6000000 });
options.push({ name: '720p - 5Mbps', maxWidth: 1280, bitrate: 5000000 });
} else if (maxAllowedWidth >= 460) {
options.push({ name: '480p - 4Mbps', maxWidth: 720, bitrate: 4000000 });
options.push({ name: '480p - 3Mbps', maxWidth: 720, bitrate: 3000000 });
options.push({ name: '480p - 2.5Mbps', maxWidth: 720, bitrate: 2500000 });
options.push({ name: '480p - 2Mbps', maxWidth: 720, bitrate: 2000000 });
options.push({ name: '480p - 1.5Mbps', maxWidth: 720, bitrate: 1500000 });
}
if (maxAllowedWidth >= 1260) {
options.push({ name: '720p - 4Mbps', maxWidth: 1280, bitrate: 4000000 });
options.push({ name: '720p - 3Mbps', maxWidth: 1280, bitrate: 3000000 });
options.push({ name: '720p - 2Mbps', maxWidth: 1280, bitrate: 2000000 });
// The extra 1 is because they're keyed off the bitrate value
options.push({ name: '720p - 1Mbps', maxWidth: 1280, bitrate: 1000001 });
}
options.push({ name: '480p - 1.0Mbps', maxWidth: 720, bitrate: 1000000 });
options.push({ name: '480p - 720kbps', maxWidth: 720, bitrate: 720000 });
options.push({ name: '480p - 420kbps', maxWidth: 720, bitrate: 420000 });
options.push({ name: '360p', maxWidth: 640, bitrate: 400000 });
options.push({ name: '240p', maxWidth: 426, bitrate: 320000 });
options.push({ name: '144p', maxWidth: 256, bitrate: 192000 });
var i, length, option;
var selectedIndex = -1;
for (i = 0, length = options.length; i < length; i++) {
option = options[i];
if (selectedIndex == -1 && option.bitrate <= bitrateSetting) {
selectedIndex = i;
}
}
if (selectedIndex == -1) {
selectedIndex = options.length - 1;
}
options[selectedIndex].selected = true;
return options;
};
self.getDeviceProfile = function () {
var qualityOption = self.getVideoQualityOptions().filter(function (q) {
return q.selected;
})[0];
var bitrateSetting = AppSettings.maxStreamingBitrate();
var canPlayWebm = self.canPlayWebm();
var profile = {};
profile.MaxStreamingBitrate = bitrateSetting;
profile.MaxStaticBitrate = 40000000;
profile.MusicStreamingTranscodingBitrate = Math.min(bitrateSetting, 192000);
profile.DirectPlayProfiles = [];
profile.DirectPlayProfiles.push({
Container: 'mp4',
Type: 'Video',
VideoCodec: 'h264',
AudioCodec: 'aac,mp3'
});
if ($.browser.chrome) {
profile.DirectPlayProfiles.push({
Container: 'mkv,m4v',
Type: 'Video',
VideoCodec: 'h264',
AudioCodec: 'aac,mp3'
});
}
profile.DirectPlayProfiles.push({
Container: 'mp3',
Type: 'Audio'
});
if (supportsAac) {
profile.DirectPlayProfiles.push({
Container: 'aac',
Type: 'Audio'
});
}
if (canPlayWebm) {
profile.DirectPlayProfiles.push({
Container: 'webm',
Type: 'Video'
});
profile.DirectPlayProfiles.push({
Container: 'webm,webma',
Type: 'Audio'
});
}
profile.TranscodingProfiles = [];
profile.TranscodingProfiles.push({
Container: 'mp3',
Type: 'Audio',
AudioCodec: 'mp3',
Context: 'Streaming',
Protocol: 'http'
});
if (self.canPlayHls()) {
profile.TranscodingProfiles.push({
Container: 'ts',
Type: 'Video',
AudioCodec: 'aac',
VideoCodec: 'h264',
Context: 'Streaming',
Protocol: 'hls'
});
}
if (canPlayWebm) {
profile.TranscodingProfiles.push({
Container: 'webm',
Type: 'Video',
AudioCodec: 'vorbis',
VideoCodec: 'vpx',
Context: 'Streaming',
Protocol: 'http'
});
}
profile.TranscodingProfiles.push({
Container: 'mp4',
Type: 'Video',
AudioCodec: 'aac',
VideoCodec: 'h264',
Context: 'Streaming',
Protocol: 'http'
});
profile.ContainerProfiles = [];
var audioConditions = [];
if ($.browser.msie) {
audioConditions.push({
Condition: 'LessThanEqual',
Property: 'AudioChannels',
Value: '2'
});
}
profile.CodecProfiles = [];
profile.CodecProfiles.push({
Type: 'Audio',
Conditions: audioConditions
});
profile.CodecProfiles.push({
Type: 'VideoAudio',
Conditions: audioConditions
});
profile.CodecProfiles.push({
Type: 'Video',
Codec: 'h264',
Conditions: [
{
Condition: 'Equals',
Property: 'IsCabac',
Value: 'true',
IsRequired: false
},
{
Condition: 'NotEquals',
Property: 'IsAnamorphic',
Value: 'true',
IsRequired: false
},
{
Condition: 'EqualsAny',
Property: 'VideoProfile',
Value: 'high|main|baseline|constrained baseline'
},
{
Condition: 'LessThanEqual',
Property: 'VideoLevel',
Value: '41'
},
{
Condition: 'LessThanEqual',
Property: 'Width',
Value: qualityOption.maxWidth
}]
});
profile.CodecProfiles.push({
Type: 'Video',
Codec: 'vpx',
Conditions: [
{
Condition: 'NotEquals',
Property: 'IsAnamorphic',
Value: 'true',
IsRequired: false
},
{
Condition: 'LessThanEqual',
Property: 'Width',
Value: qualityOption.maxWidth
}]
});
// Subtitle profiles
// External vtt or burn in
profile.SubtitleProfiles = [];
if (self.supportsTextTracks()) {
profile.SubtitleProfiles.push({
Format: 'vtt',
Method: 'External'
});
}
return profile;
};
self.updateCanClientSeek = function (elem) { self.updateCanClientSeek = function (elem) {
var duration = elem.duration; var duration = elem.duration;
@ -89,17 +341,27 @@
return currentSrc.substring(currentSrc.lastIndexOf('.')); return currentSrc.substring(currentSrc.lastIndexOf('.'));
}; };
self.getVideoTranscodingExtension = function (currentSrc) { self.canPlayHls = function () {
if (currentSrc) {
return self.getCurrentMediaExtension(currentSrc);
}
var media = testableVideoElement; var media = testableVideoElement;
// safari // safari
if (media.canPlayType('application/x-mpegURL').replace(/no/, '') || if (media.canPlayType('application/x-mpegURL').replace(/no/, '') ||
media.canPlayType('application/vnd.apple.mpegURL').replace(/no/, '')) { media.canPlayType('application/vnd.apple.mpegURL').replace(/no/, '')) {
return true;
}
return false;
};
self.getVideoTranscodingExtension = function (currentSrc) {
if (currentSrc) {
return self.getCurrentMediaExtension(currentSrc);
}
// safari
if (self.canPlayHls()) {
return '.m3u8'; return '.m3u8';
} }
@ -129,73 +391,49 @@
if (canClientSeek && params == null) { if (canClientSeek && params == null) {
element.currentTime = ticks / (1000 * 10000); element.currentTime = ticks / (1000 * 10000);
return;
} else { }
params = params || {}; params = params || {};
var currentSrc = element.currentSrc; var currentSrc = element.currentSrc;
var transcodingExtension; var playSessionId = getParameterByName('PlaySessionId', currentSrc);
var isStatic; var liveStreamId = getParameterByName('LiveStreamId', currentSrc);
var currentStreamId = getParameterByName('StreamId', currentSrc);
if (self.currentItem.MediaType == "Video") { if (params.AudioStreamIndex == null && params.SubtitleStreamIndex == null && params.Bitrate == null) {
transcodingExtension = self.getVideoTranscodingExtension(currentSrc); currentSrc = replaceQueryString(currentSrc, 'starttimeticks', ticks || 0);
changeStreamToUrl(element, playSessionId, currentSrc, ticks);
if (params.AudioStreamIndex != null) { return;
currentSrc = replaceQueryString(currentSrc, 'AudioStreamIndex', params.AudioStreamIndex);
}
if (params.SubtitleStreamIndex != null) {
currentSrc = replaceQueryString(currentSrc, 'SubtitleStreamIndex', (params.SubtitleStreamIndex == -1 ? '' : params.SubtitleStreamIndex));
} }
var maxWidth = params.MaxWidth || getParameterByName('MaxWidth', currentSrc); var deviceProfile = self.getDeviceProfile();
var audioStreamIndex = params.AudioStreamIndex == null ? getParameterByName('AudioStreamIndex', currentSrc) : params.AudioStreamIndex;
var audioStreamIndex = params.AudioStreamIndex == null ? (getParameterByName('AudioStreamIndex', currentSrc) || null) : params.AudioStreamIndex;
if (typeof (audioStreamIndex) == 'string') { if (typeof (audioStreamIndex) == 'string') {
audioStreamIndex = parseInt(audioStreamIndex); audioStreamIndex = parseInt(audioStreamIndex);
} }
var subtitleStreamIndex = self.currentSubtitleStreamIndex;
var videoBitrate = parseInt(getParameterByName('VideoBitrate', currentSrc) || '0');
var audioBitrate = parseInt(getParameterByName('AudioBitrate', currentSrc) || '0');
var bitrate = params.Bitrate || (videoBitrate + audioBitrate);
var finalParams = self.getFinalVideoParams(self.currentMediaSource, maxWidth, bitrate, audioStreamIndex, subtitleStreamIndex, transcodingExtension); var subtitleStreamIndex = params.SubtitleStreamIndex == null ? (getParameterByName('SubtitleStreamIndex', currentSrc) || null) : params.SubtitleStreamIndex;
if (typeof (subtitleStreamIndex) == 'string') {
currentSrc = replaceQueryString(currentSrc, 'MaxWidth', finalParams.maxWidth); subtitleStreamIndex = parseInt(subtitleStreamIndex);
currentSrc = replaceQueryString(currentSrc, 'VideoBitrate', finalParams.videoBitrate);
currentSrc = replaceQueryString(currentSrc, 'VideoCodec', finalParams.videoCodec);
currentSrc = replaceQueryString(currentSrc, 'profile', finalParams.profile || '');
currentSrc = replaceQueryString(currentSrc, 'level', finalParams.level || '');
if (finalParams.isStatic) {
currentSrc = currentSrc.replace('.webm', '.mp4').replace('.m3u8', '.mp4');
currentSrc = replaceQueryString(currentSrc, 'ClientTime', '');
} else {
currentSrc = currentSrc.replace('.mp4', transcodingExtension).replace('.m4v', transcodingExtension).replace('.mkv', transcodingExtension).replace('.webm', transcodingExtension);
currentSrc = replaceQueryString(currentSrc, 'ClientTime', new Date().getTime());
} }
currentSrc = replaceQueryString(currentSrc, 'AudioBitrate', finalParams.audioBitrate); getPlaybackInfo(self.currentItem.Id, deviceProfile, ticks, self.currentMediaSource, audioStreamIndex, subtitleStreamIndex, liveStreamId).done(function (result) {
currentSrc = replaceQueryString(currentSrc, 'Static', finalParams.isStatic);
currentSrc = replaceQueryString(currentSrc, 'AudioCodec', finalParams.audioCodec);
isStatic = finalParams.isStatic;
} else {
transcodingExtension = '.mp3';
}
var isSeekableMedia = self.currentMediaSource.RunTimeTicks; if (validatePlaybackInfoResult(result)) {
var isClientSeekable = isStatic || (isSeekableMedia && transcodingExtension == '.m3u8');
if (isClientSeekable || !ticks || !isSeekableMedia) { self.currentMediaSource = result.MediaSources[0];
currentSrc = replaceQueryString(currentSrc, 'starttimeticks', ''); self.currentSubtitleStreamIndex = subtitleStreamIndex;
}
else { currentSrc = ApiClient.getUrl(self.currentMediaSource.TranscodingUrl);
currentSrc = replaceQueryString(currentSrc, 'starttimeticks', ticks); changeStreamToUrl(element, playSessionId, currentSrc, ticks);
} }
});
};
function changeStreamToUrl(element, playSessionId, url, newPositionTicks) {
clearProgressInterval(); clearProgressInterval();
@ -211,21 +449,20 @@
}); });
if (self.currentItem.MediaType == "Video") { if (self.currentItem.MediaType == "Video") {
ApiClient.stopActiveEncodings(currentStreamId).done(function () { ApiClient.stopActiveEncodings(playSessionId).done(function () {
self.startTimeTicksOffset = ticks; self.startTimeTicksOffset = newPositionTicks;
element.src = currentSrc; element.src = url;
}); });
self.updateTextStreamUrls(ticks || 0); self.updateTextStreamUrls(newPositionTicks || 0);
} else { } else {
self.startTimeTicksOffset = ticks; self.startTimeTicksOffset = newPositionTicks;
element.src = currentSrc; element.src = url;
element.play(); element.play();
} }
} }
};
self.setCurrentTime = function (ticks, positionSlider, currentTimeElement) { self.setCurrentTime = function (ticks, positionSlider, currentTimeElement) {
@ -274,143 +511,6 @@
return supportsTextTracks; return supportsTextTracks;
}; };
self.getVideoDirectPlayMethod = function (mediaSource, videoStream, audioStream, subtitleStream, maxWidth, bitrate) {
if (!mediaSource) {
throw new Error('Null mediaSource');
}
if (!videoStream) {
console.log('Cannot direct play without videoStream info');
return null;
}
if (mediaSource.Protocol.toLowerCase() == "rtmp" || mediaSource.Protocol.toLowerCase() == "rtsp") {
//console.log('Transcoding because the content is not a video file');
return null;
}
if (mediaSource.VideoType && mediaSource.VideoType != "VideoFile") {
//console.log('Transcoding because the content is not a video file');
return null;
}
var isH264 = (videoStream.Codec || '').toLowerCase().indexOf('h264') != -1;
if (!isH264) {
console.log('Transcoding because the content is not h264');
return null;
}
if (audioStream && !canPlayAudioStreamDirect(audioStream)) {
console.log('Transcoding because the audio cannot be played directly.');
return null;
}
if (subtitleStream && (!subtitleStream.SupportsExternalStream || !subtitleStream.IsTextSubtitleStream || !self.supportsTextTracks())) {
console.log('Transcoding because subtitles are required');
return null;
}
if (videoStream.IsCabac != null && !videoStream.IsCabac) {
console.log('Video not CABAC');
//return false;
}
if (!videoStream.Width) {
console.log('Transcoding because resolution is unknown');
return null;
}
if (videoStream.Width > maxWidth) {
console.log('Transcoding because resolution is too high');
return null;
}
if (videoStream && videoStream.IsAnamorphic) {
console.log('Transcoding because video is anamorphic');
return null;
}
if (!mediaSource.Bitrate) {
console.log('Transcoding because bitrate is unknown');
return null;
}
if (mediaSource.Bitrate > bitrate) {
console.log('Transcoding because bitrate is too high');
return null;
}
var extension = (mediaSource.Container || '').toLowerCase();
var profile = (videoStream ? (videoStream.Profile || '') : '').toLowerCase();
// only support high, baseline variants and main variants
if (isH264 && profile != 'high' && profile.indexOf('baseline') == -1 && profile.indexOf('main') == -1) {
console.log('Transcoding because of unsupported h264 profile');
return null;
}
if (mediaSource.Protocol == 'Http') {
if (Dashboard.isConnectMode()) {
return null;
}
return 'DirectPlay';
}
if (extension == 'mp4') {
return 'DirectStream';
}
if (extension == 'm4v' || extension == 'mkv') {
if ($.browser.chrome) {
return 'DirectStream';
}
}
return null;
};
self.getFinalVideoParams = function (mediaSource, maxWidth, bitrate, audioStreamIndex, subtitleStreamIndex, transcodingExtension) {
var mediaStreams = mediaSource.MediaStreams;
var videoStream = mediaStreams.filter(function (stream) {
return stream.Type === "Video";
})[0];
var audioStream = mediaStreams.filter(function (stream) {
return stream.Index === audioStreamIndex && stream.Type == 'Audio';
})[0];
var subtitleStream = mediaStreams.filter(function (stream) {
return stream.Index === subtitleStreamIndex && stream.Type == 'Subtitle';
})[0];
var directPlayMethod = self.getVideoDirectPlayMethod(mediaSource, videoStream, audioStream, subtitleStream, maxWidth, bitrate);
var audioBitrate = bitrate >= 700000 ? 192000 : 64000;
var videoBitrate = bitrate - audioBitrate;
var params = {
isStatic: directPlayMethod != null,
maxWidth: maxWidth,
audioCodec: transcodingExtension == '.webm' ? 'vorbis' : 'aac',
videoCodec: transcodingExtension == '.webm' ? 'vpx' : 'h264',
audioBitrate: audioBitrate,
videoBitrate: videoBitrate
};
if (params.videoCodec == 'h264') {
params.profile = 'baseline';
params.level = '3';
}
return params;
};
self.canQueueMediaType = function (mediaType) { self.canQueueMediaType = function (mediaType) {
return self.currentItem && self.currentItem.MediaType == mediaType; return self.currentItem && self.currentItem.MediaType == mediaType;
@ -504,11 +604,6 @@
}; };
self.getMaxPlayableWidth = function () {
return Math.max(screen.height, screen.width);
};
self.playWithIntros = function (items, options, user) { self.playWithIntros = function (items, options, user) {
var firstItem = items[0]; var firstItem = items[0];
@ -532,40 +627,31 @@
}); });
}; };
function getOptimalMediaSource(mediaType, versions) { function supportsDirectPlay(mediaSource) {
var optimalVersion; if (mediaSource.SupportsDirectPlay && mediaSource.Protocol == 'Http' && !mediaSource.RequiredHttpHeaders.length) {
var bitrateSetting = AppSettings.maxStreamingBitrate();
if (mediaType == 'Video') { // TODO: Need to verify the host is going to be reachable
var maxAllowedWidth = self.getMaxPlayableWidth();
optimalVersion = versions.filter(function (v) {
var videoStream = v.MediaStreams.filter(function (s) {
return s.Type == 'Video';
})[0];
var audioStream = v.MediaStreams.filter(function (s) {
return s.Type == 'Audio';
})[0];
var directPlayMethod = self.getVideoDirectPlayMethod(v, videoStream, audioStream, null, maxAllowedWidth, bitrateSetting);
if (directPlayMethod == 'DirectPlay') {
return true; return true;
} }
return v.SupportsDirectStream && directPlayMethod == 'DirectStream'; return false;
}
function getOptimalMediaSource(mediaType, versions) {
var optimalVersion = versions.filter(function (v) {
v.enableDirectPlay = supportsDirectPlay(v);
return v.enableDirectPlay;
})[0]; })[0];
} else { if (!optimalVersion) {
optimalVersion = versions.filter(function (v) { optimalVersion = versions.filter(function (v) {
return v.SupportsDirectStream && canPlayAudioMediaSourceDirect(v); return v.SupportsDirectStream;
})[0]; })[0];
} }
@ -575,6 +661,153 @@
})[0]; })[0];
} }
function getPlaybackInfo(itemId, deviceProfile, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex, liveStreamId) {
var postData = {
DeviceProfile: deviceProfile
};
var query = {
UserId: Dashboard.getCurrentUserId(),
StartTimeTicks: startPosition || 0
};
if (audioStreamIndex != null) {
query.AudioStreamIndex = audioStreamIndex;
}
if (subtitleStreamIndex != null) {
query.SubtitleStreamIndex = subtitleStreamIndex;
}
if (mediaSource) {
query.MediaSourceId = mediaSource.Id;
}
if (liveStreamId) {
query.LiveStreamId = liveStreamId;
}
return ApiClient.ajax({
url: ApiClient.getUrl('Items/' + itemId + '/PlaybackInfo', query),
type: 'POST',
data: JSON.stringify(postData),
contentType: "application/json",
dataType: "json"
});
}
function getLiveStream(itemId, deviceProfile, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex) {
var postData = {
DeviceProfile: deviceProfile,
OpenToken: mediaSource.OpenToken
};
var query = {
UserId: Dashboard.getCurrentUserId(),
StartTimeTicks: startPosition || 0,
ItemId: itemId
};
if (audioStreamIndex != null) {
query.AudioStreamIndex = audioStreamIndex;
}
if (subtitleStreamIndex != null) {
query.SubtitleStreamIndex = subtitleStreamIndex;
}
return ApiClient.ajax({
url: ApiClient.getUrl('LiveStreams/Open', query),
type: 'POST',
data: JSON.stringify(postData),
contentType: "application/json",
dataType: "json"
});
}
self.createStreamInfo = function (type, item, mediaSource, startPosition) {
var mediaUrl;
var contentType;
var startTimeTicksOffset = 0;
var startPositionInSeekParam = startPosition ? (startPosition / 10000000) : 0;
var seekParam = startPositionInSeekParam ? '#t=' + startPositionInSeekParam : '';
if (type == 'video') {
contentType = 'video/' + mediaSource.Container;
if (mediaSource.enableDirectPlay) {
mediaUrl = mediaSource.Path;
} else {
if (mediaSource.SupportsDirectStream) {
mediaUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.' + mediaSource.Container, {
Static: true,
mediaSourceId: mediaSource.Id,
api_key: ApiClient.accessToken()
});
mediaUrl += seekParam;
} else {
startTimeTicksOffset = startPosition || 0;
mediaUrl = ApiClient.getUrl(mediaSource.TranscodingUrl);
if (mediaSource.TranscodingSubProtocol == 'hls') {
mediaUrl += seekParam;
contentType = 'application/x-mpegURL';
} else {
contentType = 'video/' + mediaSource.TranscodingContainer;
}
}
}
} else {
contentType = 'audio/' + mediaSource.Container;
if (mediaSource.enableDirectPlay) {
mediaUrl = mediaSource.Path;
} else {
var isDirectStream = mediaSource.SupportsDirectStream;
if (isDirectStream) {
var outputContainer = (mediaSource.Container || '').toLowerCase();
mediaUrl = ApiClient.getUrl('Audio/' + item.Id + '/stream.' + outputContainer, {
mediaSourceId: mediaSource.Id,
deviceId: ApiClient.deviceId(),
api_key: ApiClient.accessToken()
});
mediaUrl += "&static=true" + seekParam;
} else {
contentType = 'audio/' + mediaSource.TranscodingContainer;
mediaUrl = ApiClient.getUrl(mediaSource.TranscodingUrl);
}
startTimeTicksOffset = startPosition || 0;
}
}
return {
url: mediaUrl,
contentType: contentType,
startTimeTicksOffset: startTimeTicksOffset,
startPositionInSeekParam: startPositionInSeekParam
};
};
self.playInternal = function (item, startPosition, callback) { self.playInternal = function (item, startPosition, callback) {
if (item == null) { if (item == null) {
@ -595,11 +828,9 @@
} }
var mediaSource; var mediaSource;
var deviceProfile = self.getDeviceProfile();
ApiClient.getJSON(ApiClient.getUrl('Items/' + item.Id + '/PlaybackInfo', { getPlaybackInfo(item.Id, deviceProfile, startPosition).done(function (result) {
userId: Dashboard.getCurrentUserId()
})).done(function (result) {
if (validatePlaybackInfoResult(result)) { if (validatePlaybackInfoResult(result)) {
@ -607,26 +838,17 @@
if (mediaSource) { if (mediaSource) {
self.currentMediaSource = mediaSource; if (mediaSource.RequiresOpening) {
self.currentItem = item;
if (item.MediaType === "Video") { getLiveStream(item.Id, deviceProfile, startPosition, mediaSource, null, null).done(function (openLiveStreamResult) {
self.currentMediaElement = self.playVideo(result, item, self.currentMediaSource, startPosition); openLiveStreamResult.MediaSource.enableDirectPlay = supportsDirectPlay(openLiveStreamResult.MediaSource);
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks; playInternalPostMediaSourceSelection(item, openLiveStreamResult.MediaSource, startPosition, callback);
});
self.updateNowPlayingInfo(item); } else {
playInternalPostMediaSourceSelection(item, mediaSource, startPosition, callback);
} else if (item.MediaType === "Audio") {
self.currentMediaElement = playAudio(result, item, self.currentMediaSource, startPosition);
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
} }
if (callback) {
callback();
}
} else { } else {
showPlaybackInfoErrorMessage('NoCompatibleStream'); showPlaybackInfoErrorMessage('NoCompatibleStream');
} }
@ -635,6 +857,29 @@
}); });
}; };
function playInternalPostMediaSourceSelection(item, mediaSource, startPosition, callback) {
self.currentMediaSource = mediaSource;
self.currentItem = item;
if (item.MediaType === "Video") {
self.currentMediaElement = self.playVideo(item, self.currentMediaSource, startPosition);
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
self.updateNowPlayingInfo(item);
} else if (item.MediaType === "Audio") {
self.currentMediaElement = playAudio(item, self.currentMediaSource, startPosition);
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
}
if (callback) {
callback();
}
}
function validatePlaybackInfoResult(result) { function validatePlaybackInfoResult(result) {
if (result.ErrorCode) { if (result.ErrorCode) {
@ -1103,12 +1348,10 @@
self.currentMediaSource = null; self.currentMediaSource = null;
} }
if (self.currentItem && self.currentItem.MediaType == "Video") {
if (self.isFullScreen()) { if (self.isFullScreen()) {
self.exitFullScreen(); self.exitFullScreen();
} }
self.resetEnhancements(); self.resetEnhancements();
}
}; };
self.isPlaying = function () { self.isPlaying = function () {
@ -1153,6 +1396,9 @@
state.PlayState.PlayMethod = getParameterByName('static', currentSrc) == 'true' ? state.PlayState.PlayMethod = getParameterByName('static', currentSrc) == 'true' ?
'DirectStream' : 'DirectStream' :
'Transcode'; 'Transcode';
state.PlayState.LiveStreamId = getParameterByName('LiveStreamId', currentSrc);
state.PlayState.PlaySessionId = getParameterByName('PlaySessionId', currentSrc);
} }
} }
@ -1276,7 +1522,7 @@
var playerElement = this; var playerElement = this;
var currentStreamId = getParameterByName('StreamId', playerElement.currentSrc); var playSessionId = getParameterByName('PlaySessionId', playerElement.currentSrc);
$(playerElement).off('.mediaplayerevent').off('ended.playbackstopped'); $(playerElement).off('.mediaplayerevent').off('ended.playbackstopped');
@ -1289,7 +1535,6 @@
if (item.MediaType == "Video") { if (item.MediaType == "Video") {
ApiClient.stopActiveEncodings(currentStreamId);
if (self.isFullScreen()) { if (self.isFullScreen()) {
self.exitFullScreen(); self.exitFullScreen();
} }
@ -1319,7 +1564,8 @@
function sendProgressUpdate() { function sendProgressUpdate() {
var state = self.getPlayerStateInternal(self.currentMediaElement, self.currentItem, self.currentMediaSource); var element = self.currentMediaElement;
var state = self.getPlayerStateInternal(element, self.currentItem, self.currentMediaSource);
var info = { var info = {
QueueableMediaTypes: state.NowPlayingItem.MediaType, QueueableMediaTypes: state.NowPlayingItem.MediaType,
@ -1380,63 +1626,11 @@
return $('.mediaPlayerAudio'); return $('.mediaPlayerAudio');
} }
function canPlayAudioMediaSourceDirect(mediaSource) { function playAudio(item, mediaSource, startPositionTicks) {
var sourceContainer = (mediaSource.Container || '').toLowerCase(); var streamInfo = self.createStreamInfo('audio', item, mediaSource, startPositionTicks);
var audioUrl = streamInfo.url;
if (sourceContainer == 'mp3' || self.startTimeTicksOffset = streamInfo.startTimeTicksOffset;
(sourceContainer == 'aac' && supportsAac)) {
for (var i = 0, length = mediaSource.MediaStreams.length; i < length; i++) {
var stream = mediaSource.MediaStreams[i];
if (stream.Type == "Audio") {
// Stream statically when possible
if (stream.BitRate <= 320000) {
return true;
}
break;
}
}
}
return false;
}
var supportsAac = document.createElement('audio').canPlayType('audio/aac').replace(/no/, '');
function playAudio(playbackInfo, item, mediaSource, startPositionTicks) {
startPositionTicks = startPositionTicks || 0;
var baseParams = {
audioChannels: 2,
audioBitrate: 128000,
StartTimeTicks: startPositionTicks,
mediaSourceId: mediaSource.Id,
deviceId: ApiClient.deviceId(),
api_key: ApiClient.accessToken(),
StreamId: playbackInfo.StreamId
};
var sourceContainer = (mediaSource.Container || '').toLowerCase();
var isStatic = canPlayAudioMediaSourceDirect(mediaSource);
var outputContainer = isStatic ? sourceContainer : 'mp3';
var audioUrl = ApiClient.getUrl('Audio/' + item.Id + '/stream.' + outputContainer, $.extend({}, baseParams, {
audioCodec: outputContainer
}));
if (isStatic) {
var seekParam = startPositionTicks ? '#t=' + (startPositionTicks / 10000000) : '';
audioUrl += "&static=true" + seekParam;
} else {
audioUrl += "&ClientTime=" + new Date().getTime();
}
self.startTimeTicksOffset = isStatic ? 0 : startPositionTicks;
var initialVolume = self.getSavedVolume(); var initialVolume = self.getSavedVolume();
@ -1488,31 +1682,6 @@
})[0]; })[0];
}; };
function canPlayAudioStreamDirect(audioStream) {
var audioCodec = (audioStream.Codec || '').toLowerCase().replace('-', '');
if (audioCodec.indexOf('aac') == -1 &&
audioCodec.indexOf('mp3') == -1 &&
audioCodec.indexOf('mpeg') == -1) {
console.log('Cannot direct play. Unsupported audio codec');
return false;
}
if (audioStream.Channels == null) {
return false;
}
// IE won't play at all if more than two channels
if (audioStream.Channels > 2 && $.browser.msie) {
return false;
}
return true;
}
var getItemFields = "MediaSources,Chapters"; var getItemFields = "MediaSources,Chapters";
self.getCurrentTargetInfo = function () { self.getCurrentTargetInfo = function () {

View file

@ -74,6 +74,17 @@
lazy: true lazy: true
}); });
} }
else if (view == "Thumb") {
html = LibraryBrowser.getPosterViewHtml({
items: result.Items,
shape: "backdrop",
context: 'movies',
showTitle: true,
centerText: true,
lazy: true,
preferThumb: true
});
}
$('.noItemsMessage', page).hide(); $('.noItemsMessage', page).hide();

View file

@ -9,7 +9,7 @@
SortOrder: "Ascending", SortOrder: "Ascending",
IncludeItemTypes: "Movie", IncludeItemTypes: "Movie",
Recursive: true, Recursive: true,
Fields: "DateCreated,SyncInfo", Fields: "DateCreated,SyncInfo,ItemCounts",
StartIndex: 0 StartIndex: 0
}; };

View file

@ -9,7 +9,7 @@
SortOrder: "Ascending", SortOrder: "Ascending",
IncludeItemTypes: "Movie,Trailer", IncludeItemTypes: "Movie,Trailer",
Recursive: true, Recursive: true,
Fields: "DateCreated", Fields: "DateCreated,ItemCounts",
PersonTypes: "", PersonTypes: "",
StartIndex: 0, StartIndex: 0,
Limit: 100 Limit: 100

View file

@ -1,34 +0,0 @@
(function ($, document) {
$(document).on('pagebeforeshow', "#moviesLatestPage", function () {
var parentId = LibraryMenu.getTopParentId();
var userId = Dashboard.getCurrentUserId();
var page = this;
var options = {
IncludeItemTypes: "Movie",
Limit: 30,
Fields: "PrimaryImageAspectRatio,MediaSourceCount,SyncInfo",
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: "Primary,Backdrop,Banner,Thumb"
};
ApiClient.getJSON(ApiClient.getUrl('Users/' + userId + '/Items/Latest', options)).done(function (items) {
$('#recentlyAddedItems', page).html(LibraryBrowser.getPosterViewHtml({
items: items,
lazy: true,
shape: 'portrait',
overlayText: false
})).lazyChildren().trigger('create');
});
});
})(jQuery, document);

View file

@ -1,5 +1,29 @@
(function ($, document) { (function ($, document) {
function loadLatest(page, userId, parentId) {
var options = {
IncludeItemTypes: "Movie",
Limit: 20,
Fields: "PrimaryImageAspectRatio,MediaSourceCount,SyncInfo",
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: "Primary,Backdrop,Banner,Thumb"
};
ApiClient.getJSON(ApiClient.getUrl('Users/' + userId + '/Items/Latest', options)).done(function (items) {
$('#recentlyAddedItems', page).html(LibraryBrowser.getPosterViewHtml({
items: items,
lazy: true,
shape: 'portrait',
overlayText: false
})).lazyChildren().trigger('create');
});
}
function getRecommendationHtml(recommendation) { function getRecommendationHtml(recommendation) {
var html = ''; var html = '';
@ -51,6 +75,7 @@
var screenWidth = $(window).width(); var screenWidth = $(window).width();
var page = this; var page = this;
var userId = Dashboard.getCurrentUserId();
var options = { var options = {
@ -58,7 +83,7 @@
SortOrder: "Descending", SortOrder: "Descending",
IncludeItemTypes: "Movie", IncludeItemTypes: "Movie",
Filters: "IsResumable", Filters: "IsResumable",
Limit: screenWidth >= 1920 ? 12 : (screenWidth >= 1600 ? 8 : 6), Limit: screenWidth >= 1920 ? 6 : (screenWidth >= 1600 ? 4 : 3),
Recursive: true, Recursive: true,
Fields: "PrimaryImageAspectRatio,MediaSourceCount,SyncInfo", Fields: "PrimaryImageAspectRatio,MediaSourceCount,SyncInfo",
CollapseBoxSetItems: false, CollapseBoxSetItems: false,
@ -67,7 +92,7 @@
EnableImageTypes: "Primary,Backdrop,Banner,Thumb" EnableImageTypes: "Primary,Backdrop,Banner,Thumb"
}; };
ApiClient.getItems(Dashboard.getCurrentUserId(), options).done(function (result) { ApiClient.getItems(userId, options).done(function (result) {
if (result.Items.length) { if (result.Items.length) {
$('#resumableSection', page).show(); $('#resumableSection', page).show();
@ -87,9 +112,11 @@
}); });
loadLatest(page, userId, parentId);
var url = ApiClient.getUrl("Movies/Recommendations", { var url = ApiClient.getUrl("Movies/Recommendations", {
userId: Dashboard.getCurrentUserId(), userId: userId,
categoryLimit: screenWidth >= 1200 ? 4 : 3, categoryLimit: screenWidth >= 1200 ? 4 : 3,
ItemLimit: screenWidth >= 1920 ? 10 : (screenWidth >= 1600 ? 8 : (screenWidth >= 1200 ? 7 : 6)), ItemLimit: screenWidth >= 1920 ? 10 : (screenWidth >= 1600 ? 8 : (screenWidth >= 1200 ? 7 : 6)),
Fields: "PrimaryImageAspectRatio,MediaSourceCount,SyncInfo", Fields: "PrimaryImageAspectRatio,MediaSourceCount,SyncInfo",

View file

@ -7,7 +7,7 @@
SortOrder: "Ascending", SortOrder: "Ascending",
IncludeItemTypes: "Movie", IncludeItemTypes: "Movie",
Recursive: true, Recursive: true,
Fields: "DateCreated", Fields: "DateCreated,ItemCounts",
StartIndex: 0 StartIndex: 0
}; };

View file

@ -10,7 +10,7 @@
SortBy: "SortName", SortBy: "SortName",
SortOrder: "Ascending", SortOrder: "Ascending",
Recursive: true, Recursive: true,
Fields: "PrimaryImageAspectRatio,SortName,DateCreated,SyncInfo", Fields: "PrimaryImageAspectRatio,SortName,DateCreated,SyncInfo,ItemCounts",
StartIndex: 0, StartIndex: 0,
ImageTypeLimit: 1, ImageTypeLimit: 1,
EnableImageTypes: "Primary,Backdrop,Banner,Thumb" EnableImageTypes: "Primary,Backdrop,Banner,Thumb"

View file

@ -10,7 +10,7 @@
SortBy: "SortName", SortBy: "SortName",
SortOrder: "Ascending", SortOrder: "Ascending",
Recursive: true, Recursive: true,
Fields: "PrimaryImageAspectRatio,SortName,DateCreated,SyncInfo", Fields: "PrimaryImageAspectRatio,SortName,DateCreated,SyncInfo,ItemCounts",
StartIndex: 0, StartIndex: 0,
ImageTypeLimit: 1, ImageTypeLimit: 1,
EnableImageTypes: "Primary,Backdrop,Banner,Thumb" EnableImageTypes: "Primary,Backdrop,Banner,Thumb"

View file

@ -7,7 +7,7 @@
SortOrder: "Ascending", SortOrder: "Ascending",
IncludeItemTypes: "Audio,MusicVideo", IncludeItemTypes: "Audio,MusicVideo",
Recursive: true, Recursive: true,
Fields: "DateCreated,SyncInfo", Fields: "DateCreated,SyncInfo,ItemCounts",
StartIndex: 0 StartIndex: 0
}; };

View file

@ -133,6 +133,8 @@
$('#chkDisplayCollectionView', page).checked(user.Configuration.DisplayCollectionsView || false).checkboxradio("refresh"); $('#chkDisplayCollectionView', page).checked(user.Configuration.DisplayCollectionsView || false).checkboxradio("refresh");
$('#chkDisplayFolderView', page).checked(user.Configuration.DisplayFoldersView || false).checkboxradio("refresh"); $('#chkDisplayFolderView', page).checked(user.Configuration.DisplayFoldersView || false).checkboxradio("refresh");
$('#chkHidePlayedFromLatest', page).checked(user.Configuration.HidePlayedInLatest || false).checkboxradio("refresh");
var promise1 = ApiClient.getItems(user.Id, { var promise1 = ApiClient.getItems(user.Id, {
sortBy: "SortName" sortBy: "SortName"
}); });
@ -163,6 +165,8 @@
user.Configuration.DisplayCollectionsView = $('#chkDisplayCollectionView', page).checked(); user.Configuration.DisplayCollectionsView = $('#chkDisplayCollectionView', page).checked();
user.Configuration.DisplayFoldersView = $('#chkDisplayFolderView', page).checked(); user.Configuration.DisplayFoldersView = $('#chkDisplayFolderView', page).checked();
user.Configuration.HidePlayedInLatest = $('#chkHidePlayedFromLatest', page).checked();
user.Configuration.IncludeTrailersInSuggestions = $('#chkDisplayTrailersWithinMovieSuggestions', page).checked(); user.Configuration.IncludeTrailersInSuggestions = $('#chkDisplayTrailersWithinMovieSuggestions', page).checked();
user.Configuration.LatestItemsExcludes = $(".chkIncludeInLatest:not(:checked)", page).get().map(function (i) { user.Configuration.LatestItemsExcludes = $(".chkIncludeInLatest:not(:checked)", page).get().map(function (i) {

View file

@ -185,8 +185,7 @@ var Dashboard = {
var url = getWindowUrl().toLowerCase(); var url = getWindowUrl().toLowerCase();
return url.indexOf('mediabrowser.tv') != -1 || return url.indexOf('mediabrowser.tv') != -1 ||
url.indexOf('emby.media') != -1 || url.indexOf('emby.media') != -1;
url.indexOf('mediabrowser.github') != -1;
}, },
logout: function (logoutWithServer) { logout: function (logoutWithServer) {
@ -756,6 +755,9 @@ var Dashboard = {
var pageElem = page[0]; var pageElem = page[0];
var isServicesPage = page.hasClass('appServicesPage');
var context = getParameterByName('context');
return [{ return [{
name: Globalize.translate('TabServer'), name: Globalize.translate('TabServer'),
href: "dashboard.html", href: "dashboard.html",
@ -793,7 +795,7 @@ var Dashboard = {
}, { }, {
name: Globalize.translate('TabSync'), name: Globalize.translate('TabSync'),
href: "syncactivity.html", href: "syncactivity.html",
selected: page.hasClass('syncConfigurationPage'), selected: page.hasClass('syncConfigurationPage') || (isServicesPage && context == 'sync'),
icon: 'fa-cloud' icon: 'fa-cloud'
}, { }, {
divider: true, divider: true,
@ -813,7 +815,7 @@ var Dashboard = {
}, { }, {
name: Globalize.translate('TabLiveTV'), name: Globalize.translate('TabLiveTV'),
href: "livetvstatus.html", href: "livetvstatus.html",
selected: page.hasClass("liveTvSettingsPage"), selected: page.hasClass("liveTvSettingsPage") || (isServicesPage && context == 'livetv'),
icon: 'fa-video-camera', icon: 'fa-video-camera',
color: '#293AAE' color: '#293AAE'
}, { }, {
@ -1352,7 +1354,9 @@ var Dashboard = {
}); });
if (!Dashboard.isServerlessPage()) { if (!Dashboard.isServerlessPage()) {
if (Dashboard.serverAddress() && Dashboard.getCurrentUserId() && Dashboard.getAccessToken()) { if (Dashboard.serverAddress() && Dashboard.getCurrentUserId() && Dashboard.getAccessToken()) {
window.ApiClient = new MediaBrowser.ApiClient(Logger, Dashboard.serverAddress(), appName, appVersion, deviceName, deviceId); window.ApiClient = new MediaBrowser.ApiClient(Logger, Dashboard.serverAddress(), appName, appVersion, deviceName, deviceId);
ApiClient.setCurrentUserId(Dashboard.getCurrentUserId(), Dashboard.getAccessToken()); ApiClient.setCurrentUserId(Dashboard.getCurrentUserId(), Dashboard.getAccessToken());
@ -1361,6 +1365,7 @@ var Dashboard = {
ConnectionManager.addApiClient(ApiClient, true).fail(Dashboard.logout); ConnectionManager.addApiClient(ApiClient, true).fail(Dashboard.logout);
} else { } else {
Dashboard.logout(); Dashboard.logout();
return; return;
} }

View file

@ -43,10 +43,10 @@
return $(".radioDonationType:checked", page).val(); return $(".radioDonationType:checked", page).val();
} }
var lifeTimeAmount = 40; var lifeTimeAmount = 59;
var dailyAmount = 1; var dailyAmount = 1;
var monthlyAmount = 4; var monthlyAmount = 4;
var yearlyAmount = 28; var yearlyAmount = 32;
function getDonationAmount(page) { function getDonationAmount(page) {
var type = getDonationType(page); var type = getDonationType(page);

View file

@ -1,66 +0,0 @@
(function ($, document) {
function reloadList(page) {
Dashboard.showLoadingMsg();
var promise1 = ApiClient.getAvailablePlugins({
TargetSystems: 'Server'
});
var promise2 = ApiClient.getInstalledPlugins();
$.when(promise1, promise2).done(function (response1, response2) {
renderInstalled(page, response1[0], response2[0]);
renderCatalog(page, response1[0], response2[0]);
});
}
function renderInstalled(page, availablePlugins, installedPlugins) {
installedPlugins = installedPlugins.filter(function (i) {
var catalogEntry = availablePlugins.filter(function (a) {
return a.guid == i.Id;
})[0];
return catalogEntry && catalogEntry.category == 'Sync';
});
PluginsPage.renderPlugins(page, installedPlugins);
}
function renderCatalog(page, availablePlugins, installedPlugins) {
PluginCatalog.renderCatalog({
catalogElement: $('.catalog', page),
availablePlugins: availablePlugins,
installedPlugins: installedPlugins,
categories: ['Sync'],
showCategory: false,
context: 'sync',
targetSystem: 'Server'
});
}
$(document).on('pageshow', "#syncServicesPage", function () {
var page = this;
reloadList(page);
Dashboard.getPluginSecurityInfo().done(function (pluginSecurityInfo) {
if (pluginSecurityInfo.IsMBSupporter) {
$('.syncPromotion', page).hide();
} else {
$('.syncPromotion', page).show();
}
});
});
})(jQuery, document);

View file

@ -113,7 +113,7 @@ $.fn.taskButton = function (options) {
ApiClient.sendWebSocketMessage("ScheduledTasksInfoStop"); ApiClient.sendWebSocketMessage("ScheduledTasksInfoStop");
} }
} else { } else if (this.length) {
this.on('click.taskbutton', function () { this.on('click.taskbutton', function () {

View file

@ -9,7 +9,7 @@
SortOrder: "Ascending", SortOrder: "Ascending",
IncludeItemTypes: "Series", IncludeItemTypes: "Series",
Recursive: true, Recursive: true,
Fields: "DateCreated,SyncInfo", Fields: "DateCreated,SyncInfo,ItemCounts",
StartIndex: 0 StartIndex: 0
}; };

View file

@ -9,7 +9,7 @@
SortOrder: "Ascending", SortOrder: "Ascending",
IncludeItemTypes: "Series,Episode", IncludeItemTypes: "Series,Episode",
Recursive: true, Recursive: true,
Fields: "DateCreated", Fields: "DateCreated,ItemCounts",
PersonTypes: "", PersonTypes: "",
StartIndex: 0, StartIndex: 0,
Limit: 100 Limit: 100

View file

@ -7,7 +7,7 @@
SortOrder: "Ascending", SortOrder: "Ascending",
IncludeItemTypes: "Series", IncludeItemTypes: "Series",
Recursive: true, Recursive: true,
Fields: "DateCreated", Fields: "DateCreated,ItemCounts",
StartIndex: 0 StartIndex: 0
}; };

View file

@ -14,12 +14,7 @@
var id = 'mediaFolder' + i; var id = 'mediaFolder' + i;
var isChecked; var isChecked = user.Policy.EnableAllFolders || user.Policy.EnabledFolders.indexOf(folder.Id) != -1;
if (user.Policy.BlockedMediaFolders != null) {
isChecked = user.Policy.BlockedMediaFolders.indexOf(folder.Id) == -1 && user.Policy.BlockedMediaFolders.indexOf(folder.Name) == -1;
} else {
isChecked = user.Policy.EnableAllFolders || user.Policy.EnabledFolders.indexOf(folder.Id) != -1;
}
var checkedAttribute = isChecked ? ' checked="checked"' : ''; var checkedAttribute = isChecked ? ' checked="checked"' : '';
html += '<input class="chkFolder" data-id="' + folder.Id + '" type="checkbox" id="' + id + '"' + checkedAttribute + ' />'; html += '<input class="chkFolder" data-id="' + folder.Id + '" type="checkbox" id="' + id + '"' + checkedAttribute + ' />';
@ -30,12 +25,8 @@
$('.folderAccess', page).html(html).trigger('create'); $('.folderAccess', page).html(html).trigger('create');
if (user.Policy.BlockedMediaFolders != null) {
$('#chkEnableAllFolders', page).checked(user.Policy.BlockedMediaFolders.length == 0).checkboxradio('refresh').trigger('change');
} else {
$('#chkEnableAllFolders', page).checked(user.Policy.EnableAllFolders).checkboxradio('refresh').trigger('change'); $('#chkEnableAllFolders', page).checked(user.Policy.EnableAllFolders).checkboxradio('refresh').trigger('change');
} }
}
function loadChannels(page, user, channels) { function loadChannels(page, user, channels) {
@ -51,12 +42,7 @@
var id = 'channels' + i; var id = 'channels' + i;
var isChecked; var isChecked = user.Policy.EnableAllChannels || user.Policy.EnabledChannels.indexOf(folder.Id) != -1;
if (user.Policy.BlockedChannels != null) {
isChecked = user.Policy.BlockedChannels.indexOf(folder.Id) == -1;
} else {
isChecked = user.Policy.EnableAllChannels || user.Policy.EnabledChannels.indexOf(folder.Id) != -1;
}
var checkedAttribute = isChecked ? ' checked="checked"' : ''; var checkedAttribute = isChecked ? ' checked="checked"' : '';
html += '<input class="chkChannel" data-id="' + folder.Id + '" type="checkbox" id="' + id + '"' + checkedAttribute + ' />'; html += '<input class="chkChannel" data-id="' + folder.Id + '" type="checkbox" id="' + id + '"' + checkedAttribute + ' />';
@ -73,12 +59,8 @@
$('.channelAccessContainer', page).hide(); $('.channelAccessContainer', page).hide();
} }
if (user.Policy.BlockedChannels != null) {
$('#chkEnableAllChannels', page).checked(user.Policy.BlockedChannels.length == 0).checkboxradio('refresh').trigger('change');
} else {
$('#chkEnableAllChannels', page).checked(user.Policy.EnableAllChannels).checkboxradio('refresh').trigger('change'); $('#chkEnableAllChannels', page).checked(user.Policy.EnableAllChannels).checkboxradio('refresh').trigger('change');
} }
}
function loadDevices(page, user, devices) { function loadDevices(page, user, devices) {
@ -140,7 +122,6 @@
return this.getAttribute('data-id'); return this.getAttribute('data-id');
}).get(); }).get();
user.Policy.BlockedMediaFolders = null;
user.Policy.EnableAllChannels = $('#chkEnableAllChannels', page).checked(); user.Policy.EnableAllChannels = $('#chkEnableAllChannels', page).checked();
user.Policy.EnabledChannels = user.Policy.EnableAllChannels ? user.Policy.EnabledChannels = user.Policy.EnableAllChannels ?
@ -150,7 +131,6 @@
return this.getAttribute('data-id'); return this.getAttribute('data-id');
}).get(); }).get();
user.Policy.BlockedChannels = null;
user.Policy.EnableAllDevices = $('#chkEnableAllDevices', page).checked(); user.Policy.EnableAllDevices = $('#chkEnableAllDevices', page).checked();
user.Policy.EnabledDevices = user.Policy.EnableAllDevices ? user.Policy.EnabledDevices = user.Policy.EnableAllDevices ?

View file

@ -165,7 +165,7 @@
itemHtml += '<li class="liSchedule" data-day="' + a.DayOfWeek + '" data-start="' + a.StartHour + '" data-end="' + a.EndHour + '">'; itemHtml += '<li class="liSchedule" data-day="' + a.DayOfWeek + '" data-start="' + a.StartHour + '" data-end="' + a.EndHour + '">';
itemHtml += '<a href="#">'; itemHtml += '<a href="#">';
itemHtml += '<h3>' + a.DayOfWeek + '</h3>'; itemHtml += '<h3>' + Globalize.translate('Option' + a.DayOfWeek) + '</h3>';
itemHtml += '<p>' + getDisplayTime(a.StartHour) + ' - ' + getDisplayTime(a.EndHour) + '</p>'; itemHtml += '<p>' + getDisplayTime(a.StartHour) + ' - ' + getDisplayTime(a.EndHour) + '</p>';
itemHtml += '</a>'; itemHtml += '</a>';

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="songsPage" data-role="page" class="page libraryPage"> <div id="songsPage" data-role="page" class="page libraryPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="musicrecommended.html">${TabSuggested}</a> <a href="musicrecommended.html">${TabSuggestions}</a>
<a href="#" class="ui-btn-active">${TabSongs}</a> <a href="#" class="ui-btn-active">${TabSongs}</a>
<a href="musicalbums.html">${TabAlbums}</a> <a href="musicalbums.html">${TabAlbums}</a>
<a href="musicalbumartists.html">${TabAlbumArtists}</a> <a href="musicalbumartists.html">${TabAlbumArtists}</a>

View file

@ -87,6 +87,7 @@
</div> </div>
</div> </div>
<div style="display:none;">
<br /> <br />
<h1>${HeaderSupporterBenefits}</h1> <h1>${HeaderSupporterBenefits}</h1>
<p class="linkSupporterKeyMessage"></p> <p class="linkSupporterKeyMessage"></p>
@ -102,6 +103,7 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div data-role="popup" class="popupAddUser popup" data-theme="a"> <div data-role="popup" class="popupAddUser popup" data-theme="a">
<div class="ui-bar-a" style="text-align: center; padding: 0 20px; position: relative;"> <div class="ui-bar-a" style="text-align: center; padding: 0 20px; position: relative;">

View file

@ -11,7 +11,7 @@
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
<a href="#" data-role="button" class="ui-btn-active">${TabActivity}</a> <a href="#" data-role="button" class="ui-btn-active">${TabActivity}</a>
<a href="syncservices.html" data-role="button">${TabServices}</a> <a href="appservices.html?context=sync" data-role="button">${TabServices}</a>
<a href="syncsettings.html" data-role="button">${TabSettings}</a> <a href="syncsettings.html" data-role="button">${TabSettings}</a>
</div> </div>
@ -20,7 +20,7 @@
<progress max="100" min="0" style="width:100px;display:none;" class="syncProgress"></progress> <progress max="100" min="0" style="width:100px;display:none;" class="syncProgress"></progress>
</div> </div>
<br /> <br />
<div class="supporterPromotion syncPromotion" style="display:none;"> <div class="staticSupporterPromotion supporterPromotion syncPromotion" style="display:none;">
<a class="btn btnActionAccent" href="supporter.html" style="font-size:14px;"> <a class="btn btnActionAccent" href="supporter.html" style="font-size:14px;">
<div> <div>
${HeaderSyncRequiresSupporterMembership} ${HeaderSyncRequiresSupporterMembership}

View file

@ -11,7 +11,7 @@
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
<a href="syncactivity.html" data-role="button" class="ui-btn-active">${TabActivity}</a> <a href="syncactivity.html" data-role="button" class="ui-btn-active">${TabActivity}</a>
<a href="syncservices.html" data-role="button">${TabServices}</a> <a href="appservices.html?context=sync" data-role="button">${TabServices}</a>
<a href="syncsettings.html" data-role="button">${TabSettings}</a> <a href="syncsettings.html" data-role="button">${TabSettings}</a>
</div> </div>

View file

@ -1,43 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>${TitleSync}</title>
</head>
<body>
<div id="syncServicesPage" data-role="page" class="page type-interior syncConfigurationPage" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Sync">
<div data-role="content">
<div class="content-primary">
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
<a href="syncactivity.html" data-role="button">${TabActivity}</a>
<a href="#" data-role="button" class="ui-btn-active">${TabServices}</a>
<a href="syncsettings.html" data-role="button">${TabSettings}</a>
</div>
<div class="detailSectionHeader">${HeaderInstalledServices}</div>
<div class="installedPlugins"></div>
<br />
<br />
<br />
<div class="detailSectionHeader">${HeaderAvailableServices}</div>
<div class="catalog"></div>
<div class="supporterPromotion syncPromotion" style="display:none;">
<a class="btn btnActionAccent" href="supporter.html" style="font-size:14px;">
<div>
${HeaderSyncRequiresSupporterMembership}
</div>
<div>
${HeaderEnjoyDayTrial}
</div>
<div style="font-weight:normal;font-size:90%;margin-top:5px;">
${ButtonLearnMore}
</div>
</a>
</div>
</div>
</div>
</div>
</body>
</html>

View file

@ -11,7 +11,7 @@
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
<a href="syncactivity.html" data-role="button">${TabActivity}</a> <a href="syncactivity.html" data-role="button">${TabActivity}</a>
<a href="syncservices.html" data-role="button">${TabServices}</a> <a href="appservices.html?context=sync" data-role="button">${TabServices}</a>
<a href="#" data-role="button" class="ui-btn-active">${TabSettings}</a> <a href="#" data-role="button" class="ui-btn-active">${TabSettings}</a>
</div> </div>

View file

@ -306,7 +306,13 @@
throw new Error("Url name cannot be empty"); throw new Error("Url name cannot be empty");
} }
var url = serverAddress + "/" + name; var url = serverAddress;
if (name.charAt(0) != '/') {
url += '/';
}
url += name;
if (params) { if (params) {
url += "?" + AjaxApi.param(params); url += "?" + AjaxApi.param(params);
@ -1881,14 +1887,14 @@
}); });
}; };
self.stopActiveEncodings = function (streamId) { self.stopActiveEncodings = function (playSessionId) {
var options = { var options = {
deviceId: deviceId deviceId: deviceId
}; };
if (streamId) { if (playSessionId) {
options.streamId = streamId; options.PlaySessionId = playSessionId;
} }
var url = self.getUrl("Videos/ActiveEncodings", options); var url = self.getUrl("Videos/ActiveEncodings", options);

View file

@ -455,7 +455,10 @@
self.isLoggedIntoConnect = function () { self.isLoggedIntoConnect = function () {
// Make sure it returns true or false // Make sure it returns true or false
return (self.connectToken() && self.connectUserId()) == true; if (!self.connectToken() || !self.connectUserId()) {
return false;
}
return true;
}; };
self.logout = function () { self.logout = function () {

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="tvGenresPage" data-role="page" class="page libraryPage"> <div id="tvGenresPage" data-role="page" class="page libraryPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="tvrecommended.html">${TabSuggested}</a> <a href="tvrecommended.html">${TabSuggestions}</a>
<a href="tvlatest.html">${TabLatest}</a> <a href="tvlatest.html">${TabLatest}</a>
<a href="tvupcoming.html">${TabUpcoming}</a> <a href="tvupcoming.html">${TabUpcoming}</a>
<a href="tvshows.html">${TabShows}</a> <a href="tvshows.html">${TabShows}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="tvNextUpPage" data-role="page" class="page libraryPage backdropPage" data-backdroptype="series"> <div id="tvNextUpPage" data-role="page" class="page libraryPage backdropPage" data-backdroptype="series">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="tvrecommended.html">${TabSuggested}</a> <a href="tvrecommended.html">${TabSuggestions}</a>
<a href="#" class="ui-btn-active">${TabLatest}</a> <a href="#" class="ui-btn-active">${TabLatest}</a>
<a href="tvupcoming.html">${TabUpcoming}</a> <a href="tvupcoming.html">${TabUpcoming}</a>
<a href="tvshows.html">${TabShows}</a> <a href="tvshows.html">${TabShows}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="tvPeoplePage" data-role="page" class="page libraryPage"> <div id="tvPeoplePage" data-role="page" class="page libraryPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="tvrecommended.html">${TabSuggested}</a> <a href="tvrecommended.html">${TabSuggestions}</a>
<a href="tvlatest.html">${TabLatest}</a> <a href="tvlatest.html">${TabLatest}</a>
<a href="tvupcoming.html">${TabUpcoming}</a> <a href="tvupcoming.html">${TabUpcoming}</a>
<a href="tvshows.html">${TabShows}</a> <a href="tvshows.html">${TabShows}</a>

View file

@ -14,7 +14,7 @@
<a href="tvupcoming.html">${TabUpcoming}</a> <a href="tvupcoming.html">${TabUpcoming}</a>
</div> </div>
<div class="libraryViewNav scopedLibraryViewNav" style="display: none;"> <div class="libraryViewNav scopedLibraryViewNav" style="display: none;">
<a href="tvrecommended.html" class="ui-btn-active">${TabSuggested}</a> <a href="tvrecommended.html" class="ui-btn-active">${TabSuggestions}</a>
<a href="tvlatest.html">${TabLatest}</a> <a href="tvlatest.html">${TabLatest}</a>
<a href="tvupcoming.html">${TabUpcoming}</a> <a href="tvupcoming.html">${TabUpcoming}</a>
<a href="tvshows.html">${TabShows}</a> <a href="tvshows.html">${TabShows}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="tvShowsPage" data-role="page" class="page libraryPage"> <div id="tvShowsPage" data-role="page" class="page libraryPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="tvrecommended.html">${TabSuggested}</a> <a href="tvrecommended.html">${TabSuggestions}</a>
<a href="tvlatest.html">${TabLatest}</a> <a href="tvlatest.html">${TabLatest}</a>
<a href="tvupcoming.html">${TabUpcoming}</a> <a href="tvupcoming.html">${TabUpcoming}</a>
<a href="#" class="ui-btn-active">${TabShows}</a> <a href="#" class="ui-btn-active">${TabShows}</a>

View file

@ -6,7 +6,7 @@
<body> <body>
<div id="tvStudiosPage" data-role="page" class="page libraryPage"> <div id="tvStudiosPage" data-role="page" class="page libraryPage">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">
<a href="tvrecommended.html">${TabSuggested}</a> <a href="tvrecommended.html">${TabSuggestions}</a>
<a href="tvlatest.html">${TabLatest}</a> <a href="tvlatest.html">${TabLatest}</a>
<a href="tvupcoming.html">${TabUpcoming}</a> <a href="tvupcoming.html">${TabUpcoming}</a>
<a href="tvshows.html">${TabShows}</a> <a href="tvshows.html">${TabShows}</a>
@ -20,7 +20,7 @@
<div class="listTopPaging"> <div class="listTopPaging">
</div> </div>
</div> </div>
<div id="items" class="itemsContainer paddedItemsContainer"></div> <div id="items" class="itemsContainer paddedItemsContainer" style="text-align:center;"></div>
</div> </div>
<div data-role="panel" class="viewPanel" data-theme="a" data-position="right" data-display="overlay" data-position-fixed="true"> <div data-role="panel" class="viewPanel" data-theme="a" data-position="right" data-display="overlay" data-position-fixed="true">

View file

@ -13,7 +13,7 @@
<a href="#" class="ui-btn-active">${TabUpcoming}</a> <a href="#" class="ui-btn-active">${TabUpcoming}</a>
</div> </div>
<div class="libraryViewNav scopedLibraryViewNav" style="display: none;"> <div class="libraryViewNav scopedLibraryViewNav" style="display: none;">
<a href="tvrecommended.html">${TabSuggested}</a> <a href="tvrecommended.html">${TabSuggestions}</a>
<a href="tvlatest.html">${TabLatest}</a> <a href="tvlatest.html">${TabLatest}</a>
<a href="tvupcoming.html" class="ui-btn-active">${TabUpcoming}</a> <a href="tvupcoming.html" class="ui-btn-active">${TabUpcoming}</a>
<a href="tvshows.html">${TabShows}</a> <a href="tvshows.html">${TabShows}</a>

View file

@ -55,7 +55,7 @@
<form class="addUserForm"> <form class="addUserForm">
<div> <div>
<label for="txtConnectUsername">${LabelConnectGuestUserName}</label> <label for="txtConnectUsername">${LabelConnectGuestUserName}</label>
<input type="text" id="txtConnectUsername" value="" placeholder="Username" required="required"> <input type="text" id="txtConnectUsername" value="" placeholder="${PlaceholderUsername}" required="required">
<div class="fieldDescription"> <div class="fieldDescription">
<div>${LabelConnectGuestUserNameHelp}</div> <div>${LabelConnectGuestUserNameHelp}</div>
<div style="margin-top: .75em;"><a href="http://emby.media/connect" target="_blank">${ButtonLearnMoreAboutEmbyConnect}</a></div> <div style="margin-top: .75em;"><a href="http://emby.media/connect" target="_blank">${ButtonLearnMoreAboutEmbyConnect}</a></div>