Pushing missing changes
80
Html/addPlugin.html
Normal file
@ -0,0 +1,80 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="addPluginPage" data-role="page" class="page type-interior pluginConfigurationPage">
|
||||
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<p>
|
||||
<a data-role="button" data-icon="arrow-left" data-inline="true" data-mini="true" data-theme="b" href="pluginCatalog.html">Plugin Catalog</a>
|
||||
</p>
|
||||
<form id="addPluginForm">
|
||||
<p id="tagline" style="font-style: italic;"></p>
|
||||
<p id="pPreviewImage" style="text-align: center; margin: 2em 0;"></p>
|
||||
|
||||
<p id="overview"></p>
|
||||
|
||||
<div data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em;" data-theme="a">
|
||||
<h3>Install</h3>
|
||||
<p id="pCurrentVersion">
|
||||
</p>
|
||||
<p>
|
||||
<label for="selectVersion">Select version to install:</label>
|
||||
<select id="selectVersion" name="selectVersion"></select>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<button id="btnInstall" type="submit" data-icon="download" data-theme="b">Install</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form name="_xclick" target="_blank" action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||
<div class="premiumPackage" data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em; display: none" data-theme="a">
|
||||
<h3>Registration</h3>
|
||||
<p id="regStatus">
|
||||
</p>
|
||||
<p id="regInfo">
|
||||
</p>
|
||||
<p id="regPrice">
|
||||
</p>
|
||||
<input type="hidden" name="cmd" value="_xclick">
|
||||
<input type="hidden" id="payPalEmail" name="business" value="mb_1358534950_biz@reedsplace.com">
|
||||
<input type="hidden" name="currency_code" value="USD">
|
||||
<input type="hidden" id="featureName" name="item_name" value="MBSupporter">
|
||||
<input type="hidden" id="amount" name="amount" value="10">
|
||||
<input type="hidden" id="featureId" name="item_number" value="MBSupporter">
|
||||
<input type="hidden" name="notify_url" value="http://mb3admin.com/admin/service/services/ppipn.php">
|
||||
<input type="hidden" name="return" id ="paypalReturnUrl" value="#">
|
||||
<a data-role="button" id="ppButton" onclick="_xclick.submit();"><img src="css/images/registerpp.png"/></a>
|
||||
<p id="noEmail" style="display: none"><strong>This developer has not provided a PayPal email. Please see their
|
||||
website for registration information.</strong>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em;" data-theme="a">
|
||||
<h3>Developer Info</h3>
|
||||
<p id="developer"></p>
|
||||
<p id="pViewWebsite" style="display: none;">
|
||||
<a href="#" data-rel="external" target="_blank">View Website</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div data-role="collapsible" data-content-theme="c" style="margin-top: 2em;" data-theme="a">
|
||||
<h3>Revision History</h3>
|
||||
<div id="revisionHistory"></div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$('#addPluginForm').on('submit', AddPluginPage.onSubmit);
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
56
Html/advanced.html
Normal file
@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Advanced</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="advancedConfigurationPage" data-role="page" class="page type-interior">
|
||||
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<form id="advancedConfigurationForm">
|
||||
|
||||
<ul data-role="listview" class="ulForm">
|
||||
<li>
|
||||
<input type="checkbox" id="chkRunAtStartup" name="chkRunAtStartup" />
|
||||
<label for="chkRunAtStartup">Run server at startup</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="txtPortNumber">Http server port number: </label>
|
||||
<input type="number" id="txtPortNumber" name="txtPortNumber" pattern="[0-9]*" required="required" min="1" />
|
||||
</li>
|
||||
<li id="fldWebSocketPortNumber" style="display:none;">
|
||||
<label for="txtWebSocketPortNumber">Web socket port number: </label>
|
||||
<input type="number" id="txtWebSocketPortNumber" name="txtWebSocketPortNumber" pattern="[0-9]*" required="required" min="1" />
|
||||
</li>
|
||||
<li>
|
||||
<input type="checkbox" id="chkEnableDeveloperTools" name="chkEnableDeveloperTools" />
|
||||
<label for="chkEnableDeveloperTools">Enable developer tools</label>
|
||||
<div class="fieldDescription">
|
||||
When enabled, developer tools will be available from the system tray.
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<input type="checkbox" id="chkDebugLog" name="chkDebugLog" />
|
||||
<label for="chkDebugLog">Enable debug logging </label>
|
||||
</li>
|
||||
<li>
|
||||
<button type="submit" data-theme="b" data-icon="ok">
|
||||
Save
|
||||
</button>
|
||||
<button type="button" onclick="Dashboard.navigate('dashboard.html');" data-icon="delete">
|
||||
Cancel
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$('#advancedConfigurationForm').on('submit', AdvancedConfigurationPage.onSubmit);
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
43
Html/advancedMetadata.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Metadata</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="advancedMetadataConfigurationPage" data-role="page" class="page type-interior">
|
||||
|
||||
<div data-role="content">
|
||||
|
||||
<div class="content-primary">
|
||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
||||
<a href="metadata.html" data-role="button">Basics</a>
|
||||
<a href="metadataImages.html" data-role="button">Images</a>
|
||||
<a href="advancedMetadata.html" data-role="button" class="ui-btn-active">Advanced</a>
|
||||
</div>
|
||||
|
||||
<form id="advancedMetadataConfigurationForm">
|
||||
<ul data-role="listview" class="ulForm">
|
||||
<li>
|
||||
<label>Disable internet providers for:</label>
|
||||
<div id="divItemTypes"></div>
|
||||
</li>
|
||||
<li>
|
||||
<button type="submit" data-theme="b">
|
||||
Save
|
||||
</button>
|
||||
<button type="button" onclick="Dashboard.navigate('dashboard.html');">
|
||||
Cancel
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$('#advancedMetadataConfigurationForm').on('submit', AdvancedMetadataConfigurationPage.onSubmit);
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
BIN
Html/css/images/bg.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
Html/css/images/checkMarkGreen.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
Html/css/images/checkmarkblack.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
Html/css/images/clients/android.png
Normal file
After Width: | Height: | Size: 7.6 KiB |
BIN
Html/css/images/clients/html5.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
Html/css/images/clients/ios.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
Html/css/images/clients/mb.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
Html/css/images/clients/win8.png
Normal file
After Width: | Height: | Size: 390 KiB |
BIN
Html/css/images/clients/windowsphone.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
Html/css/images/clients/windowsrt.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
Html/css/images/cloudNetwork.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
Html/css/images/currentUserDefaultBlack.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
Html/css/images/currentUserDefaultWhite.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
Html/css/images/defaultCollectionImage.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
Html/css/images/donatepp.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
Html/css/images/home.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Html/css/images/iossplash.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
Html/css/images/itemDetails/audioDefault.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
Html/css/images/itemDetails/gameDefault.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Html/css/images/itemDetails/videoDefault.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
Html/css/images/leftArrowBlack.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
Html/css/images/leftArrowWhite.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
Html/css/images/logindefault.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
Html/css/images/mblogoblackfull.png
Normal file
After Width: | Height: | Size: 58 KiB |
BIN
Html/css/images/mblogowhitefull.png
Normal file
After Width: | Height: | Size: 58 KiB |
BIN
Html/css/images/media/nextTrack.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
Html/css/images/media/pause.png
Normal file
After Width: | Height: | Size: 459 B |
BIN
Html/css/images/media/play.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Html/css/images/media/playCircle.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
Html/css/images/media/previousTrack.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
Html/css/images/media/stop.png
Normal file
After Width: | Height: | Size: 419 B |
BIN
Html/css/images/movieFolder.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
Html/css/images/notifications/cancelled.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
Html/css/images/notifications/done.png
Normal file
After Width: | Height: | Size: 916 B |
BIN
Html/css/images/notifications/download.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
Html/css/images/notifications/error.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
Html/css/images/notifications/info.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
Html/css/images/premiumflag.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
Html/css/images/registerpp.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
Html/css/images/rightArrow.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
Html/css/images/stars.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
Html/css/images/suppbadge.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
BIN
Html/css/images/toolsBlack.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
Html/css/images/toolsWhite.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
Html/css/images/touchicon.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
Html/css/images/touchicon114.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
Html/css/images/touchicon72.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
Html/css/images/userFlyoutDefault.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
897
Html/css/site.css
Normal file
52
Html/dashboard.html
Normal file
@ -0,0 +1,52 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Dashboard</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="dashboardPage" data-role="page" class="page type-interior">
|
||||
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<div class="readOnlyContent">
|
||||
<div data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em;">
|
||||
<h3>Server Information</h3>
|
||||
<div>
|
||||
<p>
|
||||
Version <span id="appVersionNumber"></span>
|
||||
</p>
|
||||
<p id="pUpToDate" style="display: none;">
|
||||
<img src="css/images/checkMarkGreen.png" style="height: 20px; margin-right: 3px; position: relative; top: 4px;" />
|
||||
Media Browser Server is up to date
|
||||
</p>
|
||||
<div id="pUpdateNow" style="display: none;">
|
||||
<p><strong>A new version of Media Browser Server is available!</strong></p>
|
||||
<p id="newVersionNumber"></p>
|
||||
<button id="btnUpdateApplication" type="button" data-icon="download" data-theme="b" onclick="DashboardPage.updateApplication();">Update Now</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em; display: none;" id="collapsiblePluginUpdates">
|
||||
<h3>Plugin Information</h3>
|
||||
<div id="pPluginUpdates"></div>
|
||||
</div>
|
||||
|
||||
<div data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em;">
|
||||
<h3>Active Connections</h3>
|
||||
<div id="divConnections">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em;">
|
||||
<h3>Running Tasks</h3>
|
||||
<div id="divRunningTasks">
|
||||
</div>
|
||||
<p><a href="scheduledTasks.html">Manage Scheduled Tasks</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
63
Html/editUser.html
Normal file
@ -0,0 +1,63 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="editUserPage" data-role="page" class="page type-interior userProfilesConfigurationPage">
|
||||
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" id="userProfileNavigation" style="display: none;" data-mini="true">
|
||||
<a href="#" data-role="button" class="ui-btn-active">Profile</a>
|
||||
<a href="#" data-role="button" onclick="Dashboard.navigate('userImage.html', true);">Image</a>
|
||||
<a href="#" data-role="button" onclick="Dashboard.navigate('updatePassword.html', true);">Password</a>
|
||||
<a href="#" data-role="button" onclick="Dashboard.navigate('library.html', true);">Media Library</a>
|
||||
</div>
|
||||
<form id="editUserProfileForm">
|
||||
<ul data-role="listview" class="ulForm">
|
||||
<li id="fldUserName">
|
||||
<label for="txtUserName">Name: </label>
|
||||
<input id="txtUserName" name="txtUserName" required="required" type="text" />
|
||||
</li>
|
||||
<li id="fldMaxParentalRating" style="display: none;">
|
||||
<label for="selectMaxParentalRating">Max parental rating:</label>
|
||||
<select name="selectMaxParentalRating" id="selectMaxParentalRating"></select>
|
||||
</li>
|
||||
<li id="fldIsAdmin" style="display: none;">
|
||||
<input type="checkbox" id="chkIsAdmin" name="chkIsAdmin" />
|
||||
<label for="chkIsAdmin">Allow this user to manage the server</label>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Video Playback Settings</h2>
|
||||
<ul data-role="listview" class="ulForm">
|
||||
<li>
|
||||
<label for="selectAudioLanguage">Audio language preference: </label>
|
||||
<select name="selectAudioLanguage" id="selectAudioLanguage"></select>
|
||||
</li>
|
||||
<li>
|
||||
<label for="selectSubtitleLanguage">Subtitle language preference: </label>
|
||||
<select name="selectSubtitleLanguage" id="selectSubtitleLanguage"></select>
|
||||
</li>
|
||||
<li>
|
||||
<input type="checkbox" id="chkForcedSubtitlesOnly" name="chkForcedSubtitlesOnly" />
|
||||
<label for="chkForcedSubtitlesOnly">Display only forced subtitles</label>
|
||||
</li>
|
||||
<li>
|
||||
<button type="submit" data-theme="b" data-icon="ok">
|
||||
Save
|
||||
</button>
|
||||
<button type="button" onclick="history.back();" data-icon="delete">
|
||||
Cancel
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$('#editUserProfileForm').on('submit', EditUserPage.onSubmit);
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
BIN
Html/favicon.ico
Normal file
After Width: | Height: | Size: 143 KiB |
33
Html/index.html
Normal file
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Media Browser</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="indexPage" data-role="page" class="page type-home libraryPage" data-theme="a">
|
||||
<div data-role="content">
|
||||
<h1>What's New <a href="#" class="imageLink">
|
||||
<img src="css/images/rightArrow.png" /></a></h1>
|
||||
|
||||
<div id="divWhatsNew"></div>
|
||||
|
||||
<div id="divResumable" style="display: none;">
|
||||
<h1>Resume <a href="#" class="imageLink">
|
||||
<img src="css/images/rightArrow.png" /></a></h1>
|
||||
|
||||
<div id="divResumableItems"></div>
|
||||
</div>
|
||||
|
||||
<h1>My Library <a href="#" class="imageLink">
|
||||
<img src="css/images/rightArrow.png" /></a></h1>
|
||||
|
||||
<div id="divMyLibrary"></div>
|
||||
|
||||
<h1>Collections <a href="#" class="imageLink">
|
||||
<img src="css/images/rightArrow.png" /></a></h1>
|
||||
|
||||
<div id="divCollections"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
66
Html/itemDetails.html
Normal file
@ -0,0 +1,66 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="itemDetailPage" data-role="page" class="page libraryPage" data-theme="a">
|
||||
<div data-role="content" style="padding-top: 0;">
|
||||
|
||||
<h1 id="itemName" style="padding-left: 10px; margin: 0;"></h1>
|
||||
|
||||
<div style="padding: 10px;">
|
||||
<div class="itemImageBlock">
|
||||
<div id="itemMedia" style="position: relative;">
|
||||
<div id="itemImage"></div>
|
||||
<div id="playButtonShadow" style="display: none; height: 48px; position: absolute; bottom: 0; left: 0; right: 0; background: black; opacity: .75;">
|
||||
</div>
|
||||
<button id="btnPlay" type="button" class="imageButton" style="display: none; position: absolute; bottom: 5px; left: 10px;" data-role="none" title="Play" onclick="ItemDetailPage.play();">
|
||||
<img src="css/images/media/playCircle.png" style="height: 28px;" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="itemDetailBlock">
|
||||
|
||||
<p id="itemTagline" style="font-style: italic;"></p>
|
||||
<p id="itemOverview"></p>
|
||||
<p id="itemCommunityRating"></p>
|
||||
<p id="itemMiscInfo" style="color: #ddd; font-size: 14px;"></p>
|
||||
|
||||
<p id="itemGenres">
|
||||
</p>
|
||||
|
||||
<p id="itemStudios">
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-role="collapsible" data-content-theme="a" id="mediaInfoCollapsible">
|
||||
<h3>Media Info</h3>
|
||||
<div id="mediaInfoContent"></div>
|
||||
</div>
|
||||
<div data-role="collapsible" data-content-theme="a" id="scenesCollapsible">
|
||||
<h3>Scenes</h3>
|
||||
<div id="scenesContent"></div>
|
||||
</div>
|
||||
<div data-role="collapsible" data-content-theme="a">
|
||||
<h3>Special Features</h3>
|
||||
<p>I'm the collapsible content. By default I'm closed, but you can click the header to open me.</p>
|
||||
</div>
|
||||
<div data-role="collapsible" data-content-theme="a">
|
||||
<h3>Trailers</h3>
|
||||
<p>I'm the collapsible content. By default I'm closed, but you can click the header to open me.</p>
|
||||
</div>
|
||||
<div data-role="collapsible" data-content-theme="a">
|
||||
<h3>Cast & Crew</h3>
|
||||
<p>I'm the collapsible content. By default I'm closed, but you can click the header to open me.</p>
|
||||
</div>
|
||||
<div data-role="collapsible" data-content-theme="a">
|
||||
<h3>Gallery</h3>
|
||||
<div id="galleryContent"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
57
Html/library.html
Normal file
@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title> </title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mediaLibraryPage" data-role="page" class="page type-interior mediaLibraryPage">
|
||||
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" id="userProfileNavigation" style="display: none;" data-mini="true">
|
||||
<a href="#" data-role="button" onclick="Dashboard.navigate('editUser.html', true);">Profile</a>
|
||||
<a href="#" data-role="button" onclick="Dashboard.navigate('userImage.html', true);">Image</a>
|
||||
<a href="#" data-role="button" onclick="Dashboard.navigate('updatePassword.html', true);">Password</a>
|
||||
<a href="#" data-role="button" class="ui-btn-active">Media Library</a>
|
||||
</div>
|
||||
<div class="readOnlyContent">
|
||||
<p id="fldUseDefaultLibrary" style="display: none;">
|
||||
<input type="checkbox" id="chkUseDefaultLibrary" name="chkUseDefaultLibrary" onchange="MediaLibraryPage.setUseDefaultMediaLibrary(this.checked);" />
|
||||
<label for="chkUseDefaultLibrary">Use default media library</label>
|
||||
</p>
|
||||
<div id="divMediaLibrary">
|
||||
<p>Below are your media collections. Expand a collection to add or remove media locations assigned to it.</p>
|
||||
<p>
|
||||
<button type="button" data-icon="plus" onclick="MediaLibraryPage.addVirtualFolder();">Add media collection</button>
|
||||
</p>
|
||||
<div id="divVirtualFolders"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-role="popup" id="popupEnterText" class="ui-corner-all popup">
|
||||
|
||||
<div class="ui-corner-top ui-bar-a" style="text-align: center; padding: 0 20px;">
|
||||
<h3>Rename</h3>
|
||||
</div>
|
||||
|
||||
<div data-role="content" class="ui-corner-bottom ui-content">
|
||||
<form id="textEntryForm">
|
||||
<label for="txtValue">New name:</label>
|
||||
<input type="text" name="txtValue" id="txtValue" required="required" />
|
||||
|
||||
<p>
|
||||
<button type="submit" data-theme="b" data-icon="ok">
|
||||
Ok
|
||||
</button>
|
||||
<button type="button" data-icon="delete" onclick="$(this).parents('.popup').popup('close');">
|
||||
Cancel
|
||||
</button>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
30
Html/log.html
Normal file
@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Log File</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="logPage" data-role="page" class="page type-interior">
|
||||
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
||||
<a href="support.html" data-role="button">General</a>
|
||||
<a href="log.html" data-role="button" class="ui-btn-active">View Log</a>
|
||||
<a href="supporter.html" data-role="button">Become a Supporter</a>
|
||||
<a href="supporterKey.html" data-role="button">Supporter Key</a>
|
||||
</div>
|
||||
<p>
|
||||
<label for="chkAutoScroll">Auto-scroll</label>
|
||||
<input type="checkbox" id="chkAutoScroll" onchange="LogPage.updateAutoScroll(this.checked);" name="chkAutoScroll" data-inline="true" />
|
||||
</p>
|
||||
<textarea id="logContents" class="pre" style="overflow-y:hidden;"></textarea>
|
||||
<p>
|
||||
<label for="chkAutoScrollBottom">Auto-scroll</label>
|
||||
<input type="checkbox" id="chkAutoScrollBottom" name="chkAutoScrollBottom" onchange="LogPage.updateAutoScroll(this.checked);" data-inline="true" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
39
Html/login.html
Normal file
@ -0,0 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Sign In</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="loginPage" data-role="page" class="page standalonePage">
|
||||
|
||||
<div data-role="content">
|
||||
<div id="divUsers" style="margin: 50px 20px 20px; text-align: center;"></div>
|
||||
</div>
|
||||
|
||||
<div data-role="popup" id="popupLogin" class="ui-corner-all popup">
|
||||
<form id="loginForm">
|
||||
<div class="ui-corner-top ui-bar-a" style="text-align: center;">
|
||||
<h3>Please sign in</h3>
|
||||
</div>
|
||||
<div data-role="content" class="ui-corner-bottom ui-content">
|
||||
<label for="pw" class="ui-hidden-accessible">Password:</label>
|
||||
<input type="password" name="pw" id="pw" value="" placeholder="password" />
|
||||
|
||||
<p>
|
||||
<button type="submit" data-theme="b" data-icon="ok">
|
||||
Sign in
|
||||
</button>
|
||||
<button type="button" data-icon="delete" onclick="$(this).parents('.popup').popup('close');">
|
||||
Cancel
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$('#loginForm').on('submit', LoginPage.onSubmit);
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
59
Html/metadata.html
Normal file
@ -0,0 +1,59 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Metadata</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="metadataConfigurationPage" data-role="page" class="page type-interior">
|
||||
|
||||
<div data-role="content">
|
||||
|
||||
<div class="content-primary">
|
||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
||||
<a href="metadata.html" data-role="button" class="ui-btn-active">Basics</a>
|
||||
<a href="metadataImages.html" data-role="button">Images</a>
|
||||
<a href="advancedMetadata.html" data-role="button">Advanced</a>
|
||||
</div>
|
||||
|
||||
<form id="metadataConfigurationForm">
|
||||
<ul data-role="listview" class="ulForm">
|
||||
<li>
|
||||
<input type="checkbox" id="chkEnableInternetProviders" name="chkEnableInternetProviders" />
|
||||
<label for="chkEnableInternetProviders">Download metadata from the internet </label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="checkbox" id="chkSaveLocal" name="chkSaveLocal" />
|
||||
<label for="chkSaveLocal">Save metadata within media folders </label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="txtRefreshDays">Metadata refresh period (days): </label>
|
||||
<input type="number" id="txtRefreshDays" name="txtRefreshDays" pattern="[0-9]*" required="required" min="1" />
|
||||
</li>
|
||||
<li>
|
||||
<label for="selectLanguage">Preferred language: </label>
|
||||
<select name="selectLanguage" id="selectLanguage"></select>
|
||||
</li>
|
||||
<li>
|
||||
<label for="selectCountry">Country: </label>
|
||||
<select name="selectCountry" id="selectCountry"></select>
|
||||
</li>
|
||||
<li>
|
||||
<button type="submit" data-theme="b">
|
||||
Save
|
||||
</button>
|
||||
<button type="button" onclick="Dashboard.navigate('dashboard.html');">
|
||||
Cancel
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$('#metadataConfigurationForm').on('submit', MetadataConfigurationPage.onSubmit);
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
120
Html/metadataImages.html
Normal file
@ -0,0 +1,120 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Metadata</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="metadataImagesConfigurationPage" data-role="page" class="page type-interior">
|
||||
|
||||
<div data-role="content">
|
||||
|
||||
<div class="content-primary">
|
||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
||||
<a href="metadata.html" data-role="button">Basics</a>
|
||||
<a href="metadataImages.html" data-role="button" class="ui-btn-active">Images</a>
|
||||
<a href="advancedMetadata.html" data-role="button">Advanced</a>
|
||||
</div>
|
||||
|
||||
<form id="metadataImagesConfigurationForm">
|
||||
<ul data-role="listview" class="ulForm">
|
||||
<li>
|
||||
<input type="checkbox" id="chkRefreshItemImages" name="chkRefreshItemImages" />
|
||||
<label for="chkRefreshItemImages">Refresh existing images </label>
|
||||
<div class="fieldDescription">
|
||||
When enabled, images will be refreshed periodically
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<label for="txtNumbackdrops">Max number of backdrops per item: </label>
|
||||
<input type="number" id="txtNumbackdrops" name="txtNumbackdrops" pattern="[0-9]*" required="required" min="1" />
|
||||
</li>
|
||||
<li>
|
||||
<label>Enable additional image downloading:</label>
|
||||
<div data-role="controlgroup">
|
||||
|
||||
<input type="checkbox" data-mini="true" id="chkDownloadMovieArt" name="chkDownloadMovieArt" />
|
||||
<label for="chkDownloadMovieArt">Movie Art</label>
|
||||
|
||||
<input type="checkbox" data-mini="true" id="chkDownloadMovieBanner" name="chkDownloadMovieBanner" />
|
||||
<label for="chkDownloadMovieBanner">Movie Banner</label>
|
||||
|
||||
<input type="checkbox" data-mini="true" id="chkDownloadMovieDisc" name="chkDownloadMovieDisc" />
|
||||
<label for="chkDownloadMovieDisc">Movie Disc</label>
|
||||
|
||||
<input type="checkbox" data-mini="true" id="chkDownloadMovieLogo" name="chkDownloadMovieLogo" />
|
||||
<label for="chkDownloadMovieLogo">Movie Logo</label>
|
||||
|
||||
<input type="checkbox" data-mini="true" id="chkDownloadMovieThumb" name="chkDownloadMovieThumb" />
|
||||
<label for="chkDownloadMovieThumb">Movie Thumb</label>
|
||||
|
||||
<input type="checkbox" data-mini="true" id="chKDownloadTVArt" name="chKDownloadTVArt" />
|
||||
<label for="chKDownloadTVArt">TV Series Art</label>
|
||||
|
||||
<input type="checkbox" data-mini="true" id="chkDownloadTVBanner" name="chkDownloadTVBanner" />
|
||||
<label for="chkDownloadTVBanner">TV Series Banner</label>
|
||||
|
||||
<input type="checkbox" data-mini="true" id="chkDownloadTVLogo" name="chkDownloadTVLogo" />
|
||||
<label for="chkDownloadTVLogo">TV Series Logo</label>
|
||||
|
||||
<input type="checkbox" data-mini="true" id="chkDownloadTVThumb" name="chkDownloadTVThumb" />
|
||||
<label for="chkDownloadTVThumb">TV Series Thumb</label>
|
||||
|
||||
<input type="checkbox" data-mini="true" id="chkDownloadSeasonBackdrops" name="chkDownloadSeasonBackdrops" />
|
||||
<label for="chkDownloadSeasonBackdrops">TV Season Backdrops</label>
|
||||
|
||||
<input type="checkbox" data-mini="true" id="chkDownloadSeasonBanner" name="chkDownloadSeasonBanner" />
|
||||
<label for="chkDownloadSeasonBanner">TV Season Banner</label>
|
||||
|
||||
<input type="checkbox" data-mini="true" id="chkDownloadSeasonThumb" name="chkDownloadSeasonThumb" />
|
||||
<label for="chkDownloadSeasonThumb">TV Season Thumb</label>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<label for="selectTmdbPosterDownloadSize">Tmdb poster download size: </label>
|
||||
<select id="selectTmdbPosterDownloadSize" name="selectTmdbPosterDownloadSize">
|
||||
<option value="original">original</option>
|
||||
<option value="w92">w92</option>
|
||||
<option value="w154">w154</option>
|
||||
<option value="w185">w185</option>
|
||||
<option value="w342">w342</option>
|
||||
<option value="w500">w500</option>
|
||||
</select>
|
||||
</li>
|
||||
<li>
|
||||
<label for="selectTmdbBackdropDownloadSize">Tmdb backdrop download size: </label>
|
||||
<select id="selectTmdbBackdropDownloadSize" name="selectTmdbBackdropDownloadSize">
|
||||
<option value="original">original</option>
|
||||
<option value="w380">w380</option>
|
||||
<option value="w780">w780</option>
|
||||
<option value="w1280">w1280</option>
|
||||
</select>
|
||||
</li>
|
||||
<li>
|
||||
<label for="selectTmdbPersonImageDownloadSize">Tmdb person image download size: </label>
|
||||
<select id="selectTmdbPersonImageDownloadSize" name="selectTmdbPersonImageDownloadSize">
|
||||
<option value="original">original</option>
|
||||
<option value="w45">w45</option>
|
||||
<option value="w185">w185</option>
|
||||
<option value="h632">h632</option>
|
||||
</select>
|
||||
</li>
|
||||
<li>
|
||||
<button type="submit" data-theme="b">
|
||||
Save
|
||||
</button>
|
||||
<button type="button" onclick="Dashboard.navigate('dashboard.html');">
|
||||
Cancel
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$('#metadataImagesConfigurationForm').on('submit', MetadataImagesPage.onSubmit);
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
22
Html/pluginCatalog.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Plugins</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="pluginCatalogPage" data-role="page" class="page type-interior pluginConfigurationPage">
|
||||
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
||||
<a href="plugins.html" data-role="button">Installed Plugins</a>
|
||||
<a href="pluginCatalog.html" data-role="button" class="ui-btn-active">Plugin Catalog</a>
|
||||
<a href="pluginUpdates.html" data-role="button">Automatic Updates</a>
|
||||
</div>
|
||||
|
||||
<div id="pluginTiles"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
34
Html/pluginUpdates.html
Normal file
@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Plugins</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="pluginUpdatesPage" data-role="page" class="page type-interior pluginConfigurationPage">
|
||||
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
||||
<a href="plugins.html" data-role="button">Installed Plugins</a>
|
||||
<a href="pluginCatalog.html" data-role="button">Plugin Catalog</a>
|
||||
<a href="pluginUpdates.html" data-role="button" class="ui-btn-active">Automatic Updates</a>
|
||||
</div>
|
||||
|
||||
<form id="pluginUpdatesForm">
|
||||
|
||||
<table id="tblPluginUpdates">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Automatic updates</th>
|
||||
<th>Update level</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbodyPluginUpdates"></tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
24
Html/plugins.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Plugins</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="pluginsPage" data-role="page" class="page type-interior pluginConfigurationPage">
|
||||
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
||||
<a href="plugins.html" data-role="button" class="ui-btn-active">Installed Plugins</a>
|
||||
<a href="pluginCatalog.html" data-role="button">Plugin Catalog</a>
|
||||
<a href="pluginUpdates.html" data-role="button">Automatic Updates</a>
|
||||
</div>
|
||||
|
||||
<div class="readOnlyContent">
|
||||
<ul id="ulInstalledPlugins" data-role="listview" data-inset="true" data-auto-enhanced="false" data-split-icon="minus"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
90
Html/scheduledTask.html
Normal file
@ -0,0 +1,90 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="scheduledTaskPage" data-role="page" class="page type-interior">
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<div class="readOnlyContent">
|
||||
<p id="pTaskDescription"></p>
|
||||
<p>
|
||||
<button type="button" data-icon="plus" onclick="ScheduledTaskPage.showAddTriggerPopup();">
|
||||
Add Task Trigger
|
||||
</button>
|
||||
</p>
|
||||
<ul id="ulTaskTriggers" data-role="listview" data-inset="true" data-auto-enhanced="false" data-split-icon="minus"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-role="popup" id="popupAddTrigger" class="ui-corner-all popup" style="min-width: 300px;">
|
||||
<form id="addTriggerForm">
|
||||
<div class="ui-corner-top ui-bar-a" style="text-align: center; padding: 0 20px;">
|
||||
<h3>Add Task Trigger</h3>
|
||||
</div>
|
||||
<div data-role="content" class="ui-corner-bottom ui-content">
|
||||
|
||||
<ul data-role="listview" class="ulForm">
|
||||
<li>
|
||||
<label for="selectTriggerType">Trigger Type:</label>
|
||||
<select id="selectTriggerType" name="selectTriggerType" onchange="ScheduledTaskPage.refreshTriggerFields(this.value);">
|
||||
<option value="DailyTrigger">Daily</option>
|
||||
<option value="WeeklyTrigger">Weekly</option>
|
||||
<option value="IntervalTrigger">On an interval</option>
|
||||
<option value="StartupTrigger">On application startup</option>
|
||||
<option value="SystemEventTrigger">After a system event</option>
|
||||
</select>
|
||||
</li>
|
||||
<li id="fldDayOfWeek">
|
||||
<label for="selectDayOfWeek">Day:</label>
|
||||
<select id="selectDayOfWeek" name="selectDayOfWeek">
|
||||
<option value="Sunday">Sunday</option>
|
||||
<option value="Monday">Monday</option>
|
||||
<option value="Tuesday">Tuesday</option>
|
||||
<option value="Wednesday">Wednesday</option>
|
||||
<option value="Thursday">Thursday</option>
|
||||
<option value="Friday">Friday</option>
|
||||
<option value="Saturday">Saturday</option>
|
||||
</select>
|
||||
</li>
|
||||
<li id="fldTimeOfDay">
|
||||
<label for="txtTimeOfDay">Time:</label>
|
||||
<input type="time" id="txtTimeOfDay" name="txtTimeOfDay" required="required" />
|
||||
</li>
|
||||
<li id="fldSelectSystemEvent">
|
||||
<label for="selectSystemEvent">Event:</label>
|
||||
<select id="selectSystemEvent" name="selectSystemEvent">
|
||||
<option value="WakeFromSleep">Wake from sleep</option>
|
||||
</select>
|
||||
</li>
|
||||
<li id="fldSelectInterval">
|
||||
<label for="selectInterval">Every:</label>
|
||||
<select id="selectInterval" name="selectInterval">
|
||||
<option value="9000000000">15 minutes</option>
|
||||
<option value="18000000000">30 minutes</option>
|
||||
<option value="27000000000">45 minutes</option>
|
||||
<option value="36000000000">1 hour</option>
|
||||
<option value="72000000000">2 hours</option>
|
||||
<option value="108000000000">3 hours</option>
|
||||
<option value="144000000000">4 hours</option>
|
||||
<option value="216000000000">6 hours</option>
|
||||
<option value="288000000000">8 hours</option>
|
||||
<option value="432000000000">12 hours</option>
|
||||
</select>
|
||||
</li>
|
||||
<li>
|
||||
<button type="submit" data-theme="b" data-icon="ok">
|
||||
Add
|
||||
</button>
|
||||
<button type="button" data-icon="delete" onclick="$(this).parents('.popup').popup('close');">
|
||||
Cancel
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
18
Html/scheduledTasks.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Scheduled Tasks</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="scheduledTasksPage" data-role="page" class="page type-interior">
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<div class="readOnlyContent">
|
||||
<p>Below are Media Browser's scheduled tasks. Click into a task to adjust it's schedule.</p>
|
||||
<ul id="ulScheduledTasks" data-role="listview" data-inset="true" data-auto-enhanced="false" data-split-icon="Play"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
243
Html/scripts/AddPluginPage.js
Normal file
@ -0,0 +1,243 @@
|
||||
var AddPluginPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
|
||||
var page = this;
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var name = getParameterByName('name');
|
||||
|
||||
var promise1 = ApiClient.getPackageInfo(name);
|
||||
var promise2 = ApiClient.getInstalledPlugins();
|
||||
var promise3 = ApiClient.getPluginSecurityInfo();
|
||||
|
||||
$.when(promise1, promise2, promise3).done(function (response1, response2, response3) {
|
||||
|
||||
AddPluginPage.renderPackage(response1[0], response2[0], response3[0], page);
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
renderPackage: function (pkg, installedPlugins, pluginSecurityInfo, page) {
|
||||
|
||||
var installedPlugin = installedPlugins.filter(function (ip) {
|
||||
return ip.Name == pkg.name;
|
||||
})[0];
|
||||
|
||||
AddPluginPage.populateVersions(pkg, page, installedPlugin);
|
||||
AddPluginPage.populateHistory(pkg);
|
||||
|
||||
Dashboard.setPageTitle(pkg.name);
|
||||
|
||||
if (pkg.shortDescription) {
|
||||
$('#tagline', page).show().html(pkg.shortDescription);
|
||||
} else {
|
||||
$('#tagline', page).hide();
|
||||
}
|
||||
|
||||
$('#overview', page).html(pkg.overview || "");
|
||||
|
||||
|
||||
$('#developer', page).html(pkg.owner);
|
||||
|
||||
if (pkg.isPremium) {
|
||||
$('.premiumPackage', page).show();
|
||||
|
||||
// Fill in registration info
|
||||
var regStatus = "<strong>";
|
||||
if (pkg.isRegistered) {
|
||||
regStatus += "You are currently registered for this feature";
|
||||
} else {
|
||||
if (new Date(pkg.expDate).getTime() < new Date(1970, 1, 1).getTime()) {
|
||||
regStatus += "You have never installed this feature";
|
||||
} else {
|
||||
if (pkg.expDate <= new Date().getTime()) {
|
||||
regStatus += "The trial period for this feature has expired on this machine";
|
||||
} else {
|
||||
regStatus += "The trial period for this feature will expire in " + Math.round((new Date(pkg.expDate).getTime() - new Date().getTime()) / (86400000)) + " day(s)";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
regStatus += "</strong>";
|
||||
$('#regStatus', page).html(regStatus);
|
||||
|
||||
if (pluginSecurityInfo.IsMBSupporter) {
|
||||
$('#regInfo', page).html(pkg.regInfo || "");
|
||||
// Fill in PayPal info
|
||||
$('#featureId', page).val(pkg.featureId);
|
||||
$('#featureName', page).val(pkg.name);
|
||||
$('#amount', page).val(pkg.price);
|
||||
$('#regPrice', page).html("<h2>Price: $" + pkg.price.toFixed(2) + " (USD)</h2>");
|
||||
var url = "http://mb3admin.com/admin/service/user/getPayPalEmail?id=" + pkg.owner;
|
||||
$.getJSON(url).done(function (dev) {
|
||||
if (dev.payPalEmail) {
|
||||
$('#payPalEmail', page).val(dev.payPalEmail);
|
||||
|
||||
} else {
|
||||
$('#ppButton', page).hide();
|
||||
$('#noEmail', page).show();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$('#regInfo', page).html("<h3>You must be a <a href='supporter.html'>Media Browser Supporter</a> in order to register this feature.</h3>");
|
||||
$('#ppButton', page).hide();
|
||||
}
|
||||
|
||||
} else {
|
||||
$('.premiumPackage', page).hide();
|
||||
}
|
||||
|
||||
if (pkg.richDescUrl) {
|
||||
$('#pViewWebsite', page).show();
|
||||
$('#pViewWebsite a', page)[0].href = pkg.richDescUrl;
|
||||
} else {
|
||||
$('#pViewWebsite', page).hide();
|
||||
}
|
||||
|
||||
if (pkg.previewImage) {
|
||||
|
||||
var color = pkg.tileColor || "#2572EB";
|
||||
var img = pkg.previewImage ? pkg.previewImage : pkg.thumbImage;
|
||||
$('#pPreviewImage', page).show().html("<img src='" + img + "' style='max-width: 100%;border-radius:10px;-moz-box-shadow: 0 0 20px 3px " + color + ";-webkit-box-shadow: 0 0 20px 3px " + color + ";box-shadow: 0 0 20px 3px " + color + ";' />");
|
||||
} else {
|
||||
$('#pPreviewImage', page).hide().html("");
|
||||
}
|
||||
|
||||
if (installedPlugin) {
|
||||
$('#pCurrentVersion', page).show().html("You currently have version <strong>" + installedPlugin.Version + "</strong> installed.");
|
||||
|
||||
} else {
|
||||
$('#pCurrentVersion', page).hide().html("");
|
||||
}
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
},
|
||||
|
||||
populateVersions: function (packageInfo, page, installedPlugin) {
|
||||
|
||||
var html = '';
|
||||
|
||||
for (var i = 0, length = packageInfo.versions.length; i < length; i++) {
|
||||
|
||||
var version = packageInfo.versions[i];
|
||||
|
||||
html += '<option value="' + version.versionStr + '|' + version.classification + '">' + version.versionStr + ' (' + version.classification + ')</option>';
|
||||
|
||||
}
|
||||
|
||||
var selectmenu = $('#selectVersion', page).html(html);
|
||||
|
||||
var packageVersion;
|
||||
|
||||
if (installedPlugin) {
|
||||
|
||||
// Select the first available package with the same update class as the installed version
|
||||
packageVersion = packageInfo.versions.filter(function (current) {
|
||||
|
||||
return current.classification == installedPlugin.UpdateClass;
|
||||
})[0];
|
||||
|
||||
|
||||
} else {
|
||||
$('#pCurrentVersion', page).hide().html("");
|
||||
}
|
||||
|
||||
// If we don't have a package version to select, pick the first release build
|
||||
if (!packageVersion) {
|
||||
|
||||
// Select the first available package with the same update class as the installed version
|
||||
packageVersion = packageInfo.versions.filter(function (current) {
|
||||
|
||||
return current.classification == "Release";
|
||||
})[0];
|
||||
}
|
||||
|
||||
// If we still don't have a package version to select, pick the first Beta build
|
||||
if (!packageVersion) {
|
||||
|
||||
// Select the first available package with the same update class as the installed version
|
||||
packageVersion = packageInfo.versions.filter(function (current) {
|
||||
|
||||
return current.classification == "Beta";
|
||||
})[0];
|
||||
}
|
||||
|
||||
if (packageVersion) {
|
||||
var val = packageVersion.versionStr + '|' + packageVersion.classification;
|
||||
|
||||
$('#selectVersion', page).val(val);
|
||||
}
|
||||
|
||||
selectmenu.selectmenu('refresh');
|
||||
},
|
||||
|
||||
populateHistory: function (packageInfo) {
|
||||
|
||||
var html = '';
|
||||
|
||||
for (var i = 0, length = Math.min(packageInfo.versions.length, 10) ; i < length; i++) {
|
||||
|
||||
var version = packageInfo.versions[i];
|
||||
|
||||
html += '<h2 style="margin:.5em 0;">' + version.versionStr + ' (' + version.classification + ')</h2>';
|
||||
|
||||
html += '<div style="margin-bottom:1.5em;">' + version.description + '</div>';
|
||||
}
|
||||
|
||||
$('#revisionHistory', $.mobile.activePage).html(html);
|
||||
},
|
||||
|
||||
onSubmit: function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
$('#btnInstall', $.mobile.activePage).button('disable');
|
||||
|
||||
var name = getParameterByName('name');
|
||||
|
||||
ApiClient.getInstalledPlugins().done(function (plugins) {
|
||||
|
||||
var installedPlugin = plugins.filter(function (ip) {
|
||||
return ip.Name == name;
|
||||
})[0];
|
||||
|
||||
var vals = $('#selectVersion', $.mobile.activePage).val().split('|');
|
||||
|
||||
var version = vals[0];
|
||||
|
||||
if (installedPlugin && installedPlugin.Version == version) {
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
|
||||
Dashboard.confirm("Are you sure you wish to reinstall the same version you already have? In most cases this will not have any effect.", "Plugin Reinstallation", function (confirmResult) {
|
||||
|
||||
if (confirmResult) {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
AddPluginPage.performInstallation(name, vals[1], version);
|
||||
} else {
|
||||
$('#btnInstall', $.mobile.activePage).button('enable');
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
AddPluginPage.performInstallation(name, vals[1], version);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
performInstallation: function (packageName, updateClass, version) {
|
||||
|
||||
ApiClient.installPlugin(packageName, updateClass, version).done(function () {
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#addPluginPage", AddPluginPage.onPageShow);
|
63
Html/scripts/AdvancedConfigurationPage.js
Normal file
@ -0,0 +1,63 @@
|
||||
var AdvancedConfigurationPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var promise1 = ApiClient.getServerConfiguration();
|
||||
|
||||
var promise2 = ApiClient.getSystemInfo();
|
||||
|
||||
$.when(promise1, promise2).done(function (response1, response2) {
|
||||
|
||||
AdvancedConfigurationPage.loadPage(response1[0], response2[0]);
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
loadPage: function (config, systemInfo) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
if (systemInfo.SupportsNativeWebSocket) {
|
||||
|
||||
$('#fldWebSocketPortNumber', page).hide();
|
||||
} else {
|
||||
$('#fldWebSocketPortNumber', page).show();
|
||||
}
|
||||
|
||||
$('#txtWebSocketPortNumber', page).val(config.LegacyWebSocketPortNumber);
|
||||
|
||||
$('#txtPortNumber', page).val(config.HttpServerPortNumber);
|
||||
$('#chkDebugLog', page).checked(config.EnableDebugLevelLogging).checkboxradio("refresh");
|
||||
|
||||
$('#chkEnableDeveloperTools', page).checked(config.EnableDeveloperTools).checkboxradio("refresh");
|
||||
$('#chkRunAtStartup', page).checked(config.RunAtStartup).checkboxradio("refresh");
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
},
|
||||
|
||||
onSubmit: function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var form = this;
|
||||
|
||||
ApiClient.getServerConfiguration().done(function (config) {
|
||||
|
||||
config.LegacyWebSocketPortNumber = $('#txtWebSocketPortNumber', form).val();
|
||||
|
||||
config.HttpServerPortNumber = $('#txtPortNumber', form).val();
|
||||
config.EnableDebugLevelLogging = $('#chkDebugLog', form).checked();
|
||||
|
||||
config.EnableDeveloperTools = $('#chkEnableDeveloperTools', form).checked();
|
||||
config.RunAtStartup = $('#chkRunAtStartup', form).checked();
|
||||
|
||||
ApiClient.updateServerConfiguration(config).done(Dashboard.processServerConfigurationUpdateResult);
|
||||
});
|
||||
|
||||
// Disable default form submission
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#advancedConfigurationPage", AdvancedConfigurationPage.onPageShow);
|
65
Html/scripts/AdvancedMetadataConfigurationPage.js
Normal file
@ -0,0 +1,65 @@
|
||||
var AdvancedMetadataConfigurationPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var page = this;
|
||||
|
||||
var promise1 = ApiClient.getServerConfiguration();
|
||||
var promise2 = ApiClient.getItemTypes({ HasInternetProvider: true });
|
||||
|
||||
$.when(promise1, promise2).done(function (response1, response2) {
|
||||
|
||||
AdvancedMetadataConfigurationPage.load(page, response1[0], response2[0]);
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
load: function (page, config, itemTypes) {
|
||||
|
||||
AdvancedMetadataConfigurationPage.loadItemTypes(page, config, itemTypes);
|
||||
Dashboard.hideLoadingMsg();
|
||||
},
|
||||
|
||||
loadItemTypes: function (page, configuration, types) {
|
||||
|
||||
var html = '<div data-role="controlgroup">';
|
||||
|
||||
for (var i = 0, length = types.length; i < length; i++) {
|
||||
|
||||
var type = types[i];
|
||||
var id = "checkbox-" + i + "a";
|
||||
|
||||
var checkedAttribute = configuration.InternetProviderExcludeTypes.indexOf(type) != -1 ? ' checked="checked"' : '';
|
||||
|
||||
html += '<input' + checkedAttribute + ' class="chkItemType" data-itemtype="' + type + '" type="checkbox" name="' + id + '" id="' + id + '" />';
|
||||
html += '<label for="' + id + '">' + type + '</label>';
|
||||
}
|
||||
|
||||
html += "</div>";
|
||||
|
||||
$('#divItemTypes', page).html(html).trigger("create");
|
||||
},
|
||||
|
||||
onSubmit: function () {
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var form = this;
|
||||
|
||||
ApiClient.getServerConfiguration().done(function (config) {
|
||||
|
||||
config.InternetProviderExcludeTypes = $.map($('.chkItemType:checked', form), function (currentCheckbox) {
|
||||
|
||||
return currentCheckbox.getAttribute('data-itemtype');
|
||||
});
|
||||
|
||||
ApiClient.updateServerConfiguration(config).done(Dashboard.processServerConfigurationUpdateResult);
|
||||
});
|
||||
|
||||
// Disable default form submission
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#advancedMetadataConfigurationPage", AdvancedMetadataConfigurationPage.onPageShow);
|
423
Html/scripts/DashboardPage.js
Normal file
@ -0,0 +1,423 @@
|
||||
var DashboardPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
DashboardPage.pollForInfo();
|
||||
DashboardPage.startInterval();
|
||||
$(document).on("websocketmessage", DashboardPage.onWebSocketMessage).on("websocketopen", DashboardPage.onWebSocketConnectionChange).on("websocketerror", DashboardPage.onWebSocketConnectionChange).on("websocketclose", DashboardPage.onWebSocketConnectionChange);
|
||||
|
||||
DashboardPage.lastAppUpdateCheck = null;
|
||||
DashboardPage.lastPluginUpdateCheck = null;
|
||||
},
|
||||
|
||||
onPageHide: function () {
|
||||
|
||||
$(document).off("websocketmessage", DashboardPage.onWebSocketMessage).off("websocketopen", DashboardPage.onWebSocketConnectionChange).off("websocketerror", DashboardPage.onWebSocketConnectionChange).off("websocketclose", DashboardPage.onWebSocketConnectionChange);
|
||||
DashboardPage.stopInterval();
|
||||
},
|
||||
|
||||
startInterval: function () {
|
||||
|
||||
if (Dashboard.isWebSocketOpen()) {
|
||||
Dashboard.sendWebSocketMessage("DashboardInfoStart", "0,1500");
|
||||
}
|
||||
},
|
||||
|
||||
stopInterval: function () {
|
||||
|
||||
if (Dashboard.isWebSocketOpen()) {
|
||||
Dashboard.sendWebSocketMessage("DashboardInfoStop");
|
||||
}
|
||||
},
|
||||
|
||||
onWebSocketMessage: function (e, msg) {
|
||||
|
||||
if (msg.MessageType == "DashboardInfo") {
|
||||
DashboardPage.renderInfo(msg.Data);
|
||||
}
|
||||
},
|
||||
|
||||
onWebSocketConnectionChange: function () {
|
||||
|
||||
DashboardPage.stopInterval();
|
||||
DashboardPage.startInterval();
|
||||
},
|
||||
|
||||
pollForInfo: function () {
|
||||
$.getJSON("dashboardInfo").done(DashboardPage.renderInfo);
|
||||
},
|
||||
|
||||
renderInfo: function (dashboardInfo) {
|
||||
|
||||
DashboardPage.lastDashboardInfo = dashboardInfo;
|
||||
|
||||
DashboardPage.renderRunningTasks(dashboardInfo);
|
||||
DashboardPage.renderSystemInfo(dashboardInfo);
|
||||
DashboardPage.renderActiveConnections(dashboardInfo);
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
},
|
||||
|
||||
renderActiveConnections: function (dashboardInfo) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
var html = '';
|
||||
|
||||
if (!dashboardInfo.ActiveConnections.length) {
|
||||
html += '<p>There are no users currently connected.</p>';
|
||||
$('#divConnections', page).html(html).trigger('create');
|
||||
return;
|
||||
}
|
||||
|
||||
html += '<table class="tblConnections" style="border-collapse:collapse;">';
|
||||
|
||||
for (var i = 0, length = dashboardInfo.ActiveConnections.length; i < length; i++) {
|
||||
|
||||
var connection = dashboardInfo.ActiveConnections[i];
|
||||
|
||||
var user = dashboardInfo.Users.filter(function (u) {
|
||||
return u.Id == connection.UserId;
|
||||
})[0];
|
||||
|
||||
html += '<tr>';
|
||||
|
||||
html += '<td style="text-align:center;">';
|
||||
html += DashboardPage.getClientType(connection);
|
||||
html += '</td>';
|
||||
|
||||
html += '<td>';
|
||||
html += user.Name;
|
||||
html += '</td>';
|
||||
|
||||
html += '<td>';
|
||||
html += connection.DeviceName;
|
||||
html += '</td>';
|
||||
|
||||
html += '<td>';
|
||||
html += DashboardPage.getNowPlayingImage(connection.NowPlayingItem);
|
||||
html += '</td>';
|
||||
|
||||
html += '<td>';
|
||||
html += DashboardPage.getNowPlayingText(connection, connection.NowPlayingItem);
|
||||
html += '</td>';
|
||||
|
||||
html += '</tr>';
|
||||
|
||||
}
|
||||
|
||||
html += '</table>';
|
||||
|
||||
$('#divConnections', page).html(html);
|
||||
},
|
||||
|
||||
getClientType: function (connection) {
|
||||
|
||||
if (connection.ClientType == "Dashboard") {
|
||||
|
||||
return "<img src='css/images/clients/html5.png' alt='Dashboard' title='Dashboard' />";
|
||||
}
|
||||
if (connection.ClientType == "Pc") {
|
||||
|
||||
return "<img src='css/images/clients/mb.png' alt='Media Browser' title='Media Browser' />";
|
||||
}
|
||||
if (connection.ClientType == "Android") {
|
||||
|
||||
return "<img src='css/images/clients/android.png' alt='Android' title='Android' />";
|
||||
}
|
||||
if (connection.ClientType == "Ios") {
|
||||
|
||||
return "<img src='css/images/clients/ios.png' alt='iOS' title='iOS' />";
|
||||
}
|
||||
if (connection.ClientType == "WindowsRT") {
|
||||
|
||||
return "<img src='css/images/clients/windowsrt.png' alt='Windows RT' title='Windows RT' />";
|
||||
}
|
||||
if (connection.ClientType == "WindowsPhone") {
|
||||
|
||||
return "<img src='css/images/clients/windowsphone.png' alt='Windows Phone' title='Windows Phone' />";
|
||||
}
|
||||
|
||||
return connection.ClientType;
|
||||
},
|
||||
|
||||
getNowPlayingImage: function (item) {
|
||||
|
||||
if (item) {
|
||||
|
||||
if (item.BackdropImageTag) {
|
||||
var url = ApiClient.getImageUrl(item.Id, {
|
||||
type: "Backdrop",
|
||||
height: 100,
|
||||
tag: item.BackdropImageTag
|
||||
});
|
||||
|
||||
return "<img class='clientNowPlayingImage' src='" + url + "' alt='" + item.Name + "' title='" + item.Name + "' />";
|
||||
}
|
||||
else if (item.PrimaryImageTag) {
|
||||
|
||||
var url = ApiClient.getImageUrl(item.Id, {
|
||||
type: "Primary",
|
||||
height: 100,
|
||||
tag: item.PrimaryImageTag
|
||||
});
|
||||
|
||||
return "<img class='clientNowPlayingImage' src='" + url + "' alt='" + item.Name + "' title='" + item.Name + "' />";
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
},
|
||||
|
||||
getNowPlayingText: function (connection, item) {
|
||||
|
||||
var html = "";
|
||||
|
||||
if (item) {
|
||||
|
||||
html += "<div>" + item.Name + "</div>";
|
||||
|
||||
html += "<div>";
|
||||
|
||||
if (item.RunTimeTicks) {
|
||||
html += DashboardPage.getDisplayText(connection.NowPlayingPositionTicks || 0) + " / ";
|
||||
|
||||
html += DashboardPage.getDisplayText(item.RunTimeTicks);
|
||||
}
|
||||
|
||||
html += "</div>";
|
||||
}
|
||||
|
||||
return html;
|
||||
},
|
||||
|
||||
getDisplayText: function (ticks) {
|
||||
|
||||
var ticksPerHour = 36000000000;
|
||||
|
||||
var parts = [];
|
||||
|
||||
var hours = ticks / ticksPerHour;
|
||||
hours = parseInt(hours);
|
||||
|
||||
if (hours) {
|
||||
parts.push(hours);
|
||||
}
|
||||
|
||||
ticks -= (hours * ticksPerHour);
|
||||
|
||||
var ticksPerMinute = 600000000;
|
||||
|
||||
var minutes = ticks / ticksPerMinute;
|
||||
minutes = parseInt(minutes);
|
||||
|
||||
ticks -= (minutes * ticksPerMinute);
|
||||
|
||||
if (minutes < 10) {
|
||||
minutes = '0' + minutes;
|
||||
}
|
||||
parts.push(minutes);
|
||||
|
||||
var ticksPerSecond = 10000000;
|
||||
|
||||
var seconds = ticks / ticksPerSecond;
|
||||
seconds = parseInt(seconds);
|
||||
|
||||
if (seconds < 10) {
|
||||
seconds = '0' + seconds;
|
||||
}
|
||||
parts.push(seconds);
|
||||
|
||||
return parts.join(':');
|
||||
},
|
||||
|
||||
renderRunningTasks: function (dashboardInfo) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
var html = '';
|
||||
|
||||
if (!dashboardInfo.RunningTasks.length) {
|
||||
html += '<p>No tasks are currently running.</p>';
|
||||
}
|
||||
|
||||
for (var i = 0, length = dashboardInfo.RunningTasks.length; i < length; i++) {
|
||||
|
||||
|
||||
var task = dashboardInfo.RunningTasks[i];
|
||||
|
||||
html += '<p>';
|
||||
|
||||
html += task.Name;
|
||||
|
||||
if (task.State == "Running") {
|
||||
var progress = task.CurrentProgress || { PercentComplete: 0 };
|
||||
html += '<span style="color:#267F00;margin-right:5px;font-weight:bold;"> - ' + Math.round(progress.PercentComplete) + '%</span>';
|
||||
|
||||
html += '<button type="button" data-icon="stop" data-iconpos="notext" data-inline="true" data-theme="b" data-mini="true" onclick="DashboardPage.stopTask(\'' + task.Id + '\');">Stop</button>';
|
||||
}
|
||||
else if (task.State == "Cancelling") {
|
||||
html += '<span style="color:#cc0000;"> - Stopping</span>';
|
||||
}
|
||||
|
||||
html += '</p>';
|
||||
}
|
||||
|
||||
|
||||
$('#divRunningTasks', page).html(html).trigger('create');
|
||||
},
|
||||
|
||||
renderSystemInfo: function (dashboardInfo) {
|
||||
|
||||
Dashboard.updateSystemInfo(dashboardInfo.SystemInfo);
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
$('#appVersionNumber', page).html(dashboardInfo.SystemInfo.Version);
|
||||
|
||||
if (dashboardInfo.RunningTasks.filter(function (task) {
|
||||
|
||||
return task.Id == dashboardInfo.ApplicationUpdateTaskId;
|
||||
|
||||
}).length) {
|
||||
|
||||
$('#btnUpdateApplication', page).button('disable');
|
||||
} else {
|
||||
$('#btnUpdateApplication', page).button('enable');
|
||||
}
|
||||
|
||||
DashboardPage.renderApplicationUpdateInfo(dashboardInfo);
|
||||
DashboardPage.renderPluginUpdateInfo(dashboardInfo);
|
||||
},
|
||||
|
||||
renderApplicationUpdateInfo: function (dashboardInfo) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
if (dashboardInfo.SystemInfo.IsNetworkDeployed && !dashboardInfo.SystemInfo.HasPendingRestart) {
|
||||
|
||||
// Only check once every 10 mins
|
||||
if (DashboardPage.lastAppUpdateCheck && (new Date().getTime() - DashboardPage.lastAppUpdateCheck) < 600000) {
|
||||
return;
|
||||
}
|
||||
|
||||
DashboardPage.lastAppUpdateCheck = new Date().getTime();
|
||||
|
||||
ApiClient.getAvailableApplicationUpdate().done(function (packageInfo) {
|
||||
|
||||
var version = packageInfo.versions[0];
|
||||
|
||||
if (!version) {
|
||||
$('#pUpToDate', page).show();
|
||||
$('#pUpdateNow', page).hide();
|
||||
} else {
|
||||
$('#pUpToDate', page).hide();
|
||||
|
||||
$('#pUpdateNow', page).show();
|
||||
|
||||
$('#newVersionNumber', page).html("Version " + version.versionStr + " is now available for download.");
|
||||
}
|
||||
|
||||
}).fail(function () {
|
||||
|
||||
Dashboard.showFooterNotification({ html: '<img src="css/images/notifications/error.png" class="notificationIcon" />There was an error connecting to the remote Media Browser repository.', id: "MB3ConnectionError" });
|
||||
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
if (dashboardInfo.SystemInfo.HasPendingRestart) {
|
||||
$('#pUpToDate', page).hide();
|
||||
} else {
|
||||
$('#pUpToDate', page).show();
|
||||
}
|
||||
|
||||
$('#pUpdateNow', page).hide();
|
||||
}
|
||||
},
|
||||
|
||||
renderPluginUpdateInfo: function (dashboardInfo) {
|
||||
|
||||
// Only check once every 10 mins
|
||||
if (DashboardPage.lastPluginUpdateCheck && (new Date().getTime() - DashboardPage.lastPluginUpdateCheck) < 600000) {
|
||||
return;
|
||||
}
|
||||
|
||||
DashboardPage.lastPluginUpdateCheck = new Date().getTime();
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
ApiClient.getAvailablePluginUpdates().done(function (updates) {
|
||||
|
||||
if (updates.length) {
|
||||
|
||||
$('#collapsiblePluginUpdates', page).show();
|
||||
|
||||
} else {
|
||||
$('#collapsiblePluginUpdates', page).hide();
|
||||
|
||||
return;
|
||||
}
|
||||
var html = '';
|
||||
|
||||
for (var i = 0, length = updates.length; i < length; i++) {
|
||||
|
||||
var update = updates[i];
|
||||
|
||||
html += '<p><strong>A new version of ' + update.name + ' is available!</strong></p>';
|
||||
|
||||
html += '<button type="button" data-icon="download" data-theme="b" onclick="DashboardPage.installPluginUpdate(this);" data-name="' + update.name + '" data-version="' + update.versionStr + '" data-classification="' + update.classification + '">Update Now</button>';
|
||||
}
|
||||
|
||||
$('#pPluginUpdates', page).html(html).trigger('create');
|
||||
|
||||
}).fail(function () {
|
||||
|
||||
Dashboard.showFooterNotification({ html: '<img src="css/images/notifications/error.png" class="notificationIcon" />There was an error connecting to the remote Media Browser repository.', id: "MB3ConnectionError" });
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
installPluginUpdate: function (button) {
|
||||
|
||||
$(button).button('disable');
|
||||
|
||||
var name = button.getAttribute('data-name');
|
||||
var version = button.getAttribute('data-version');
|
||||
var classification = button.getAttribute('data-classification');
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.installPlugin(name, classification, version).done(function () {
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
},
|
||||
|
||||
updateApplication: function () {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
$('#btnUpdateApplication', page).button('disable');
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.startScheduledTask(DashboardPage.lastDashboardInfo.ApplicationUpdateTaskId).done(function () {
|
||||
|
||||
DashboardPage.pollForInfo();
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
},
|
||||
|
||||
stopTask: function (id) {
|
||||
|
||||
ApiClient.stopScheduledTask(id).done(function () {
|
||||
|
||||
DashboardPage.pollForInfo();
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#dashboardPage", DashboardPage.onPageShow).on('pagehide', "#dashboardPage", DashboardPage.onPageHide);
|
46
Html/scripts/DisplaySettingsPage.js
Normal file
@ -0,0 +1,46 @@
|
||||
var DisplaySettingsPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var page = this;
|
||||
|
||||
ApiClient.getServerConfiguration().done(function (config) {
|
||||
|
||||
$('#txtWeatherLocation', page).val(config.WeatherLocation);
|
||||
$('#txtMinResumePct', page).val(config.MinResumePct);
|
||||
$('#txtMaxResumePct', page).val(config.MaxResumePct);
|
||||
$('#txtMinResumeDuration', page).val(config.MinResumeDurationSeconds);
|
||||
$('#selectWeatherUnit', page).val(config.WeatherUnit).selectmenu("refresh");
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
submit: function() {
|
||||
|
||||
$('.btnSubmit', $.mobile.activePage)[0].click();
|
||||
|
||||
},
|
||||
|
||||
onSubmit: function () {
|
||||
var form = this;
|
||||
|
||||
ApiClient.getServerConfiguration().done(function (config) {
|
||||
|
||||
config.WeatherLocation = $('#txtWeatherLocation', form).val();
|
||||
config.WeatherUnit = $('#selectWeatherUnit', form).val();
|
||||
config.MinResumePct = $('#txtMinResumePct', form).val();
|
||||
config.MaxResumePct = $('#txtMaxResumePct', form).val();
|
||||
config.MinResumeDurationSeconds = $('#txtMinResumeDuration', form).val();
|
||||
|
||||
ApiClient.updateServerConfiguration(config);
|
||||
});
|
||||
|
||||
// Disable default form submission
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#displaySettingsPage", DisplaySettingsPage.onPageShow);
|
175
Html/scripts/EditUserPage.js
Normal file
@ -0,0 +1,175 @@
|
||||
var EditUserPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
if (userId) {
|
||||
$('#userProfileNavigation', this).show();
|
||||
} else {
|
||||
$('#userProfileNavigation', this).hide();
|
||||
}
|
||||
|
||||
var promise4 = ApiClient.getCultures();
|
||||
|
||||
var promise3 = ApiClient.getParentalRatings();
|
||||
|
||||
var promise1;
|
||||
|
||||
if (!userId) {
|
||||
|
||||
var deferred = $.Deferred();
|
||||
|
||||
deferred.resolveWith(null, [{
|
||||
Configuration: {}
|
||||
}]);
|
||||
|
||||
promise1 = deferred.promise();
|
||||
} else {
|
||||
|
||||
promise1 = ApiClient.getUser(userId);
|
||||
}
|
||||
|
||||
var promise2 = Dashboard.getCurrentUser();
|
||||
|
||||
$.when(promise1, promise2, promise3, promise4).done(function (response1, response2, response3, response4) {
|
||||
|
||||
EditUserPage.loadUser(response1[0] || response1, response2[0], response3[0], response4[0]);
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
loadUser: function (user, loggedInUser, allParentalRatings, allCultures) {
|
||||
|
||||
var page = $($.mobile.activePage);
|
||||
|
||||
EditUserPage.populateLanguages($('#selectAudioLanguage', page), allCultures);
|
||||
EditUserPage.populateLanguages($('#selectSubtitleLanguage', page), allCultures);
|
||||
EditUserPage.populateRatings(allParentalRatings, page);
|
||||
|
||||
if (!loggedInUser.Configuration.IsAdministrator || user.Id == loggedInUser.Id) {
|
||||
|
||||
$('#fldIsAdmin', page).hide();
|
||||
$('#fldMaxParentalRating', page).hide();
|
||||
} else {
|
||||
$('#fldIsAdmin', page).show();
|
||||
$('#fldMaxParentalRating', page).show();
|
||||
}
|
||||
|
||||
Dashboard.setPageTitle(user.Name || "Add User");
|
||||
|
||||
$('#txtUserName', page).val(user.Name);
|
||||
|
||||
var ratingValue = "";
|
||||
|
||||
if (user.Configuration.MaxParentalRating) {
|
||||
|
||||
for (var i = 0, length = allParentalRatings.length; i < length; i++) {
|
||||
|
||||
var rating = allParentalRatings[i];
|
||||
|
||||
if (user.Configuration.MaxParentalRating >= rating.Value) {
|
||||
ratingValue = rating.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$('#selectMaxParentalRating', page).val(ratingValue).selectmenu("refresh");
|
||||
|
||||
$('#selectAudioLanguage', page).val(user.Configuration.AudioLanguagePreference || "").selectmenu("refresh");
|
||||
$('#selectSubtitleLanguage', page).val(user.Configuration.SubtitleLanguagePreference || "").selectmenu("refresh");
|
||||
|
||||
$('#chkForcedSubtitlesOnly', page).checked(user.Configuration.UseForcedSubtitlesOnly || false).checkboxradio("refresh");
|
||||
$('#chkIsAdmin', page).checked(user.Configuration.IsAdministrator || false).checkboxradio("refresh");
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
},
|
||||
|
||||
populateLanguages: function (select, allCultures) {
|
||||
|
||||
var html = "";
|
||||
|
||||
html += "<option value=''>None</option>";
|
||||
|
||||
for (var i = 0, length = allCultures.length; i < length; i++) {
|
||||
|
||||
var culture = allCultures[i];
|
||||
|
||||
html += "<option value='" + culture.ThreeLetterISOLanguageName + "'>" + culture.DisplayName + "</option>";
|
||||
}
|
||||
|
||||
select.html(html).selectmenu("refresh");
|
||||
},
|
||||
|
||||
populateRatings: function (allParentalRatings, page) {
|
||||
|
||||
var html = "";
|
||||
|
||||
html += "<option value=''>None</option>";
|
||||
|
||||
for (var i = 0, length = allParentalRatings.length; i < length; i++) {
|
||||
|
||||
var rating = allParentalRatings[i];
|
||||
|
||||
html += "<option value='" + rating.Value + "'>" + rating.Name + "</option>";
|
||||
}
|
||||
|
||||
$('#selectMaxParentalRating', page).html(html).selectmenu("refresh");
|
||||
},
|
||||
|
||||
saveUser: function (user) {
|
||||
|
||||
var page = $($.mobile.activePage);
|
||||
|
||||
user.Name = $('#txtUserName', page).val();
|
||||
user.Configuration.MaxParentalRating = $('#selectMaxParentalRating', page).val() || null;
|
||||
|
||||
user.Configuration.IsAdministrator = $('#chkIsAdmin', page).checked();
|
||||
|
||||
user.Configuration.AudioLanguagePreference = $('#selectAudioLanguage', page).val();
|
||||
user.Configuration.SubtitleLanguagePreference = $('#selectSubtitleLanguage', page).val();
|
||||
user.Configuration.UseForcedSubtitlesOnly = $('#chkForcedSubtitlesOnly', page).checked();
|
||||
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
if (userId) {
|
||||
ApiClient.updateUser(user).done(EditUserPage.saveComplete);
|
||||
} else {
|
||||
ApiClient.createUser(user).done(EditUserPage.saveComplete);
|
||||
}
|
||||
},
|
||||
|
||||
saveComplete: function () {
|
||||
Dashboard.hideLoadingMsg();
|
||||
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
Dashboard.validateCurrentUser();
|
||||
|
||||
if (userId) {
|
||||
Dashboard.alert("Settings saved.");
|
||||
} else {
|
||||
Dashboard.navigate("userProfiles.html");
|
||||
}
|
||||
},
|
||||
|
||||
onSubmit: function () {
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
if (!userId) {
|
||||
EditUserPage.saveUser({
|
||||
Configuration: {}
|
||||
});
|
||||
} else {
|
||||
ApiClient.getUser(userId).done(EditUserPage.saveUser);
|
||||
}
|
||||
|
||||
// Disable default form submission
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#editUserPage", EditUserPage.onPageShow);
|
333
Html/scripts/Extensions.js
Normal file
@ -0,0 +1,333 @@
|
||||
// Array Remove - By John Resig (MIT Licensed)
|
||||
Array.prototype.remove = function (from, to) {
|
||||
var rest = this.slice((to || from) + 1 || this.length);
|
||||
this.length = from < 0 ? this.length + from : from;
|
||||
return this.push.apply(this, rest);
|
||||
};
|
||||
|
||||
String.prototype.endsWith = function (suffix) {
|
||||
return this.indexOf(suffix, this.length - suffix.length) !== -1;
|
||||
};
|
||||
|
||||
$.fn.checked = function (value) {
|
||||
if (value === true || value === false) {
|
||||
// Set the value of the checkbox
|
||||
return $(this).each(function () {
|
||||
this.checked = value;
|
||||
});
|
||||
} else {
|
||||
// Return check state
|
||||
return $(this).is(':checked');
|
||||
}
|
||||
};
|
||||
|
||||
var WebNotifications = {
|
||||
|
||||
show: function (data) {
|
||||
if (window.webkitNotifications) {
|
||||
if (!webkitNotifications.checkPermission()) {
|
||||
var notif = webkitNotifications.createNotification(data.icon, data.title, data.body);
|
||||
notif.show();
|
||||
|
||||
if (data.timeout) {
|
||||
setTimeout(function () {
|
||||
notif.cancel();
|
||||
}, data.timeout);
|
||||
}
|
||||
|
||||
return notif;
|
||||
} else {
|
||||
webkitNotifications.requestPermission(function () {
|
||||
return WebNotifications.show(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (window.Notification) {
|
||||
if (Notification.permissionLevel() === "granted") {
|
||||
var notif = new Notification(data.title, data);
|
||||
notif.show();
|
||||
|
||||
if (data.timeout) {
|
||||
setTimeout(function () {
|
||||
notif.cancel();
|
||||
}, data.timeout);
|
||||
}
|
||||
|
||||
return notif;
|
||||
} else if (Notification.permissionLevel() === "default") {
|
||||
Notification.requestPermission(function () {
|
||||
return WebNotifications.show(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
requestPermission: function () {
|
||||
if (window.webkitNotifications) {
|
||||
if (!webkitNotifications.checkPermission()) {
|
||||
} else {
|
||||
webkitNotifications.requestPermission(function () {
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (window.Notification) {
|
||||
if (Notification.permissionLevel() === "granted") {
|
||||
} else if (Notification.permissionLevel() === "default") {
|
||||
Notification.requestPermission(function () {
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Javascript Humane Dates
|
||||
* Copyright (c) 2008 Dean Landolt (deanlandolt.com)
|
||||
* Re-write by Zach Leatherman (zachleat.com)
|
||||
*
|
||||
* Adopted from the John Resig's pretty.js
|
||||
* at http://ejohn.org/blog/javascript-pretty-date
|
||||
* and henrah's proposed modification
|
||||
* at http://ejohn.org/blog/javascript-pretty-date/#comment-297458
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
*/
|
||||
|
||||
function humane_date(date_str) {
|
||||
var time_formats = [[90, 'a minute'], // 60*1.5
|
||||
[3600, 'minutes', 60], // 60*60, 60
|
||||
[5400, 'an hour'], // 60*60*1.5
|
||||
[86400, 'hours', 3600], // 60*60*24, 60*60
|
||||
[129600, 'a day'], // 60*60*24*1.5
|
||||
[604800, 'days', 86400], // 60*60*24*7, 60*60*24
|
||||
[907200, 'a week'], // 60*60*24*7*1.5
|
||||
[2628000, 'weeks', 604800], // 60*60*24*(365/12), 60*60*24*7
|
||||
[3942000, 'a month'], // 60*60*24*(365/12)*1.5
|
||||
[31536000, 'months', 2628000], // 60*60*24*365, 60*60*24*(365/12)
|
||||
[47304000, 'a year'], // 60*60*24*365*1.5
|
||||
[3153600000, 'years', 31536000] // 60*60*24*365*100, 60*60*24*365
|
||||
];
|
||||
|
||||
var dt = new Date;
|
||||
var date = parseISO8601Date(date_str, true);
|
||||
|
||||
var seconds = ((dt - date) / 1000);
|
||||
var token = ' ago';
|
||||
var i = 0;
|
||||
var format;
|
||||
|
||||
if (seconds < 0) {
|
||||
seconds = Math.abs(seconds);
|
||||
token = '';
|
||||
}
|
||||
|
||||
while (format = time_formats[i++]) {
|
||||
if (seconds < format[0]) {
|
||||
if (format.length == 2) {
|
||||
return format[1] + token;
|
||||
} else {
|
||||
return Math.round(seconds / format[2]) + ' ' + format[1] + token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// overflow for centuries
|
||||
if (seconds > 4730400000)
|
||||
return Math.round(seconds / 4730400000) + ' centuries' + token;
|
||||
|
||||
return date_str;
|
||||
};
|
||||
|
||||
function humane_elapsed(firstDateStr, secondDateStr) {
|
||||
var dt1 = new Date(firstDateStr);
|
||||
var dt2 = new Date(secondDateStr);
|
||||
var seconds = (dt2.getTime() - dt1.getTime()) / 1000;
|
||||
var numdays = Math.floor((seconds % 31536000) / 86400);
|
||||
var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600);
|
||||
var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60);
|
||||
var numseconds = Math.round((((seconds % 31536000) % 86400) % 3600) % 60);
|
||||
|
||||
var elapsedStr = '';
|
||||
elapsedStr += numdays == 1 ? numdays + ' day ' : '';
|
||||
elapsedStr += numdays > 1 ? numdays + ' days ' : '';
|
||||
elapsedStr += numhours == 1 ? numhours + ' hour ' : '';
|
||||
elapsedStr += numhours > 1 ? numhours + ' hours ' : '';
|
||||
elapsedStr += numminutes == 1 ? numminutes + ' minute ' : '';
|
||||
elapsedStr += numminutes > 1 ? numminutes + ' minutes ' : '';
|
||||
elapsedStr += elapsedStr.length > 0 ? 'and ' : '';
|
||||
elapsedStr += numseconds == 1 ? numseconds + ' second' : '';
|
||||
elapsedStr += numseconds == 0 || numseconds > 1 ? numseconds + ' seconds' : '';
|
||||
|
||||
return elapsedStr;
|
||||
|
||||
}
|
||||
|
||||
function getParameterByName(name) {
|
||||
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
|
||||
var regexS = "[\\?&]" + name + "=([^&#]*)";
|
||||
var regex = new RegExp(regexS);
|
||||
var results = regex.exec(window.location.search);
|
||||
if (results == null)
|
||||
return "";
|
||||
else
|
||||
return decodeURIComponent(results[1].replace(/\+/g, " "));
|
||||
}
|
||||
|
||||
function parseISO8601Date(s, toLocal) {
|
||||
|
||||
// parenthese matches:
|
||||
// year month day hours minutes seconds
|
||||
// dotmilliseconds
|
||||
// tzstring plusminus hours minutes
|
||||
var re = /(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d+)?(Z|([+-])(\d\d):(\d\d))/;
|
||||
|
||||
var d = [];
|
||||
d = s.match(re);
|
||||
|
||||
// "2010-12-07T11:00:00.000-09:00" parses to:
|
||||
// ["2010-12-07T11:00:00.000-09:00", "2010", "12", "07", "11",
|
||||
// "00", "00", ".000", "-09:00", "-", "09", "00"]
|
||||
// "2010-12-07T11:00:00.000Z" parses to:
|
||||
// ["2010-12-07T11:00:00.000Z", "2010", "12", "07", "11",
|
||||
// "00", "00", ".000", "Z", undefined, undefined, undefined]
|
||||
|
||||
if (!d) {
|
||||
throw "Couldn't parse ISO 8601 date string '" + s + "'";
|
||||
}
|
||||
|
||||
// parse strings, leading zeros into proper ints
|
||||
var a = [1, 2, 3, 4, 5, 6, 10, 11];
|
||||
for (var i in a) {
|
||||
d[a[i]] = parseInt(d[a[i]], 10);
|
||||
}
|
||||
d[7] = parseFloat(d[7]);
|
||||
|
||||
// Date.UTC(year, month[, date[, hrs[, min[, sec[, ms]]]]])
|
||||
// note that month is 0-11, not 1-12
|
||||
// see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/UTC
|
||||
var ms = Date.UTC(d[1], d[2] - 1, d[3], d[4], d[5], d[6]);
|
||||
|
||||
// if there are milliseconds, add them
|
||||
if (d[7] > 0) {
|
||||
ms += Math.round(d[7] * 1000);
|
||||
}
|
||||
|
||||
// if there's a timezone, calculate it
|
||||
if (d[8] != "Z" && d[10]) {
|
||||
var offset = d[10] * 60 * 60 * 1000;
|
||||
if (d[11]) {
|
||||
offset += d[11] * 60 * 1000;
|
||||
}
|
||||
if (d[9] == "-") {
|
||||
ms -= offset;
|
||||
} else {
|
||||
ms += offset;
|
||||
}
|
||||
} else if (!toLocal) {
|
||||
ms += new Date().getTimezoneOffset() * 60000;
|
||||
}
|
||||
|
||||
return new Date(ms);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// jqm.page.params.js - version 0.1
|
||||
// Copyright (c) 2011, Kin Blas
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the <organization> nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
(function ($, window, undefined) {
|
||||
|
||||
// Given a query string, convert all the name/value pairs
|
||||
// into a property/value object. If a name appears more than
|
||||
// once in a query string, the value is automatically turned
|
||||
// into an array.
|
||||
function queryStringToObject(qstr) {
|
||||
var result = {}, nvPairs = ((qstr || "").replace(/^\?/, "").split(/&/)), i, pair, n, v;
|
||||
|
||||
for (i = 0; i < nvPairs.length; i++) {
|
||||
var pstr = nvPairs[i];
|
||||
if (pstr) {
|
||||
pair = pstr.split(/=/);
|
||||
n = pair[0];
|
||||
v = pair[1];
|
||||
if (result[n] === undefined) {
|
||||
result[n] = v;
|
||||
} else {
|
||||
if (typeof result[n] !== "object") {
|
||||
result[n] = [result[n]];
|
||||
}
|
||||
result[n].push(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// The idea here is to listen for any pagebeforechange notifications from
|
||||
// jQuery Mobile, and then muck with the toPage and options so that query
|
||||
// params can be passed to embedded/internal pages. So for example, if a
|
||||
// changePage() request for a URL like:
|
||||
//
|
||||
// http://mycompany.com/myapp/#page-1?foo=1&bar=2
|
||||
//
|
||||
// is made, the page that will actually get shown is:
|
||||
//
|
||||
// http://mycompany.com/myapp/#page-1
|
||||
//
|
||||
// The browser's location will still be updated to show the original URL.
|
||||
// The query params for the embedded page are also added as a property/value
|
||||
// object on the options object. You can access it from your page notifications
|
||||
// via data.options.pageData.
|
||||
$(document).bind("pagebeforechange", function (e, data) {
|
||||
|
||||
// We only want to handle the case where we are being asked
|
||||
// to go to a page by URL, and only if that URL is referring
|
||||
// to an internal page by id.
|
||||
|
||||
if (typeof data.toPage === "string") {
|
||||
var u = $.mobile.path.parseUrl(data.toPage);
|
||||
if ($.mobile.path.isEmbeddedPage(u)) {
|
||||
|
||||
// The request is for an internal page, if the hash
|
||||
// contains query (search) params, strip them off the
|
||||
// toPage URL and then set options.dataUrl appropriately
|
||||
// so the location.hash shows the originally requested URL
|
||||
// that hash the query params in the hash.
|
||||
|
||||
var u2 = $.mobile.path.parseUrl(u.hash.replace(/^#/, ""));
|
||||
if (u2.search) {
|
||||
if (!data.options.dataUrl) {
|
||||
data.options.dataUrl = data.toPage;
|
||||
}
|
||||
data.options.pageData = queryStringToObject(u2.search);
|
||||
data.toPage = u.hrefNoHash + "#" + u2.pathname;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery, window);
|
106
Html/scripts/IndexPage.js
Normal file
@ -0,0 +1,106 @@
|
||||
var IndexPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
IndexPage.loadLibrary(Dashboard.getCurrentUserId(), this);
|
||||
},
|
||||
|
||||
loadLibrary: function (userId, page) {
|
||||
|
||||
if (!userId) {
|
||||
return;
|
||||
}
|
||||
|
||||
page = $(page);
|
||||
|
||||
var options = {
|
||||
|
||||
limit: 5,
|
||||
sortBy: "DateCreated",
|
||||
sortOrder: "Descending",
|
||||
filters: "IsRecentlyAdded,IsNotFolder",
|
||||
ImageTypes: "Primary,Backdrop,Thumb",
|
||||
recursive: true
|
||||
};
|
||||
|
||||
ApiClient.getItems(userId, options).done(function (result) {
|
||||
|
||||
$('#divWhatsNew', page).html(Dashboard.getPosterViewHtml({
|
||||
items: result.Items,
|
||||
preferBackdrop: true,
|
||||
showTitle: true
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
options = {
|
||||
|
||||
limit: 5,
|
||||
sortBy: "DatePlayed",
|
||||
sortOrder: "Descending",
|
||||
filters: "IsResumable",
|
||||
recursive: true
|
||||
};
|
||||
|
||||
ApiClient.getItems(userId, options).done(function (result) {
|
||||
|
||||
$('#divResumableItems', page).html(Dashboard.getPosterViewHtml({
|
||||
items: result.Items,
|
||||
preferBackdrop: true,
|
||||
showTitle: true
|
||||
}));
|
||||
|
||||
if (result.Items.length) {
|
||||
$('#divResumable', page).show();
|
||||
} else {
|
||||
$('#divResumable', page).hide();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
options = {
|
||||
|
||||
sortBy: "SortName"
|
||||
};
|
||||
|
||||
ApiClient.getItems(userId, options).done(function (result) {
|
||||
|
||||
$('#divCollections', page).html(Dashboard.getPosterViewHtml({
|
||||
items: result.Items,
|
||||
showTitle: true
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
IndexPage.loadMyLibrary(userId, page);
|
||||
},
|
||||
|
||||
loadMyLibrary: function (userId, page) {
|
||||
|
||||
var items = [{
|
||||
Name: "Recently Played",
|
||||
IsFolder: true
|
||||
}, {
|
||||
Name: "Favorites",
|
||||
IsFolder: true
|
||||
}, {
|
||||
Name: "Genres",
|
||||
IsFolder: true
|
||||
}, {
|
||||
Name: "Studios",
|
||||
IsFolder: true
|
||||
}, {
|
||||
Name: "Performers",
|
||||
IsFolder: true
|
||||
}, {
|
||||
Name: "Directors",
|
||||
IsFolder: true
|
||||
}];
|
||||
|
||||
$('#divMyLibrary', page).html(Dashboard.getPosterViewHtml({
|
||||
items: items,
|
||||
showTitle: true
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#indexPage", IndexPage.onPageShow);
|
353
Html/scripts/ItemDetailPage.js
Normal file
@ -0,0 +1,353 @@
|
||||
var ItemDetailPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
|
||||
var id = getParameterByName('id');
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.getItem(Dashboard.getCurrentUserId(), id).done(ItemDetailPage.renderItem);
|
||||
|
||||
},
|
||||
|
||||
renderItem: function (item) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
ItemDetailPage.item = item;
|
||||
|
||||
var name = item.Name;
|
||||
|
||||
if (item.IndexNumber != null) {
|
||||
name = item.IndexNumber + " - " + name;
|
||||
}
|
||||
|
||||
Dashboard.setPageTitle(name);
|
||||
|
||||
ItemDetailPage.renderImage(item);
|
||||
ItemDetailPage.renderOverviewBlock(item);
|
||||
ItemDetailPage.renderScenes(item);
|
||||
ItemDetailPage.renderGallery(item);
|
||||
ItemDetailPage.renderMediaInfo(item);
|
||||
|
||||
$('#itemName', page).html(name);
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
},
|
||||
|
||||
renderImage: function (item) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
var imageTags = item.ImageTags || {};
|
||||
|
||||
var html = '';
|
||||
|
||||
var url;
|
||||
var useBackgroundColor;
|
||||
|
||||
if (imageTags.Primary) {
|
||||
|
||||
url = ApiClient.getImageUrl(item.Id, {
|
||||
type: "Primary",
|
||||
width: 800,
|
||||
tag: item.ImageTags.Primary
|
||||
});
|
||||
}
|
||||
else if (item.BackdropImageTags && item.BackdropImageTags.length) {
|
||||
|
||||
url = ApiClient.getImageUrl(item.Id, {
|
||||
type: "Backdrop",
|
||||
width: 800,
|
||||
tag: item.BackdropImageTags[0]
|
||||
});
|
||||
}
|
||||
else if (imageTags.Thumb) {
|
||||
|
||||
url = ApiClient.getImageUrl(item.Id, {
|
||||
type: "Thumb",
|
||||
width: 800,
|
||||
tag: item.ImageTags.Thumb
|
||||
});
|
||||
}
|
||||
else if (imageTags.Disc) {
|
||||
|
||||
url = ApiClient.getImageUrl(item.Id, {
|
||||
type: "Disc",
|
||||
width: 800,
|
||||
tag: item.ImageTags.Disc
|
||||
});
|
||||
}
|
||||
else if (item.MediaType == "Audio") {
|
||||
url = "css/images/itemDetails/audioDefault.png";
|
||||
useBackgroundColor = true;
|
||||
}
|
||||
else if (item.MediaType == "Game") {
|
||||
url = "css/images/itemDetails/gameDefault.png";
|
||||
useBackgroundColor = true;
|
||||
}
|
||||
else {
|
||||
url = "css/images/itemDetails/videoDefault.png";
|
||||
useBackgroundColor = true;
|
||||
}
|
||||
|
||||
if (url) {
|
||||
|
||||
var style = useBackgroundColor ? "background-color:" + Dashboard.getRandomMetroColor() + ";" : "";
|
||||
|
||||
html += "<img class='itemDetailImage' src='" + url + "' style='" + style + "' />";
|
||||
}
|
||||
|
||||
$('#itemImage', page).html(html);
|
||||
},
|
||||
|
||||
renderOverviewBlock: function (item) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
if (item.Taglines && item.Taglines.length) {
|
||||
$('#itemTagline', page).html(item.Taglines[0]).show();
|
||||
} else {
|
||||
$('#itemTagline', page).hide();
|
||||
}
|
||||
|
||||
if (item.Overview) {
|
||||
$('#itemOverview', page).html(item.Overview).show();
|
||||
} else {
|
||||
$('#itemOverview', page).hide();
|
||||
}
|
||||
|
||||
if (item.CommunityRating) {
|
||||
$('#itemCommunityRating', page).html(ItemDetailPage.getStarRating(item)).show().attr('title', item.CommunityRating);
|
||||
} else {
|
||||
$('#itemCommunityRating', page).hide();
|
||||
}
|
||||
|
||||
if (MediaPlayer.canPlay(item)) {
|
||||
$('#btnPlay', page).show();
|
||||
$('#playButtonShadow', page).show();
|
||||
} else {
|
||||
$('#btnPlay', page).hide();
|
||||
$('#playButtonShadow', page).hide();
|
||||
}
|
||||
|
||||
var miscInfo = [];
|
||||
|
||||
if (item.ProductionYear) {
|
||||
miscInfo.push(item.ProductionYear);
|
||||
}
|
||||
|
||||
if (item.OfficialRating) {
|
||||
miscInfo.push(item.OfficialRating);
|
||||
}
|
||||
|
||||
if (item.RunTimeTicks) {
|
||||
|
||||
var minutes = item.RunTimeTicks / 600000000;
|
||||
|
||||
minutes = minutes || 1;
|
||||
|
||||
miscInfo.push(parseInt(minutes) + "min");
|
||||
}
|
||||
|
||||
if (item.DisplayMediaType) {
|
||||
miscInfo.push(item.DisplayMediaType);
|
||||
}
|
||||
|
||||
if (item.VideoFormat && item.VideoFormat !== 'Standard') {
|
||||
miscInfo.push(item.VideoFormat);
|
||||
}
|
||||
|
||||
$('#itemMiscInfo', page).html(miscInfo.join(' '));
|
||||
|
||||
ItemDetailPage.renderGenres(item);
|
||||
ItemDetailPage.renderStudios(item);
|
||||
},
|
||||
|
||||
renderGenres: function (item) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
if (item.Genres && item.Genres.length) {
|
||||
var elem = $('#itemGenres', page).show();
|
||||
|
||||
var html = 'Genres: ';
|
||||
|
||||
for (var i = 0, length = item.Genres.length; i < length; i++) {
|
||||
|
||||
if (i > 0) {
|
||||
html += ' / ';
|
||||
}
|
||||
|
||||
html += '<a class="interiorLink" href="#">' + item.Genres[i] + '</a>';
|
||||
}
|
||||
|
||||
elem.html(html);
|
||||
|
||||
|
||||
} else {
|
||||
$('#itemGenres', page).hide();
|
||||
}
|
||||
},
|
||||
|
||||
renderStudios: function (item) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
if (item.Studios && item.Studios.length) {
|
||||
var elem = $('#itemStudios', page).show();
|
||||
|
||||
var html = 'Studios: ';
|
||||
|
||||
for (var i = 0, length = item.Studios.length; i < length; i++) {
|
||||
|
||||
if (i > 0) {
|
||||
html += ' / ';
|
||||
}
|
||||
|
||||
html += '<a class="interiorLink" href="#">' + item.Studios[i] + '</a>';
|
||||
}
|
||||
|
||||
elem.html(html);
|
||||
|
||||
|
||||
} else {
|
||||
$('#itemStudios', page).hide();
|
||||
}
|
||||
},
|
||||
|
||||
getStarRating: function (item) {
|
||||
var rating = item.CommunityRating;
|
||||
|
||||
var html = "";
|
||||
for (var i = 1; i <= 10; i++) {
|
||||
if (rating < i - 1) {
|
||||
html += "<div class='starRating emptyStarRating'></div>";
|
||||
}
|
||||
else if (rating < i) {
|
||||
html += "<div class='starRating halfStarRating'></div>";
|
||||
}
|
||||
else {
|
||||
html += "<div class='starRating'></div>";
|
||||
}
|
||||
}
|
||||
|
||||
return html;
|
||||
},
|
||||
|
||||
renderScenes: function (item) {
|
||||
|
||||
var html = '';
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
if (!item.Chapters || !item.Chapters.length) {
|
||||
$('#scenesCollapsible', page).hide();
|
||||
$('#scenesContent', page).html(html);
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0, length = item.Chapters.length; i < length; i++) {
|
||||
|
||||
var chapter = item.Chapters[i];
|
||||
|
||||
|
||||
}
|
||||
|
||||
$('#scenesCollapsible', page).show();
|
||||
$('#scenesContent', page).html(html);
|
||||
},
|
||||
|
||||
play: function () {
|
||||
MediaPlayer.play([ItemDetailPage.item]);
|
||||
},
|
||||
|
||||
renderGallery: function (item) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
var imageTags = item.ImageTags || {};
|
||||
|
||||
var html = '';
|
||||
|
||||
var downloadWidth = 400;
|
||||
|
||||
if (imageTags.Logo) {
|
||||
|
||||
html += '<img class="galleryImage" src="' + ApiClient.getImageUrl(item.Id, {
|
||||
type: "Logo",
|
||||
width: downloadWidth,
|
||||
tag: item.ImageTags.Logo
|
||||
}) + '" />';
|
||||
}
|
||||
if (imageTags.Thumb) {
|
||||
|
||||
html += '<img class="galleryImage" src="' + ApiClient.getImageUrl(item.Id, {
|
||||
type: "Thumb",
|
||||
width: downloadWidth,
|
||||
tag: item.ImageTags.Thumb
|
||||
}) + '" />';
|
||||
}
|
||||
if (imageTags.Art) {
|
||||
|
||||
html += '<img class="galleryImage" src="' + ApiClient.getImageUrl(item.Id, {
|
||||
type: "Art",
|
||||
width: downloadWidth,
|
||||
tag: item.ImageTags.Art
|
||||
}) + '" />';
|
||||
}
|
||||
if (imageTags.Menu) {
|
||||
|
||||
html += '<img class="galleryImage" src="' + ApiClient.getImageUrl(item.Id, {
|
||||
type: "Menu",
|
||||
width: downloadWidth,
|
||||
tag: item.ImageTags.Menu
|
||||
}) + '" />';
|
||||
}
|
||||
if (imageTags.Disc) {
|
||||
|
||||
html += '<img class="galleryImage" src="' + ApiClient.getImageUrl(item.Id, {
|
||||
type: "Disc",
|
||||
width: downloadWidth,
|
||||
tag: item.ImageTags.Disc
|
||||
}) + '" />';
|
||||
}
|
||||
if (imageTags.Box) {
|
||||
|
||||
html += '<img class="galleryImage" src="' + ApiClient.getImageUrl(item.Id, {
|
||||
type: "Box",
|
||||
width: downloadWidth,
|
||||
tag: item.ImageTags.Box
|
||||
}) + '" />';
|
||||
}
|
||||
|
||||
if (item.BackdropImageTags) {
|
||||
|
||||
for (var i = 0, length = item.BackdropImageTags.length; i < length; i++) {
|
||||
html += '<img class="galleryImage" src="' + ApiClient.getImageUrl(item.Id, {
|
||||
type: "Backdrop",
|
||||
width: downloadWidth,
|
||||
tag: item.BackdropImageTags[0],
|
||||
index: i
|
||||
}) + '" />';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$('#galleryContent', page).html(html);
|
||||
},
|
||||
|
||||
renderMediaInfo: function(item) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
if (!item.MediaStreams || !item.MediaStreams.length) {
|
||||
$('#mediaInfoCollapsible', page).hide();
|
||||
return;
|
||||
}
|
||||
|
||||
$('#mediaInfoCollapsible', page).show();
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#itemDetailPage", ItemDetailPage.onPageShow);
|
86
Html/scripts/LogPage.js
Normal file
@ -0,0 +1,86 @@
|
||||
var LogPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
|
||||
LogPage.startLine = 0;
|
||||
|
||||
$('#logContents', this).html('');
|
||||
|
||||
$(document).on("websocketmessage", LogPage.onWebSocketMessage).on("websocketopen", LogPage.onWebSocketConnectionChange).on("websocketerror", LogPage.onWebSocketConnectionChange).on("websocketclose", LogPage.onWebSocketConnectionChange);
|
||||
|
||||
LogPage.startInterval();
|
||||
|
||||
var autoScroll = localStorage.getItem("autoScrollLogPage");
|
||||
|
||||
if (autoScroll == "true") {
|
||||
LogPage.updateAutoScroll(true);
|
||||
}
|
||||
else if (autoScroll == "false") {
|
||||
LogPage.updateAutoScroll(false);
|
||||
}
|
||||
},
|
||||
|
||||
onPageHide: function () {
|
||||
|
||||
$(document).off("websocketmessage", LogPage.onWebSocketMessage).off("websocketopen", LogPage.onWebSocketConnectionChange).off("websocketerror", LogPage.onWebSocketConnectionChange).off("websocketclose", LogPage.onWebSocketConnectionChange);
|
||||
|
||||
LogPage.stopInterval();
|
||||
},
|
||||
|
||||
startInterval: function () {
|
||||
|
||||
if (Dashboard.isWebSocketOpen()) {
|
||||
Dashboard.sendWebSocketMessage("LogFileStart", "0,2000");
|
||||
}
|
||||
},
|
||||
|
||||
stopInterval: function () {
|
||||
|
||||
if (Dashboard.isWebSocketOpen()) {
|
||||
Dashboard.sendWebSocketMessage("LogFileStop");
|
||||
}
|
||||
},
|
||||
|
||||
onWebSocketConnectionChange: function () {
|
||||
LogPage.stopInterval();
|
||||
LogPage.startInterval();
|
||||
},
|
||||
|
||||
onWebSocketMessage: function (e, msg) {
|
||||
|
||||
if (msg.MessageType == "LogFile") {
|
||||
LogPage.appendLines(msg.Data);
|
||||
}
|
||||
},
|
||||
|
||||
appendLines: function (lines) {
|
||||
|
||||
if (!lines.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
LogPage.startLine += lines.length;
|
||||
|
||||
lines = lines.join('\n') + '\n';
|
||||
|
||||
var elem = $('#logContents', $.mobile.activePage).append(lines)[0];
|
||||
|
||||
elem.style.height = (elem.scrollHeight) + 'px';
|
||||
|
||||
if ($('#chkAutoScroll', $.mobile.activePage).checked()) {
|
||||
$('html, body').animate({ scrollTop: $(document).height() }, 'slow');
|
||||
}
|
||||
},
|
||||
|
||||
updateAutoScroll: function (value) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
$('#chkAutoScrollBottom', page).checked(value).checkboxradio('refresh');
|
||||
$('#chkAutoScroll', page).checked(value).checkboxradio('refresh');
|
||||
|
||||
localStorage.setItem("autoScrollLogPage", value.toString());
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#logPage", LogPage.onPageShow).on('pagehide', "#logPage", LogPage.onPageHide);
|
112
Html/scripts/LoginPage.js
Normal file
@ -0,0 +1,112 @@
|
||||
var LoginPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.getAllUsers().done(LoginPage.loadUserList);
|
||||
},
|
||||
|
||||
getLastSeenText: function (lastActivityDate) {
|
||||
|
||||
if (!lastActivityDate) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return "Last seen " + humane_date(lastActivityDate);
|
||||
},
|
||||
|
||||
getImagePath: function (user) {
|
||||
|
||||
if (!user.PrimaryImageTag) {
|
||||
return "css/images/logindefault.png";
|
||||
}
|
||||
|
||||
return ApiClient.getUserImageUrl(user.Id, {
|
||||
width: 240,
|
||||
tag: user.PrimaryImageTag,
|
||||
type: "Primary"
|
||||
});
|
||||
},
|
||||
|
||||
authenticateUserLink: function (link) {
|
||||
|
||||
LoginPage.authenticateUser(link.getAttribute('data-username'), link.getAttribute('data-userid'));
|
||||
},
|
||||
|
||||
authenticateUser: function (username, userId, password) {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.authenticateUser(userId, password).done(function () {
|
||||
|
||||
Dashboard.setCurrentUser(userId);
|
||||
|
||||
window.location = "index.html?u=" + userId;
|
||||
|
||||
}).fail(function () {
|
||||
Dashboard.hideLoadingMsg();
|
||||
|
||||
setTimeout(function () {
|
||||
Dashboard.showError("Invalid user or password.");
|
||||
}, 300);
|
||||
});
|
||||
},
|
||||
|
||||
loadUserList: function (users) {
|
||||
var html = "";
|
||||
|
||||
for (var i = 0, length = users.length; i < length; i++) {
|
||||
var user = users[i];
|
||||
|
||||
var linkId = "lnkUser" + i;
|
||||
|
||||
var background = Dashboard.getRandomMetroColor();
|
||||
|
||||
if (user.HasPassword) {
|
||||
html += "<a id='" + linkId + "' data-userid='" + user.Id + "' data-username='" + user.Name + "' href='#popupLogin' data-rel='popup' onclick='LoginPage.authenticatingLinkId=this.id;' class='userItem'>";
|
||||
} else {
|
||||
html += "<a id='" + linkId + "' data-userid='" + user.Id + "' data-username='" + user.Name + "' href='#' onclick='LoginPage.authenticateUserLink(this);' class='userItem'>";
|
||||
}
|
||||
|
||||
if (user.PrimaryImageTag) {
|
||||
|
||||
var imgUrl = ApiClient.getUserImageUrl(user.Id, {
|
||||
width: 500,
|
||||
tag: user.PrimaryImageTag,
|
||||
type: "Primary"
|
||||
});
|
||||
|
||||
html += '<img class="userItemImage" src="' + imgUrl + '" />';
|
||||
} else {
|
||||
html += '<img class="userItemImage" src="css/images/logindefault.png" style="background:' + background + ';" />';
|
||||
}
|
||||
|
||||
html += '<div class="userItemContent" style="background:' + background + ';">';
|
||||
|
||||
html += '<div class="userItemContentInner">';
|
||||
html += '<p class="userItemHeader">' + user.Name + '</p>';
|
||||
html += '<p>' + LoginPage.getLastSeenText(user.LastActivityDate) + '</p>';
|
||||
html += '</div>';
|
||||
|
||||
html += '</div>';
|
||||
html += '</a>';
|
||||
}
|
||||
|
||||
$('#divUsers', '#loginPage').html(html);
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
},
|
||||
|
||||
onSubmit: function () {
|
||||
$('#popupLogin', '#loginPage').popup('close');
|
||||
|
||||
var link = $('#' + LoginPage.authenticatingLinkId)[0];
|
||||
|
||||
LoginPage.authenticateUser(link.getAttribute('data-username'), link.getAttribute('data-userid'), $('#pw', '#loginPage').val());
|
||||
|
||||
// Disable default form submission
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#loginPage", LoginPage.onPageShow);
|
272
Html/scripts/MediaLibraryPage.js
Normal file
@ -0,0 +1,272 @@
|
||||
var MediaLibraryPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
|
||||
MediaLibraryPage.lastVirtualFolderName = "";
|
||||
|
||||
MediaLibraryPage.reloadLibrary();
|
||||
},
|
||||
|
||||
reloadLibrary: function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
if (userId) {
|
||||
|
||||
$('#userProfileNavigation', page).show();
|
||||
|
||||
ApiClient.getUser(userId).done(function (user) {
|
||||
|
||||
Dashboard.setPageTitle(user.Name);
|
||||
|
||||
$('#fldUseDefaultLibrary', page).show();
|
||||
|
||||
$('#chkUseDefaultLibrary', page).checked(!user.Configuration.UseCustomLibrary).checkboxradio("refresh");
|
||||
|
||||
if (user.Configuration.UseCustomLibrary) {
|
||||
|
||||
ApiClient.getVirtualFolders(userId).done(MediaLibraryPage.reloadVirtualFolders);
|
||||
$('#divMediaLibrary', page).show();
|
||||
} else {
|
||||
$('#divMediaLibrary', page).hide();
|
||||
Dashboard.hideLoadingMsg();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
$('#userProfileNavigation', page).hide();
|
||||
ApiClient.getVirtualFolders().done(MediaLibraryPage.reloadVirtualFolders);
|
||||
|
||||
$('#fldUseDefaultLibrary', page).hide();
|
||||
$('#divMediaLibrary', page).show();
|
||||
Dashboard.setPageTitle("Media Library");
|
||||
}
|
||||
},
|
||||
|
||||
reloadVirtualFolders: function (virtualFolders) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
if (virtualFolders) {
|
||||
MediaLibraryPage.virtualFolders = virtualFolders;
|
||||
} else {
|
||||
virtualFolders = MediaLibraryPage.virtualFolders;
|
||||
}
|
||||
|
||||
var html = '';
|
||||
|
||||
for (var i = 0, length = virtualFolders.length; i < length; i++) {
|
||||
|
||||
var virtualFolder = virtualFolders[i];
|
||||
|
||||
var isCollapsed = MediaLibraryPage.lastVirtualFolderName != virtualFolder.Name;
|
||||
|
||||
html += MediaLibraryPage.getVirtualFolderHtml(virtualFolder, isCollapsed, i);
|
||||
}
|
||||
|
||||
$('#divVirtualFolders', page).html(html).trigger('create');
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
},
|
||||
|
||||
getVirtualFolderHtml: function (virtualFolder, isCollapsed, index) {
|
||||
|
||||
isCollapsed = isCollapsed ? "true" : "false";
|
||||
var html = '<div class="collapsibleVirtualFolder" data-role="collapsible" data-collapsed="' + isCollapsed + '" data-content-theme="c">';
|
||||
|
||||
html += '<h3>' + virtualFolder.Name + '</h3>';
|
||||
|
||||
html += '<ul class="mediaFolderLocations" data-inset="true" data-role="listview" data-split-icon="minus">';
|
||||
|
||||
html += '<li data-role="list-divider" class="mediaLocationsHeader">Media Locations';
|
||||
html += '<button type="button" data-icon="plus" data-mini="true" data-theme="c" data-inline="true" data-iconpos="notext" onclick="MediaLibraryPage.addMediaLocation(' + index + ');"></button>';
|
||||
html += '</li>';
|
||||
|
||||
for (var i = 0, length = virtualFolder.Locations.length; i < length; i++) {
|
||||
|
||||
var location = virtualFolder.Locations[i];
|
||||
html += '<li>';
|
||||
html += '<a class="lnkMediaLocation" href="#">' + location + '</a>';
|
||||
html += '<a href="#" data-index="' + i + '" data-folderindex="' + index + '" onclick="MediaLibraryPage.deleteMediaLocation(this);"></a>';
|
||||
html += '</li>';
|
||||
}
|
||||
html += '</ul>';
|
||||
|
||||
html += '<p>';
|
||||
html += '<button type="button" data-inline="true" data-icon="minus" data-folderindex="' + index + '" onclick="MediaLibraryPage.deleteVirtualFolder(this);">Remove collection</button>';
|
||||
html += '<button type="button" data-inline="true" data-icon="pencil" data-folderindex="' + index + '" onclick="MediaLibraryPage.renameVirtualFolder(this);">Rename collection</button>';
|
||||
html += '</p>';
|
||||
|
||||
html += '</div>';
|
||||
|
||||
return html;
|
||||
},
|
||||
|
||||
setUseDefaultMediaLibrary: function (useDefaultLibrary) {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
ApiClient.getUser(userId).done(function (user) {
|
||||
|
||||
user.Configuration.UseCustomLibrary = !useDefaultLibrary;
|
||||
|
||||
ApiClient.updateUser(user).done(MediaLibraryPage.reloadLibrary);
|
||||
});
|
||||
},
|
||||
|
||||
addVirtualFolder: function () {
|
||||
|
||||
MediaLibraryPage.getTextValue("Add Media Collection", "Name:", "", function (name) {
|
||||
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
MediaLibraryPage.lastVirtualFolderName = name;
|
||||
|
||||
ApiClient.addVirtualFolder(name, userId).done(MediaLibraryPage.processOperationResult);
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
addMediaLocation: function (virtualFolderIndex) {
|
||||
|
||||
MediaLibraryPage.selectDirectory(function (path) {
|
||||
|
||||
if (path) {
|
||||
|
||||
var virtualFolder = MediaLibraryPage.virtualFolders[virtualFolderIndex];
|
||||
|
||||
MediaLibraryPage.lastVirtualFolderName = virtualFolder.Name;
|
||||
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
ApiClient.addMediaPath(virtualFolder.Name, path, userId).done(MediaLibraryPage.processOperationResult);
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
selectDirectory: function (callback) {
|
||||
|
||||
Dashboard.selectDirectory({callback: callback});
|
||||
},
|
||||
|
||||
getTextValue: function (header, label, initialValue, callback) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
var popup = $('#popupEnterText', page);
|
||||
|
||||
$('h3', popup).html(header);
|
||||
$('label', popup).html(label);
|
||||
$('#txtValue', popup).val(initialValue);
|
||||
|
||||
popup.popup("open").on("popupafterclose", function () {
|
||||
|
||||
$(this).off("popupafterclose").off("click");
|
||||
|
||||
$('#textEntryForm', this).off("submit");
|
||||
|
||||
});
|
||||
|
||||
$('#textEntryForm', popup).on('submit', function () {
|
||||
|
||||
if (callback) {
|
||||
callback($('#txtValue', popup).val());
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
},
|
||||
|
||||
renameVirtualFolder: function (button) {
|
||||
|
||||
var folderIndex = button.getAttribute('data-folderindex');
|
||||
var virtualFolder = MediaLibraryPage.virtualFolders[folderIndex];
|
||||
|
||||
MediaLibraryPage.lastVirtualFolderName = virtualFolder.Name;
|
||||
|
||||
MediaLibraryPage.getTextValue(virtualFolder.Name, "Rename " + virtualFolder.Name, virtualFolder.Name, function (newName) {
|
||||
|
||||
if (virtualFolder.Name != newName) {
|
||||
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
ApiClient.renameVirtualFolder(virtualFolder.Name, newName, userId).done(MediaLibraryPage.processOperationResult);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
deleteVirtualFolder: function (button) {
|
||||
|
||||
var folderIndex = button.getAttribute('data-folderindex');
|
||||
var virtualFolder = MediaLibraryPage.virtualFolders[folderIndex];
|
||||
|
||||
var parent = $(button).parents('.collapsibleVirtualFolder');
|
||||
|
||||
var locations = $('.lnkMediaLocation', parent).map(function () {
|
||||
return this.innerHTML;
|
||||
}).get();
|
||||
|
||||
var msg = "Are you sure you wish to remove " + virtualFolder.Name + "?";
|
||||
|
||||
if (locations.length) {
|
||||
msg += "<br/><br/>The following media locations will be removed from your library:<br/><br/>";
|
||||
msg += locations.join("<br/>");
|
||||
}
|
||||
|
||||
MediaLibraryPage.lastVirtualFolderName = virtualFolder.Name;
|
||||
|
||||
Dashboard.confirm(msg, "Remove Media Folder", function (confirmResult) {
|
||||
|
||||
if (confirmResult) {
|
||||
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
ApiClient.removeVirtualFolder(virtualFolder.Name, userId).done(MediaLibraryPage.processOperationResult);
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
deleteMediaLocation: function (button) {
|
||||
|
||||
var folderIndex = button.getAttribute('data-folderindex');
|
||||
var index = parseInt(button.getAttribute('data-index'));
|
||||
|
||||
var virtualFolder = MediaLibraryPage.virtualFolders[folderIndex];
|
||||
|
||||
MediaLibraryPage.lastVirtualFolderName = virtualFolder.Name;
|
||||
|
||||
var location = virtualFolder.Locations[index];
|
||||
|
||||
Dashboard.confirm("Are you sure you wish to remove " + location + "?", "Remove Media Location", function (confirmResult) {
|
||||
|
||||
if (confirmResult) {
|
||||
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
ApiClient.removeMediaPath(virtualFolder.Name, location, userId).done(MediaLibraryPage.processOperationResult);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
processOperationResult: function (result) {
|
||||
Dashboard.hideLoadingMsg();
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
$('#popupEnterText', page).popup("close");
|
||||
$('#popupDirectoryPicker', page).popup("close");
|
||||
MediaLibraryPage.reloadLibrary();
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', ".mediaLibraryPage", MediaLibraryPage.onPageShow);
|
170
Html/scripts/MediaPlayer.js
Normal file
@ -0,0 +1,170 @@
|
||||
var MediaPlayer = {
|
||||
|
||||
canPlay: function (item) {
|
||||
|
||||
if (item.MediaType === "Video") {
|
||||
|
||||
var media = document.createElement('video');
|
||||
|
||||
if (media.canPlayType) {
|
||||
|
||||
return media.canPlayType('video/mp2t').replace(/no/, '') || media.canPlayType('video/webm').replace(/no/, '') || media.canPlayType('video/ogv').replace(/no/, '');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (item.MediaType === "Audio") {
|
||||
|
||||
var media = document.createElement('audio');
|
||||
|
||||
if (media.canPlayType) {
|
||||
return media.canPlayType('audio/mpeg').replace(/no/, '') || media.canPlayType('audio/aac').replace(/no/, '');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
play: function (items) {
|
||||
|
||||
if (MediaPlayer.isPlaying()) {
|
||||
MediaPlayer.stop();
|
||||
}
|
||||
|
||||
var item = items[0];
|
||||
|
||||
var mediaElement;
|
||||
|
||||
if (item.MediaType === "Video") {
|
||||
|
||||
mediaElement = MediaPlayer.playVideo(items);
|
||||
}
|
||||
|
||||
else if (item.MediaType === "Audio") {
|
||||
|
||||
mediaElement = MediaPlayer.playAudio(items);
|
||||
}
|
||||
|
||||
if (!mediaElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
MediaPlayer.mediaElement = mediaElement;
|
||||
|
||||
var nowPlayingBar = $('#nowPlayingBar').show();
|
||||
|
||||
if (items.length > 1) {
|
||||
$('#previousTrackButton', nowPlayingBar)[0].disabled = false;
|
||||
$('#nextTrackButton', nowPlayingBar)[0].disabled = false;
|
||||
} else {
|
||||
$('#previousTrackButton', nowPlayingBar)[0].disabled = true;
|
||||
$('#nextTrackButton', nowPlayingBar)[0].disabled = true;
|
||||
}
|
||||
},
|
||||
|
||||
playAudio: function (items) {
|
||||
var item = items[0];
|
||||
|
||||
var baseParams = {
|
||||
id: item.Id,
|
||||
audioChannels: 2,
|
||||
audioBitrate: 128000
|
||||
};
|
||||
|
||||
var mp3Url = ApiClient.getUrl('audio.mp3', $.extend({}, baseParams, {
|
||||
audioCodec: 'mp3'
|
||||
}));
|
||||
|
||||
var aacUrl = ApiClient.getUrl('audio.aac', $.extend({}, baseParams, {
|
||||
audioCodec: 'aac'
|
||||
}));
|
||||
|
||||
var webmUrl = ApiClient.getUrl('audio.webma', $.extend({}, baseParams, {
|
||||
audioCodec: 'Vorbis'
|
||||
}));
|
||||
|
||||
var oggUrl = ApiClient.getUrl('audio.oga', $.extend({}, baseParams, {
|
||||
audioCodec: 'Vorbis'
|
||||
}));
|
||||
|
||||
var html = '';
|
||||
html += '<audio class="itemAudio" preload="none" controls autoplay>';
|
||||
html += '<source type="audio/mpeg" src="' + mp3Url + '">';
|
||||
html += '<source type="audio/aac" src="' + aacUrl + '">';
|
||||
html += '<source type="audio/webm" src="' + webmUrl + '">';
|
||||
html += '<source type="audio/ogg" src="' + oggUrl + '">';
|
||||
html += '</audio';
|
||||
|
||||
var nowPlayingBar = $('#nowPlayingBar').show();
|
||||
|
||||
$('#mediaElement', nowPlayingBar).html(html);
|
||||
|
||||
return $('audio', nowPlayingBar)[0];
|
||||
},
|
||||
|
||||
playVideo: function (items) {
|
||||
|
||||
var item = items[0];
|
||||
|
||||
var screenWidth = Math.max(screen.height, screen.width);
|
||||
var screenHeight = Math.min(screen.height, screen.width);
|
||||
|
||||
var baseParams = {
|
||||
id: item.Id,
|
||||
audioChannels: 2,
|
||||
audioBitrate: 128000,
|
||||
videoBitrate: 500000,
|
||||
maxWidth: screenWidth,
|
||||
maxHeight: screenHeight
|
||||
};
|
||||
|
||||
var tsVideoUrl = ApiClient.getUrl('video.ts', $.extend({}, baseParams, {
|
||||
videoCodec: 'h264',
|
||||
audioCodec: 'aac'
|
||||
}));
|
||||
|
||||
var webmVideoUrl = ApiClient.getUrl('video.webm', $.extend({}, baseParams, {
|
||||
videoCodec: 'vpx',
|
||||
audioCodec: 'Vorbis'
|
||||
}));
|
||||
|
||||
var ogvVideoUrl = ApiClient.getUrl('video.ogv', $.extend({}, baseParams, {
|
||||
videoCodec: 'theora',
|
||||
audioCodec: 'Vorbis'
|
||||
}));
|
||||
|
||||
var html = '';
|
||||
html += '<video class="itemVideo" preload="none" controls autoplay>';
|
||||
html += '<source type=\'video/mp2t; codecs="h264, aac"\' src="' + tsVideoUrl + '">';
|
||||
html += '<source type=\'video/webm; codecs="vp8, vorbis"\' src="' + webmVideoUrl + '">';
|
||||
html += '<source type=\'video/ogg; codecs="theora, vorbis"\' src="' + ogvVideoUrl + '">';
|
||||
html += '</video';
|
||||
|
||||
var nowPlayingBar = $('#nowPlayingBar').show();
|
||||
|
||||
$('#mediaElement', nowPlayingBar).html(html);
|
||||
|
||||
return $('video', nowPlayingBar)[0];
|
||||
},
|
||||
|
||||
stop: function () {
|
||||
|
||||
var elem = MediaPlayer.mediaElement;
|
||||
|
||||
elem.pause();
|
||||
elem.src = "";
|
||||
|
||||
$(elem).remove();
|
||||
|
||||
$('#nowPlayingBar').hide();
|
||||
|
||||
MediaPlayer.mediaElement = null;
|
||||
},
|
||||
|
||||
isPlaying: function() {
|
||||
return MediaPlayer.mediaElement;
|
||||
}
|
||||
};
|
103
Html/scripts/MetadataConfigurationPage.js
Normal file
@ -0,0 +1,103 @@
|
||||
var MetadataConfigurationPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var page = this;
|
||||
|
||||
var config;
|
||||
var allCultures;
|
||||
var allCountries;
|
||||
|
||||
ApiClient.getServerConfiguration().done(function (result) {
|
||||
|
||||
config = result;
|
||||
MetadataConfigurationPage.load(page, config, allCultures, allCountries);
|
||||
});
|
||||
|
||||
ApiClient.getCultures().done(function (result) {
|
||||
|
||||
MetadataConfigurationPage.populateLanguages(result);
|
||||
|
||||
allCultures = result;
|
||||
MetadataConfigurationPage.load(page, config, allCultures, allCountries);
|
||||
});
|
||||
|
||||
ApiClient.getCountries().done(function (result) {
|
||||
|
||||
MetadataConfigurationPage.populateCountries(result);
|
||||
|
||||
allCountries = result;
|
||||
MetadataConfigurationPage.load(page, config, allCultures, allCountries);
|
||||
});
|
||||
},
|
||||
|
||||
load: function (page, config, allCultures, allCountries) {
|
||||
|
||||
if (!config || !allCultures || !allCountries) {
|
||||
return;
|
||||
}
|
||||
|
||||
$('#chkEnableInternetProviders', page).checked(config.EnableInternetProviders).checkboxradio("refresh");
|
||||
$('#chkSaveLocal', page).checked(config.SaveLocalMeta).checkboxradio("refresh");
|
||||
$('#txtRefreshDays', page).val(config.MetadataRefreshDays);
|
||||
$('#selectLanguage', page).val(config.PreferredMetadataLanguage).selectmenu("refresh");
|
||||
$('#selectCountry', page).val(config.MetadataCountryCode).selectmenu("refresh");
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
},
|
||||
|
||||
populateCountries: function (allCountries) {
|
||||
|
||||
var html = "";
|
||||
|
||||
html += "<option value=''>None</option>";
|
||||
|
||||
for (var i = 0, length = allCountries.length; i < length; i++) {
|
||||
|
||||
var culture = allCountries[i];
|
||||
|
||||
html += "<option value='" + culture.TwoLetterISORegionName + "'>" + culture.DisplayName + "</option>";
|
||||
}
|
||||
|
||||
$('#selectCountry', '#metadataConfigurationPage').html(html).selectmenu("refresh");
|
||||
},
|
||||
|
||||
populateLanguages: function (allCultures) {
|
||||
|
||||
var html = "";
|
||||
|
||||
html += "<option value=''>None</option>";
|
||||
|
||||
for (var i = 0, length = allCultures.length; i < length; i++) {
|
||||
|
||||
var culture = allCultures[i];
|
||||
|
||||
html += "<option value='" + culture.TwoLetterISOLanguageName + "'>" + culture.DisplayName + "</option>";
|
||||
}
|
||||
|
||||
$('#selectLanguage', '#metadataConfigurationPage').html(html).selectmenu("refresh");
|
||||
},
|
||||
|
||||
onSubmit: function () {
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var form = this;
|
||||
|
||||
ApiClient.getServerConfiguration().done(function (config) {
|
||||
|
||||
config.EnableInternetProviders = $('#chkEnableInternetProviders', form).checked();
|
||||
config.SaveLocalMeta = $('#chkSaveLocal', form).checked();
|
||||
config.MetadataRefreshDays = $('#txtRefreshDays', form).val();
|
||||
config.PreferredMetadataLanguage = $('#selectLanguage', form).val();
|
||||
config.MetadataCountryCode = $('#selectCountry', form).val();
|
||||
|
||||
ApiClient.updateServerConfiguration(config).done(Dashboard.processServerConfigurationUpdateResult);
|
||||
});
|
||||
|
||||
// Disable default form submission
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#metadataConfigurationPage", MetadataConfigurationPage.onPageShow);
|
74
Html/scripts/MetadataImagesPage.js
Normal file
@ -0,0 +1,74 @@
|
||||
var MetadataImagesPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var page = this;
|
||||
|
||||
ApiClient.getServerConfiguration().done(function(result) {
|
||||
MetadataImagesPage.load(page, result);
|
||||
});
|
||||
},
|
||||
|
||||
load: function (page, config) {
|
||||
|
||||
$('#selectTmdbPersonImageDownloadSize', page).val(config.TmdbFetchedProfileSize).selectmenu("refresh");
|
||||
$('#selectTmdbPosterDownloadSize', page).val(config.TmdbFetchedPosterSize).selectmenu("refresh");
|
||||
$('#selectTmdbBackdropDownloadSize', page).val(config.TmdbFetchedBackdropSize).selectmenu("refresh");
|
||||
|
||||
$('#chkRefreshItemImages', page).checked(config.RefreshItemImages).checkboxradio("refresh");
|
||||
$('#txtNumbackdrops', page).val(config.MaxBackdrops);
|
||||
|
||||
$('#chkDownloadMovieArt', page).checked(config.DownloadMovieArt).checkboxradio("refresh");
|
||||
$('#chkDownloadMovieBanner', page).checked(config.DownloadMovieBanner).checkboxradio("refresh");
|
||||
$('#chkDownloadMovieDisc', page).checked(config.DownloadMovieDisc).checkboxradio("refresh");
|
||||
$('#chkDownloadMovieLogo', page).checked(config.DownloadMovieLogo).checkboxradio("refresh");
|
||||
$('#chkDownloadMovieThumb', page).checked(config.DownloadMovieThumb).checkboxradio("refresh");
|
||||
$('#chKDownloadTVArt', page).checked(config.DownloadTVArt).checkboxradio("refresh");
|
||||
$('#chkDownloadTVBanner', page).checked(config.DownloadTVBanner).checkboxradio("refresh");
|
||||
$('#chkDownloadTVLogo', page).checked(config.DownloadTVLogo).checkboxradio("refresh");
|
||||
$('#chkDownloadTVThumb', page).checked(config.DownloadTVThumb).checkboxradio("refresh");
|
||||
$('#chkDownloadSeasonBanner', page).checked(config.DownloadTVSeasonBanner).checkboxradio("refresh");
|
||||
$('#chkDownloadSeasonThumb', page).checked(config.DownloadTVSeasonThumb).checkboxradio("refresh");
|
||||
$('#chkDownloadSeasonBackdrops', page).checked(config.DownloadTVSeasonBackdrops).checkboxradio("refresh");
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
},
|
||||
|
||||
onSubmit: function () {
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var form = this;
|
||||
|
||||
ApiClient.getServerConfiguration().done(function (config) {
|
||||
|
||||
config.TmdbFetchedProfileSize = $('#selectTmdbPersonImageDownloadSize', form).val();
|
||||
config.TmdbFetchedPosterSize = $('#selectTmdbPosterDownloadSize', form).val();
|
||||
config.TmdbFetchedBackdropSize = $('#selectTmdbBackdropDownloadSize', form).val();
|
||||
|
||||
config.RefreshItemImages = $('#chkRefreshItemImages', form).checked();
|
||||
config.MaxBackdrops = $('#txtNumbackdrops', form).val();
|
||||
|
||||
config.DownloadMovieArt = $('#chkDownloadMovieArt', form).checked();
|
||||
config.DownloadMovieBanner = $('#chkDownloadMovieBanner', form).checked();
|
||||
config.DownloadMovieDisc = $('#chkDownloadMovieDisc', form).checked();
|
||||
config.DownloadMovieLogo = $('#chkDownloadMovieLogo', form).checked();
|
||||
config.DownloadMovieThumb = $('#chkDownloadMovieThumb', form).checked();
|
||||
config.DownloadTVArt = $('#chKDownloadTVArt', form).checked();
|
||||
config.DownloadTVBanner = $('#chkDownloadTVBanner', form).checked();
|
||||
config.DownloadTVLogo = $('#chkDownloadTVLogo', form).checked();
|
||||
config.DownloadTVThumb = $('#chkDownloadTVThumb', form).checked();
|
||||
config.DownloadTVSeasonBanner = $('#chkDownloadSeasonBanner', form).checked();
|
||||
config.DownloadTVSeasonThumb = $('#chkDownloadSeasonThumb', form).checked();
|
||||
config.DownloadTVSeasonBackdrops = $('#chkDownloadSeasonBackdrops', form).checked();
|
||||
|
||||
ApiClient.updateServerConfiguration(config).done(Dashboard.processServerConfigurationUpdateResult);
|
||||
});
|
||||
|
||||
// Disable default form submission
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#metadataImagesConfigurationPage", MetadataImagesPage.onPageShow);
|
80
Html/scripts/PluginCatalogPage.js
Normal file
@ -0,0 +1,80 @@
|
||||
var PluginCatalogPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
PluginCatalogPage.reloadList();
|
||||
},
|
||||
|
||||
reloadList: function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var promise1 = ApiClient.getAvailablePlugins();
|
||||
|
||||
var promise2 = ApiClient.getInstalledPlugins();
|
||||
|
||||
$.when(promise1, promise2).done(function (response1, response2) {
|
||||
|
||||
PluginCatalogPage.populateList(response1[0], response2[0]);
|
||||
});
|
||||
},
|
||||
|
||||
populateList: function (availablePlugins, installedPlugins) {
|
||||
|
||||
var page = $($.mobile.activePage);
|
||||
|
||||
availablePlugins = availablePlugins.filter(function (p) {
|
||||
|
||||
return p.type == "UserInstalled";
|
||||
|
||||
}).sort(function (a, b) {
|
||||
|
||||
return a.name > b.name ? 1 : -1;
|
||||
|
||||
});
|
||||
|
||||
var html = "";
|
||||
|
||||
for (var i = 0, length = availablePlugins.length; i < length; i++) {
|
||||
|
||||
var plugin = availablePlugins[i];
|
||||
|
||||
html += "<div class='posterViewItem'><a href='addPlugin.html?name=" + encodeURIComponent(plugin.name) + "'>";
|
||||
|
||||
if (plugin.thumbImage) {
|
||||
html += "<img src='" + plugin.thumbImage + "' />";
|
||||
} else {
|
||||
html += "<img style='background:#444444;' src='css/images/defaultCollectionImage.png' />";
|
||||
}
|
||||
|
||||
if (plugin.isPremium) {
|
||||
html += "<div class='premiumBanner'><img src='css/images/premiumflag.png' /></div>";
|
||||
}
|
||||
|
||||
var color = plugin.tileColor || Dashboard.getRandomMetroColor();
|
||||
|
||||
html += "<div class='posterViewItemText' style='background:" + color + "'>";
|
||||
|
||||
var installedPlugin = installedPlugins.filter(function (ip) {
|
||||
return ip.Name == plugin.name;
|
||||
})[0];
|
||||
|
||||
if (installedPlugin) {
|
||||
|
||||
html += plugin.name + " (Installed)";
|
||||
} else {
|
||||
html += plugin.name;
|
||||
}
|
||||
|
||||
html += "</div>";
|
||||
|
||||
html += "</a></div>";
|
||||
|
||||
}
|
||||
|
||||
$('#pluginTiles', page).html(html);
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#pluginCatalogPage", PluginCatalogPage.onPageShow);
|
109
Html/scripts/PluginUpdatesPage.js
Normal file
@ -0,0 +1,109 @@
|
||||
var PluginUpdatesPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
$('.liPluginUpdate', this).remove();
|
||||
|
||||
ApiClient.getInstalledPlugins().done(PluginUpdatesPage.loadPlugins);
|
||||
|
||||
},
|
||||
|
||||
loadPlugins: function (plugins) {
|
||||
|
||||
plugins = plugins.filter(function (p) {
|
||||
|
||||
return !p.IsCorePlugin;
|
||||
});
|
||||
|
||||
var elem = $('#tbodyPluginUpdates', $.mobile.activePage).html('');
|
||||
|
||||
for (var i = 0, length = plugins.length; i < length; i++) {
|
||||
|
||||
PluginUpdatesPage.addPlugin(plugins[i], i, elem);
|
||||
|
||||
}
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
},
|
||||
|
||||
addPlugin: function (plugin, fieldIndex, elem) {
|
||||
|
||||
var html = "";
|
||||
|
||||
html += "<tr>";
|
||||
|
||||
html += "<td><h3>" + plugin.Name + "</h3></td>";
|
||||
|
||||
var fieldId = "liPluginUpdateFielda" + fieldIndex;
|
||||
|
||||
var options = PluginUpdatesPage.getHtmlOptions(["Off", "On"], (plugin.EnableAutoUpdate ? "On" : "Off"));
|
||||
|
||||
html += "<td>";
|
||||
html += "<select data-uniqueid='" + plugin.UniqueId + "' onchange='PluginUpdatesPage.setAutoUpdate(this);' data-role='slider' id='" + fieldId + "' name='" + fieldId + "'>" + options + "</select>";
|
||||
html += "</td>";
|
||||
|
||||
fieldId = "liPluginUpdateFieldb" + fieldIndex;
|
||||
|
||||
options = PluginUpdatesPage.getHtmlOptions(["Release", "Beta", "Dev"], plugin.UpdateClass);
|
||||
|
||||
html += "<td>";
|
||||
html += "<select data-uniqueid='" + plugin.UniqueId + "' onchange='PluginUpdatesPage.setUpdateClass(this);' data-inline='true' id='" + fieldId + "' name='" + fieldId + "'>" + options + "</select>";
|
||||
html += "</td>";
|
||||
|
||||
html += "</tr>";
|
||||
|
||||
elem.append(html).trigger('create');
|
||||
},
|
||||
|
||||
getHtmlOptions: function (names, selectedValue) {
|
||||
|
||||
var html = "";
|
||||
|
||||
for (var i = 0, length = names.length; i < length; i++) {
|
||||
|
||||
var name = names[i];
|
||||
|
||||
if (name == selectedValue) {
|
||||
html += '<option value="' + name + '" selected="selected">' + name + '</option>';
|
||||
} else {
|
||||
html += '<option value="' + name + '">' + name + '</option>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return html;
|
||||
|
||||
},
|
||||
|
||||
setAutoUpdate: function (select) {
|
||||
|
||||
var id = $(select).attr('data-uniqueid');
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.getPluginConfiguration(id).done(function (config) {
|
||||
|
||||
config.EnableAutoUpdate = select.selectedIndex === 1;
|
||||
|
||||
ApiClient.updatePluginConfiguration(id, config).done(Dashboard.hideLoadingMsg);
|
||||
});
|
||||
},
|
||||
|
||||
setUpdateClass: function (select) {
|
||||
|
||||
var id = $(select).attr('data-uniqueid');
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.getPluginConfiguration(id).done(function (config) {
|
||||
|
||||
config.UpdateClass = select.value;
|
||||
|
||||
ApiClient.updatePluginConfiguration(id, config).done(Dashboard.hideLoadingMsg);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#pluginUpdatesPage", PluginUpdatesPage.onPageShow);
|
92
Html/scripts/PluginsPage.js
Normal file
@ -0,0 +1,92 @@
|
||||
var PluginsPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
PluginsPage.reloadList();
|
||||
},
|
||||
|
||||
reloadList: function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var promise1 = ApiClient.getInstalledPlugins();
|
||||
|
||||
var promise2 = $.getJSON("configurationpages?pageType=PluginConfiguration");
|
||||
|
||||
$.when(promise1, promise2).done(function(response1, response2) {
|
||||
|
||||
PluginsPage.populateList(response1[0], response2[0]);
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
populateList: function (plugins, pluginConfigurationPages) {
|
||||
|
||||
var page = $($.mobile.activePage);
|
||||
|
||||
plugins = plugins.sort(function (plugin1, plugin2) {
|
||||
|
||||
return (plugin1.IsCorePlugin.toString() + plugin1.Name) > (plugin2.IsCorePlugin.toString() + plugin2.Name) ? 1 : -1;
|
||||
|
||||
});
|
||||
|
||||
var html = "";
|
||||
|
||||
for (var i = 0, length = plugins.length; i < length; i++) {
|
||||
|
||||
var plugin = plugins[i];
|
||||
|
||||
if (plugin.IsCorePlugin) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var configPage = $.grep(pluginConfigurationPages, function (pluginConfigurationPage) {
|
||||
return pluginConfigurationPage.OwnerPluginName == plugin.Name;
|
||||
})[0];
|
||||
|
||||
html += "<li>";
|
||||
|
||||
var href = configPage ? Dashboard.getConfigurationPageUrl(configPage.Name) : "#";
|
||||
|
||||
html += "<a href='" + href + "'>";
|
||||
|
||||
html += "<h3>" + plugin.Name + "</h3>";
|
||||
|
||||
html += "<p><strong>" + plugin.Version + "</strong></p>";
|
||||
|
||||
html += "</a>";
|
||||
|
||||
if (!plugin.IsCorePlugin) {
|
||||
html += "<a data-uniqueid='" + plugin.UniqueId + "' data-pluginname='" + plugin.Name + "' onclick='PluginsPage.deletePlugin(this);' href='#'>Delete</a>";
|
||||
}
|
||||
|
||||
html += "</li>";
|
||||
}
|
||||
|
||||
$('#ulInstalledPlugins', page).html(html).listview('refresh');
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
},
|
||||
|
||||
deletePlugin: function (link) {
|
||||
|
||||
var name = link.getAttribute('data-pluginname');
|
||||
var uniqueid = link.getAttribute('data-uniqueid');
|
||||
|
||||
var msg = "Are you sure you wish to uninstall " + name + "?";
|
||||
|
||||
Dashboard.confirm(msg, "Uninstall Plugin", function (result) {
|
||||
|
||||
if (result) {
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.uninstallPlugin(uniqueid).done(function () {
|
||||
|
||||
PluginsPage.reloadList();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#pluginsPage", PluginsPage.onPageShow);
|
294
Html/scripts/ScheduledTaskPage.js
Normal file
@ -0,0 +1,294 @@
|
||||
var ScheduledTaskPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
|
||||
ScheduledTaskPage.refreshScheduledTask();
|
||||
},
|
||||
|
||||
refreshScheduledTask: function () {
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var id = getParameterByName('id');
|
||||
|
||||
|
||||
ApiClient.getScheduledTask(id).done(ScheduledTaskPage.loadScheduledTask);
|
||||
},
|
||||
|
||||
loadScheduledTask: function (task) {
|
||||
|
||||
Dashboard.setPageTitle(task.Name);
|
||||
|
||||
$('#pTaskDescription', $.mobile.activePage).html(task.Description);
|
||||
|
||||
ScheduledTaskPage.loadTaskTriggers(task);
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
},
|
||||
|
||||
loadTaskTriggers: function (task) {
|
||||
|
||||
var html = '';
|
||||
|
||||
html += '<li data-role="list-divider"><h3>Task Triggers</h3></li>';
|
||||
|
||||
for (var i = 0, length = task.Triggers.length; i < length; i++) {
|
||||
|
||||
var trigger = task.Triggers[i];
|
||||
|
||||
html += '<li>';
|
||||
|
||||
html += '<a href="#">';
|
||||
html += ScheduledTaskPage.getTriggerFriendlyName(trigger);
|
||||
html += '</a>';
|
||||
|
||||
html += '<a href="#" onclick="ScheduledTaskPage.confirmDeleteTrigger(' + i + ');">Delete</a>';
|
||||
|
||||
html += '</li>';
|
||||
}
|
||||
|
||||
$('#ulTaskTriggers', $.mobile.activePage).html(html).listview('refresh');
|
||||
},
|
||||
|
||||
getTriggerFriendlyName: function (trigger) {
|
||||
|
||||
if (trigger.Type == 'DailyTrigger') {
|
||||
return 'Daily at ' + ScheduledTaskPage.getDisplayTime(trigger.TimeOfDayTicks);
|
||||
}
|
||||
|
||||
if (trigger.Type == 'WeeklyTrigger') {
|
||||
|
||||
return trigger.DayOfWeek + 's at ' + ScheduledTaskPage.getDisplayTime(trigger.TimeOfDayTicks);
|
||||
}
|
||||
|
||||
if (trigger.Type == 'SystemEventTrigger') {
|
||||
|
||||
if (trigger.SystemEvent == 'WakeFromSleep') {
|
||||
return 'On wake from sleep';
|
||||
}
|
||||
}
|
||||
|
||||
if (trigger.Type == 'IntervalTrigger') {
|
||||
|
||||
var hours = trigger.IntervalTicks / 36000000000;
|
||||
|
||||
if (hours == .25) {
|
||||
return "Every 15 minutes";
|
||||
}
|
||||
if (hours == .5) {
|
||||
return "Every 30 minutes";
|
||||
}
|
||||
if (hours == .75) {
|
||||
return "Every 45 minutes";
|
||||
}
|
||||
if (hours == 1) {
|
||||
return "Every hour";
|
||||
}
|
||||
|
||||
return 'Every ' + hours + ' hours';
|
||||
}
|
||||
|
||||
if (trigger.Type == 'StartupTrigger') {
|
||||
return 'On application startup';
|
||||
}
|
||||
|
||||
return trigger.Type;
|
||||
},
|
||||
|
||||
getDisplayTime: function (ticks) {
|
||||
|
||||
var hours = ticks / 36000000000;
|
||||
|
||||
if (hours < 1) {
|
||||
hours = 0;
|
||||
}
|
||||
|
||||
hours = parseInt(hours);
|
||||
|
||||
ticks -= (hours * 36000000000);
|
||||
|
||||
var minutes = parseInt(ticks / 600000000);
|
||||
|
||||
var suffix = "am";
|
||||
|
||||
if (hours > 11) {
|
||||
suffix = "pm";
|
||||
}
|
||||
|
||||
hours = hours % 12;
|
||||
|
||||
if (hours == 0) {
|
||||
hours = 12;
|
||||
}
|
||||
|
||||
if (minutes < 10) {
|
||||
minutes = '0' + minutes;
|
||||
}
|
||||
|
||||
return hours + ':' + minutes + ' ' + suffix;
|
||||
},
|
||||
|
||||
showAddTriggerPopup: function () {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
$('#selectTriggerType', page).val('DailyTrigger').trigger('change').selectmenu('refresh');
|
||||
|
||||
$('#popupAddTrigger', page).popup("open").on("popupafterclose", function () {
|
||||
|
||||
$('#addTriggerForm', page).off("submit");
|
||||
$(this).off("popupafterclose");
|
||||
});
|
||||
|
||||
$('#addTriggerForm', page).on('submit', function () {
|
||||
|
||||
ScheduledTaskPage.addTrigger();
|
||||
|
||||
return false;
|
||||
});
|
||||
},
|
||||
|
||||
addTrigger: function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var id = getParameterByName('id');
|
||||
|
||||
ApiClient.getScheduledTask(id).done(function (task) {
|
||||
|
||||
task.Triggers.push(ScheduledTaskPage.getTriggerToAdd());
|
||||
|
||||
ApiClient.updateScheduledTaskTriggers(task.Id, task.Triggers).done(function () {
|
||||
|
||||
$('#popupAddTrigger').popup('close');
|
||||
|
||||
ScheduledTaskPage.refreshScheduledTask();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
confirmDeleteTrigger: function (index) {
|
||||
|
||||
Dashboard.confirm("Are you sure you wish to delete this task trigger?", "Delete Task Trigger", function (result) {
|
||||
|
||||
if (result) {
|
||||
ScheduledTaskPage.deleteTrigger(index);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
deleteTrigger: function (index) {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var id = getParameterByName('id');
|
||||
|
||||
|
||||
ApiClient.getScheduledTask(id).done(function (task) {
|
||||
|
||||
task.Triggers.remove(index);
|
||||
|
||||
ApiClient.updateScheduledTaskTriggers(task.Id, task.Triggers).done(function () {
|
||||
|
||||
ScheduledTaskPage.refreshScheduledTask();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
refreshTriggerFields: function (triggerType) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
if (triggerType == 'DailyTrigger') {
|
||||
|
||||
$('#fldTimeOfDay', page).show();
|
||||
$('#fldDayOfWeek', page).hide();
|
||||
$('#fldSelectSystemEvent', page).hide();
|
||||
$('#fldSelectInterval', page).hide();
|
||||
$('#txtTimeOfDay', page).attr('required', 'required');
|
||||
}
|
||||
|
||||
else if (triggerType == 'WeeklyTrigger') {
|
||||
$('#fldTimeOfDay', page).show();
|
||||
$('#fldDayOfWeek', page).show();
|
||||
$('#fldSelectSystemEvent', page).hide();
|
||||
$('#fldSelectInterval', page).hide();
|
||||
$('#txtTimeOfDay', page).attr('required', 'required');
|
||||
}
|
||||
|
||||
else if (triggerType == 'SystemEventTrigger') {
|
||||
$('#fldTimeOfDay', page).hide();
|
||||
$('#fldDayOfWeek', page).hide();
|
||||
$('#fldSelectSystemEvent', page).show();
|
||||
$('#fldSelectInterval', page).hide();
|
||||
$('#txtTimeOfDay', page).removeAttr('required');
|
||||
}
|
||||
|
||||
else if (triggerType == 'IntervalTrigger') {
|
||||
$('#fldTimeOfDay', page).hide();
|
||||
$('#fldDayOfWeek', page).hide();
|
||||
$('#fldSelectSystemEvent', page).hide();
|
||||
$('#fldSelectInterval', page).show();
|
||||
$('#txtTimeOfDay', page).removeAttr('required');
|
||||
}
|
||||
|
||||
else if (triggerType == 'StartupTrigger') {
|
||||
$('#fldTimeOfDay', page).hide();
|
||||
$('#fldDayOfWeek', page).hide();
|
||||
$('#fldSelectSystemEvent', page).hide();
|
||||
$('#fldSelectInterval', page).hide();
|
||||
$('#txtTimeOfDay', page).removeAttr('required');
|
||||
}
|
||||
},
|
||||
|
||||
getTriggerToAdd: function () {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
var trigger = {
|
||||
Type: $('#selectTriggerType', page).val()
|
||||
};
|
||||
|
||||
if (trigger.Type == 'DailyTrigger') {
|
||||
trigger.TimeOfDayTicks = ScheduledTaskPage.getTimeOfDayTicks($('#txtTimeOfDay', page).val());
|
||||
}
|
||||
|
||||
else if (trigger.Type == 'WeeklyTrigger') {
|
||||
trigger.DayOfWeek = $('#selectDayOfWeek', page).val();
|
||||
trigger.TimeOfDayTicks = ScheduledTaskPage.getTimeOfDayTicks($('#txtTimeOfDay', page).val());
|
||||
}
|
||||
|
||||
else if (trigger.Type == 'SystemEventTrigger') {
|
||||
trigger.SystemEvent = $('#selectSystemEvent', page).val();
|
||||
}
|
||||
|
||||
else if (trigger.Type == 'IntervalTrigger') {
|
||||
trigger.IntervalTicks = $('#selectInterval', page).val();
|
||||
}
|
||||
|
||||
return trigger;
|
||||
},
|
||||
|
||||
getTimeOfDayTicks: function (val) {
|
||||
|
||||
var vals = val.split(':');
|
||||
|
||||
var hours = vals[0];
|
||||
var minutes = vals[1];
|
||||
|
||||
// Add hours
|
||||
var ticks = hours * 60 * 60 * 1000 * 10000;
|
||||
|
||||
ticks += minutes * 60 * 1000 * 10000;
|
||||
|
||||
return ticks;
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#scheduledTaskPage", ScheduledTaskPage.onPageShow);
|
170
Html/scripts/ScheduledTasksPage.js
Normal file
@ -0,0 +1,170 @@
|
||||
var ScheduledTasksPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ScheduledTasksPage.reloadList(true);
|
||||
|
||||
$(document).on("websocketmessage", ScheduledTasksPage.onWebSocketMessage).on("websocketopen", ScheduledTasksPage.onWebSocketConnectionChange).on("websocketerror", ScheduledTasksPage.onWebSocketConnectionChange).on("websocketclose", ScheduledTasksPage.onWebSocketConnectionChange);
|
||||
},
|
||||
|
||||
onPageHide: function () {
|
||||
$(document).off("websocketmessage", ScheduledTasksPage.onWebSocketMessage).off("websocketopen", ScheduledTasksPage.onWebSocketConnectionChange).off("websocketerror", ScheduledTasksPage.onWebSocketConnectionChange).off("websocketclose", ScheduledTasksPage.onWebSocketConnectionChange);
|
||||
ScheduledTasksPage.stopInterval();
|
||||
},
|
||||
|
||||
startInterval: function () {
|
||||
|
||||
if (Dashboard.isWebSocketOpen()) {
|
||||
Dashboard.sendWebSocketMessage("ScheduledTasksInfoStart", "1500,1500");
|
||||
}
|
||||
},
|
||||
|
||||
stopInterval: function () {
|
||||
|
||||
if (Dashboard.isWebSocketOpen()) {
|
||||
Dashboard.sendWebSocketMessage("ScheduledTasksInfoStop");
|
||||
}
|
||||
},
|
||||
|
||||
onWebSocketMessage: function (e, msg) {
|
||||
|
||||
if (msg.MessageType == "ScheduledTasksInfo") {
|
||||
ScheduledTasksPage.populateList(msg.Data);
|
||||
}
|
||||
},
|
||||
|
||||
onWebSocketConnectionChange: function() {
|
||||
ScheduledTasksPage.reloadList(true);
|
||||
},
|
||||
|
||||
reloadList: function (updateInterval) {
|
||||
|
||||
if (updateInterval) {
|
||||
ScheduledTasksPage.stopInterval();
|
||||
}
|
||||
|
||||
ApiClient.getScheduledTasks().done(function (tasks) {
|
||||
ScheduledTasksPage.populateList(tasks);
|
||||
Dashboard.hideLoadingMsg();
|
||||
|
||||
if (updateInterval) {
|
||||
ScheduledTasksPage.startInterval();
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
populateList: function (tasks) {
|
||||
|
||||
tasks = tasks.sort(function (a, b) {
|
||||
|
||||
a = a.Category + " " + a.Name;
|
||||
b = b.Category + " " + b.Name;
|
||||
|
||||
if (a == b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a < b) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
});
|
||||
|
||||
var page = $($.mobile.activePage);
|
||||
|
||||
var html = "";
|
||||
|
||||
var currentCategory;
|
||||
|
||||
for (var i = 0, length = tasks.length; i < length; i++) {
|
||||
|
||||
var task = tasks[i];
|
||||
|
||||
if (task.Category != currentCategory) {
|
||||
currentCategory = task.Category;
|
||||
|
||||
html += "<li data-role='list-divider'>" + currentCategory + "</li>";
|
||||
}
|
||||
|
||||
html += "<li>";
|
||||
|
||||
html += "<a href='scheduledTask.html?id=" + task.Id + "'>";
|
||||
|
||||
html += "<h3>" + task.Name + "</h3>";
|
||||
|
||||
if (task.State == "Idle") {
|
||||
|
||||
if (task.LastExecutionResult) {
|
||||
|
||||
var text = "Last run " + humane_date(task.LastExecutionResult.EndTimeUtc) + ', taking ' + humane_elapsed(task.LastExecutionResult.StartTimeUtc, task.LastExecutionResult.EndTimeUtc);
|
||||
|
||||
if (task.LastExecutionResult.Status == "Failed") {
|
||||
text += " <span style='color:#FF0000;'>(failed)</span>";
|
||||
}
|
||||
else if (task.LastExecutionResult.Status == "Cancelled") {
|
||||
text += " <span style='color:#0026FF;'>(cancelled)</span>";
|
||||
}
|
||||
else if (task.LastExecutionResult.Status == "Aborted") {
|
||||
text += " <span style='color:#FF0000;'>(Aborted by server shutdown)</span>";
|
||||
}
|
||||
|
||||
html += "<p>" + text + "</p>";
|
||||
}
|
||||
|
||||
html += "<a href='#' data-icon='play' onclick='ScheduledTasksPage.startTask(\"" + task.Id + "\");'>Start</a>";
|
||||
}
|
||||
else if (task.State == "Running") {
|
||||
|
||||
var progress = task.CurrentProgress || { PercentComplete: 0 };
|
||||
progress = Math.round(progress.PercentComplete);
|
||||
|
||||
html += '<p><progress max="100" value="' + progress + '" title="' + progress + '%">';
|
||||
html += '' + progress + '%';
|
||||
html += '</progress>';
|
||||
|
||||
html += "<span style='color:#009F00;margin-left:5px;'>" + progress + "%</span>";
|
||||
html += '</p>';
|
||||
|
||||
html += "<a href='#' data-icon='stop' onclick='ScheduledTasksPage.stopTask(\"" + task.Id + "\");'>Stop</a>";
|
||||
|
||||
} else {
|
||||
|
||||
html += "<p style='color:#FF0000;'>Stopping</p>";
|
||||
html += "<a href='#' data-icon='play' style='visibility:hidden;'>Start</a>";
|
||||
}
|
||||
|
||||
html += "</a>";
|
||||
|
||||
html += "</li>";
|
||||
}
|
||||
|
||||
$('#ulScheduledTasks', page).html(html).listview('refresh');
|
||||
},
|
||||
|
||||
startTask: function (id) {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.startScheduledTask(id).done(function (result) {
|
||||
|
||||
ScheduledTasksPage.reloadList();
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
stopTask: function (id) {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.stopScheduledTask(id).done(function (result) {
|
||||
|
||||
ScheduledTasksPage.reloadList();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#scheduledTasksPage", ScheduledTasksPage.onPageShow).on('pagehide', "#scheduledTasksPage", ScheduledTasksPage.onPageHide);
|
79
Html/scripts/SupporterKeyPage.js
Normal file
@ -0,0 +1,79 @@
|
||||
var SupporterKeyPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
SupporterKeyPage.load();
|
||||
},
|
||||
|
||||
onPageHide: function () {
|
||||
|
||||
},
|
||||
|
||||
load: function() {
|
||||
Dashboard.showLoadingMsg();
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
ApiClient.getPluginSecurityInfo().done(function (info) {
|
||||
$('#txtSupporterKey', page).val(info.SupporterKey);
|
||||
$('#txtLegacyKey', page).val(info.LegacyKey);
|
||||
if (info.IsMBSupporter) {
|
||||
$('.supporterOnly', page).show();
|
||||
} else {
|
||||
$('.supporterOnly', page).hide();
|
||||
}
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
},
|
||||
|
||||
updateSupporterKey: function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
var key = $('#txtSupporterKey', page).val();
|
||||
var legacyKey = $('#txtLegacyKey', page).val();
|
||||
|
||||
var info = {
|
||||
SupporterKey: key,
|
||||
LegacyKey: legacyKey
|
||||
};
|
||||
|
||||
var url = ApiClient.getUrl("Plugins/SecurityInfo");
|
||||
console.log(url);
|
||||
$.post(url, JSON.stringify(info)).done(function () {
|
||||
Dashboard.resetPluginSecurityInfo();
|
||||
Dashboard.hideLoadingMsg();
|
||||
SupporterPage.load();
|
||||
|
||||
});
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
retrieveSupporterKey: function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
var email = $('#txtEmail', page).val();
|
||||
|
||||
var url = "http://mb3admin.com/admin/service/supporter/retrievekey?email="+email;
|
||||
console.log(url);
|
||||
$.post(url).done(function (res) {
|
||||
var result = JSON.parse(res);
|
||||
Dashboard.hideLoadingMsg();
|
||||
if (result.Success) {
|
||||
Dashboard.alert("Key emailed to "+email);
|
||||
} else {
|
||||
Dashboard.showError(result.ErrorMessage);
|
||||
}
|
||||
console.log(result);
|
||||
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#supporterKeyPage", SupporterKeyPage.onPageShow)
|
||||
.on('pagehide', "#supporterKeyPage", SupporterKeyPage.onPageHide);
|
29
Html/scripts/SupporterPage.js
Normal file
@ -0,0 +1,29 @@
|
||||
var SupporterPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
SupporterPage.load();
|
||||
},
|
||||
|
||||
onPageHide: function () {
|
||||
|
||||
},
|
||||
|
||||
load: function() {
|
||||
Dashboard.showLoadingMsg();
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
ApiClient.getPluginSecurityInfo().done(function (info) {
|
||||
$('#txtSupporterKey', page).val(info.SupporterKey);
|
||||
if (info.IsMBSupporter) {
|
||||
$('.supporterOnly', page).show();
|
||||
} else {
|
||||
$('.supporterOnly', page).hide();
|
||||
}
|
||||
$('#paypalReturnUrl', page).val(ApiClient.getCustomUrl("dashboard/supporterKey.html"));
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#supporterPage", SupporterPage.onPageShow)
|
||||
.on('pagehide', "#supporterPage", SupporterPage.onPageHide);
|
88
Html/scripts/UpdatePasswordPage.js
Normal file
@ -0,0 +1,88 @@
|
||||
var UpdatePasswordPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
UpdatePasswordPage.loadUser();
|
||||
},
|
||||
|
||||
loadUser: function() {
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
var userid = getParameterByName("userId");
|
||||
|
||||
ApiClient.getUser(userid).done(function (user) {
|
||||
|
||||
Dashboard.setPageTitle(user.Name);
|
||||
|
||||
if (user.HasPassword) {
|
||||
$('#btnResetPassword', page).show();
|
||||
} else {
|
||||
$('#btnResetPassword', page).hide();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$('#txtCurrentPassword', page).val('');
|
||||
$('#txtNewPassword', page).val('');
|
||||
$('#txtNewPasswordConfirm', page).val('');
|
||||
},
|
||||
|
||||
save: function () {
|
||||
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
var page = $($.mobile.activePage);
|
||||
var currentPassword = $('#txtCurrentPassword', page).val();
|
||||
var newPassword = $('#txtNewPassword', page).val();
|
||||
|
||||
ApiClient.updateUserPassword(userId, currentPassword, newPassword).done(UpdatePasswordPage.saveComplete);
|
||||
},
|
||||
|
||||
saveComplete: function () {
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
|
||||
Dashboard.alert("Password saved.");
|
||||
UpdatePasswordPage.loadUser();
|
||||
},
|
||||
|
||||
resetPassword: function () {
|
||||
|
||||
var msg = "Are you sure you wish to reset the password?";
|
||||
|
||||
Dashboard.confirm(msg, "Password Reset", function (result) {
|
||||
|
||||
if (result) {
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.resetUserPassword(userId).done(function () {
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
Dashboard.alert("The password has been reset.");
|
||||
UpdatePasswordPage.loadUser();
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onSubmit: function () {
|
||||
var page = $($.mobile.activePage);
|
||||
|
||||
if ($('#txtNewPassword', page).val() != $('#txtNewPasswordConfirm', page).val()) {
|
||||
|
||||
Dashboard.showError("Password and password confirmation must match.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
UpdatePasswordPage.save();
|
||||
|
||||
// Disable default form submission
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#updatePasswordPage", UpdatePasswordPage.onPageShow);
|
181
Html/scripts/UserImagePage.js
Normal file
@ -0,0 +1,181 @@
|
||||
var UserImagePage = {
|
||||
|
||||
onPageShow: function () {
|
||||
|
||||
UserImagePage.reloadUser();
|
||||
|
||||
$("#userImageDropZone", this).on('dragover', UserImagePage.onImageDragOver).on('drop', UserImagePage.onImageDrop);
|
||||
},
|
||||
|
||||
onPageHide: function () {
|
||||
$("#userImageDropZone", this).off('dragover', UserImagePage.onImageDragOver).off('drop', UserImagePage.onImageDrop);
|
||||
},
|
||||
|
||||
reloadUser: function () {
|
||||
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.getUser(userId).done(function (user) {
|
||||
|
||||
var page = $($.mobile.activePage);
|
||||
|
||||
$('#uploadUserImage', page).val('').trigger('change');
|
||||
|
||||
Dashboard.setPageTitle(user.Name);
|
||||
|
||||
if (user.PrimaryImageTag) {
|
||||
|
||||
var imageUrl = ApiClient.getUserImageUrl(user.Id, {
|
||||
height: 450,
|
||||
tag: user.PrimaryImageTag,
|
||||
type: "Primary"
|
||||
});
|
||||
|
||||
$('#fldImage', page).show().html('').html("<img height='200px' src='" + imageUrl + "' />");
|
||||
|
||||
$('#fldDeleteImage', page).show();
|
||||
$('#headerUploadNewImage', page).show();
|
||||
} else {
|
||||
$('#fldImage', page).hide().html('');
|
||||
$('#fldDeleteImage', page).hide();
|
||||
$('#headerUploadNewImage', page).hide();
|
||||
}
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
},
|
||||
|
||||
deleteImage: function () {
|
||||
|
||||
Dashboard.confirm("Are you sure you wish to delete the image?", "Delete Image", function (result) {
|
||||
|
||||
if (result) {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
ApiClient.deleteUserImage(userId, "primary").done(UserImagePage.processImageChangeResult);
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
processImageChangeResult: function () {
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
|
||||
Dashboard.validateCurrentUser();
|
||||
UserImagePage.reloadUser();
|
||||
},
|
||||
|
||||
onFileUploadChange: function (fileUpload) {
|
||||
|
||||
UserImagePage.setFiles(fileUpload.files);
|
||||
},
|
||||
|
||||
setFiles: function (files) {
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
var file = files[0];
|
||||
|
||||
if (!file || !file.type.match('image.*')) {
|
||||
$('#userImageOutput', page).html('');
|
||||
$('#fldUpload', page).hide();
|
||||
UserImagePage.currentFile = null;
|
||||
return;
|
||||
}
|
||||
|
||||
UserImagePage.currentFile = file;
|
||||
|
||||
var reader = new FileReader();
|
||||
|
||||
reader.onerror = UserImagePage.onFileReaderError;
|
||||
reader.onloadstart = UserImagePage.onFileReaderOnloadStart;
|
||||
reader.onabort = UserImagePage.onFileReaderAbort;
|
||||
|
||||
// Closure to capture the file information.
|
||||
reader.onload = (function (theFile) {
|
||||
return function (e) {
|
||||
|
||||
// Render thumbnail.
|
||||
var html = ['<img style="max-width:500px;max-height:200px;" src="', e.target.result, '" title="', escape(theFile.name), '"/>'].join('');
|
||||
|
||||
$('#userImageOutput', page).html(html);
|
||||
$('#fldUpload', page).show();
|
||||
};
|
||||
})(file);
|
||||
|
||||
// Read in the image file as a data URL.
|
||||
reader.readAsDataURL(file);
|
||||
},
|
||||
|
||||
onFileReaderError: function (evt) {
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
|
||||
switch (evt.target.error.code) {
|
||||
case evt.target.error.NOT_FOUND_ERR:
|
||||
Dashboard.showError('File Not Found!');
|
||||
break;
|
||||
case evt.target.error.NOT_READABLE_ERR:
|
||||
Dashboard.showError('File is not readable');
|
||||
break;
|
||||
case evt.target.error.ABORT_ERR:
|
||||
break; // noop
|
||||
default:
|
||||
Dashboard.showError('An error occurred reading this file.');
|
||||
};
|
||||
},
|
||||
|
||||
onFileReaderOnloadStart: function (evt) {
|
||||
|
||||
$('#fldUpload', $.mobile.activePage).hide();
|
||||
},
|
||||
|
||||
onFileReaderAbort: function (evt) {
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
Dashboard.showError('File read cancelled');
|
||||
},
|
||||
|
||||
onSubmit: function () {
|
||||
|
||||
var file = UserImagePage.currentFile;
|
||||
|
||||
if (!file || !file.type.match('image.*')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var userId = getParameterByName("userId");
|
||||
|
||||
ApiClient.uploadUserImage(userId, 'Primary', file).done(UserImagePage.processImageChangeResult);
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
onImageDrop: function (e) {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
UserImagePage.setFiles(e.originalEvent.dataTransfer.files);
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
onImageDragOver: function (e) {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
e.originalEvent.dataTransfer.dropEffect = 'Copy';
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#userImagePage", UserImagePage.onPageShow).on('pagehide', "#userImagePage", UserImagePage.onPageHide);
|
76
Html/scripts/UserProfilesPage.js
Normal file
@ -0,0 +1,76 @@
|
||||
var UserProfilesPage = {
|
||||
onPageShow: function () {
|
||||
|
||||
UserProfilesPage.loadPageData();
|
||||
},
|
||||
|
||||
loadPageData: function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
ApiClient.getAllUsers().done(UserProfilesPage.renderUsers);
|
||||
},
|
||||
|
||||
renderUsers: function (users) {
|
||||
|
||||
var html = "";
|
||||
|
||||
html += '<li data-role="list-divider"><h3>Users</h3></li>';
|
||||
|
||||
for (var i = 0, length = users.length; i < length; i++) {
|
||||
|
||||
var user = users[i];
|
||||
|
||||
html += "<li>";
|
||||
|
||||
html += "<a onclick='Dashboard.navigate(\"editUser.html?userId=" + user.Id + "\");' href='#'>";
|
||||
|
||||
if (user.PrimaryImageTag) {
|
||||
|
||||
var url = ApiClient.getUserImageUrl(user.Id, {
|
||||
width: 225,
|
||||
tag: user.PrimaryImageTag,
|
||||
type: "Primary"
|
||||
});
|
||||
html += "<img src='" + url + "' />";
|
||||
} else {
|
||||
html += "<img src='css/images/userFlyoutDefault.png' />";
|
||||
}
|
||||
|
||||
html += "<h3>" + user.Name + "</h3>";
|
||||
|
||||
html += "</a>";
|
||||
|
||||
html += "<a onclick='UserProfilesPage.deleteUser(this);' data-userid='" + user.Id + "' data-username='" + user.Name + "' href='#'>Delete</a>";
|
||||
|
||||
html += "</li>";
|
||||
}
|
||||
|
||||
$('#ulUserProfiles', $('#userProfilesPage')).html(html).listview('refresh');
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
},
|
||||
|
||||
deleteUser: function (link) {
|
||||
|
||||
var name = link.getAttribute('data-username');
|
||||
|
||||
var msg = "Are you sure you wish to delete " + name + "?";
|
||||
|
||||
Dashboard.confirm(msg, "Delete User", function (result) {
|
||||
|
||||
if (result) {
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var id = link.getAttribute('data-userid');
|
||||
|
||||
ApiClient.deleteUser(id).done(function () {
|
||||
|
||||
Dashboard.validateCurrentUser();
|
||||
UserProfilesPage.loadPageData();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#userProfilesPage", UserProfilesPage.onPageShow);
|
17
Html/scripts/WizardStartPage.js
Normal file
@ -0,0 +1,17 @@
|
||||
var WizardStartPage = {
|
||||
|
||||
gotoNextPage: function () {
|
||||
|
||||
ApiClient.getAllUsers().done(function (users) {
|
||||
|
||||
if (users.length > 1) {
|
||||
|
||||
Dashboard.navigate('wizardLibrary.html');
|
||||
|
||||
} else {
|
||||
Dashboard.navigate('wizardUser.html');
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
};
|
59
Html/scripts/WizardUserPage.js
Normal file
@ -0,0 +1,59 @@
|
||||
var WizardUserPage = {
|
||||
|
||||
onPageShow: function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var page = this;
|
||||
|
||||
ApiClient.getAllUsers().done(function (users) {
|
||||
|
||||
var user = users[0] || { Name: "User" };
|
||||
|
||||
$('#txtUsername', page).val(user.Name);
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
onSubmit: function() {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
ApiClient.getAllUsers().done(function (users) {
|
||||
|
||||
var user;
|
||||
|
||||
if (users.length) {
|
||||
|
||||
user = users[0];
|
||||
|
||||
user.Name = $('#txtUsername', page).val();
|
||||
|
||||
ApiClient.updateUser(user).done(WizardUserPage.saveComplete);
|
||||
|
||||
} else {
|
||||
|
||||
user = { Name: $('#txtUsername', page).val() };
|
||||
|
||||
ApiClient.createUser(user).done(WizardUserPage.saveComplete);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
saveComplete: function () {
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
|
||||
Dashboard.navigate('wizardLibrary.html');
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#wizardUserPage", WizardUserPage.onPageShow);
|
1185
Html/scripts/site.js
Normal file
42
Html/support.html
Normal file
@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Support</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="supportPage" data-role="page" class="page type-interior">
|
||||
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<div class="readOnlyContent">
|
||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
||||
<a href="support.html" data-role="button" class="ui-btn-active">General</a>
|
||||
<a href="log.html" data-role="button">View Log</a>
|
||||
<a href="supporter.html" data-role="button">Become a Supporter</a>
|
||||
<a href="supporterKey.html" data-role="button">Supporter Key</a>
|
||||
</div>
|
||||
<h2>General Help</h2>
|
||||
<p>
|
||||
Media Browser has a thriving community of users and a vast knowledge base of information to help you get the most
|
||||
out of your media collection.
|
||||
</p>
|
||||
<p>
|
||||
The Community Tracker is a place where you can ask questions, post feature requests and report bugs and get timely
|
||||
<em>and friendly</em> help from a thriving community of users and developers.
|
||||
</p>
|
||||
<a data-role="button" data-icon="arrow-r" data-iconpos="right" href="http://community.mediabrowser.tv" target="_blank">Visit the Community Tracker</a>
|
||||
<p>
|
||||
Also, within the tracker, there is a large Knowledge Base of information compiled from users and developers to help you get the
|
||||
most out of Media Browser.
|
||||
</p>
|
||||
<a data-role="button" data-icon="search" data-iconpos="right" href="http://community.mediabrowser.tv/topics?category_id=5&&status=published" target="_blank">Search the Knowledge Base</a>
|
||||
<p>
|
||||
Finally, you can visit the Media Browser Web site to see what's happening with MB now and keep up with the developer blog.
|
||||
</p>
|
||||
<a data-role="button" data-icon="home" data-iconpos="right" href="http://forum.mediabrowser3.com" target="_blank">Visit the Media Browser Web Site</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
69
Html/supporter.html
Normal file
@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Support</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="supporterPage" data-role="page" class="page type-interior">
|
||||
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<div class="readOnlyContent">
|
||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
||||
<a href="support.html" data-role="button">General</a>
|
||||
<a href="log.html" data-role="button">View Log</a>
|
||||
<a href="supporter.html" data-role="button" class="ui-btn-active">Become a Supporter</a>
|
||||
<a href="supporterKey.html" data-role="button">Supporter Key</a>
|
||||
</div>
|
||||
<h2>Support the Media Browser Team</h2>
|
||||
<p>
|
||||
By becoming a Media Browser Supporter, you ensure the continued development and support of this product <strong>and open up a whole new world of premium plug-ins.</strong>
|
||||
</p>
|
||||
<p style="margin-bottom: 30px">
|
||||
A portion of all MB3 Supporter donations is also contributed to some of our metadata providers (<a href="http://themoviedb.org" target="_blank">The Movie Db</a>,
|
||||
<a href="http://thetvdb.com" target="_blank">The TVdb</a>, and <a href="http://fanart.tv" target="_blank">FanArt.tv</a>)
|
||||
</p>
|
||||
<p style="margin-bottom: 30px">
|
||||
Premium plug-ins can be installed and used for their trial periods (14 days on any particular machine) but, to register them for use
|
||||
beyond that period, you also have to be a Media Browser Supporter.
|
||||
|
||||
</p>
|
||||
<div style="display: none; padding: 10px 10px 10px 10px; margin-bottom: 10px" class="ui-bar-e supporterOnly">
|
||||
<p>
|
||||
<strong><em>Thank You</em></strong> for your past support of the Media Browser Team. Users like you make it possible for
|
||||
Media Browser to exist and keep getting better and better. You can always support us again if you feel you are getting maximum
|
||||
value from the product.
|
||||
|
||||
</p>
|
||||
</div>
|
||||
<form name="_xclick" action="https://www.paypal.com/cgi-bin/webscr"
|
||||
method="post">
|
||||
<label for="donateAmt" >Amount (USD)</label>
|
||||
<select id="donateAmt" name="amount" >
|
||||
<option>10</option>
|
||||
<option>15</option>
|
||||
<option>20</option>
|
||||
<option>30</option>
|
||||
<option>50</option>
|
||||
</select>
|
||||
|
||||
<input type="hidden" name="cmd" value="_xclick">
|
||||
<input type="hidden" name="business" value="donate@mediabrowser3.com">
|
||||
<input type="hidden" name="currency_code" value="USD">
|
||||
<input type="hidden" name="item_name" value="Media Browser Supporter">
|
||||
<input type="hidden" name="item_number" value="MBSupporter">
|
||||
<input type="hidden" name="notify_url" value="http://mb3admin.com/admin/service/services/ppipn.php">
|
||||
<input type="hidden" name="return" id ="paypalReturnUrl" value="#">
|
||||
<a data-role="button" onclick="_xclick.submit();"><img src="css/images/donatepp.png"/></a>
|
||||
|
||||
<p><small><em>This button is now <strong>live</strong>. Transactions will result in real money being transferred.</em></small></p>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
73
Html/supporterKey.html
Normal file
@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Support</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="supporterKeyPage" data-role="page" class="page type-interior">
|
||||
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<div class="readOnlyContent">
|
||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
||||
<a href="support.html" data-role="button">General</a>
|
||||
<a href="log.html" data-role="button">View Log</a>
|
||||
<a href="supporter.html" data-role="button">Become a Supporter</a>
|
||||
<a href="supporterKey.html" data-role="button" class="ui-btn-active">Supporter Key</a>
|
||||
</div>
|
||||
<h2>Supporter Key</h2>
|
||||
</div>
|
||||
<form id="supporterKeyForm">
|
||||
<div style="margin-top: 40px; margin-bottom: 40px">
|
||||
<label for="txtSupporterKey">MB3 Supporter Key (paste from email)</label>
|
||||
<input type="password" id="txtSupporterKey" name="txtSupporterKey" data-inline="true" />
|
||||
<div class="fieldDescription">
|
||||
<strong>After becoming a supporter, you will be emailed a Supporter Key. Simply copy and paste that key into this field and start
|
||||
enjoying everything the community has developed for Media Browser. <em>Only MB 3 Supporter Keys are valid here</em></strong>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div style="margin-top: 40px; margin-bottom: 40px">
|
||||
<label for="txtLegacyKey">Legacy Supporter Key (from MB 2.x)</label>
|
||||
<input type="password" id="txtLegacyKey" name="txtLegacyKey" data-inline="true" />
|
||||
<div class="fieldDescription">
|
||||
<strong>Some premium plug-ins may give credit for registrations with previous versions in MB 2.x. Enter your MB 2.x
|
||||
Supporter Key here to allow that credit.
|
||||
</strong>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<p>
|
||||
<button type="submit" id="mbLegacyKeyBtn" data-theme="b">Save</button>
|
||||
|
||||
</p>
|
||||
|
||||
</form>
|
||||
<hr/>
|
||||
<h2>Lost Key</h2>
|
||||
<form id="lostKeyForm">
|
||||
<div style="margin-top: 40px; margin-bottom: 40px">
|
||||
<label for="txtEmail">Email Address</label>
|
||||
<input type="email" required id="txtEmail" name="txtEmail" data-inline="true" />
|
||||
<div class="fieldDescription">
|
||||
<strong>If you have lost your key, enter the email address associated with your PayPal account here and hit "Retrieve Key". The key
|
||||
will be emailed to you and you can come back here and paste it above.</strong>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<p>
|
||||
<button type="submit" id="mbRetrieveKeyBtn" data-theme="b" >Retrieve Key</button>
|
||||
|
||||
</p>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$('#supporterKeyForm').on('submit', SupporterKeyPage.updateSupporterKey);
|
||||
$('#lostKeyForm').on('submit', SupporterKeyPage.retrieveSupporterKey);
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
BIN
Html/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons-v2.png
vendored
Normal file
After Width: | Height: | Size: 54 KiB |
BIN
Html/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons.png
vendored
Normal file
After Width: | Height: | Size: 108 KiB |