diff --git a/ApiClient.js b/ApiClient.js
index fe676abaf..759fb0dc4 100644
--- a/ApiClient.js
+++ b/ApiClient.js
@@ -862,13 +862,19 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
/**
* Gets a studio
*/
- self.getStudio = function (name) {
+ self.getStudio = function (name, userId) {
if (!name) {
throw new Error("null name");
}
- var url = self.getUrl("Studios/" + encodeName(name));
+ var options = {};
+
+ if (userId) {
+ options.userId = userId;
+ }
+
+ var url = self.getUrl("Studios/" + encodeName(name), options);
return self.ajax({
type: "GET",
@@ -880,13 +886,43 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
/**
* Gets a genre
*/
- self.getGenre = function (name) {
+ self.getGenre = function (name, userId) {
if (!name) {
throw new Error("null name");
}
- var url = self.getUrl("Genres/" + encodeName(name));
+ var options = {};
+
+ if (userId) {
+ options.userId = userId;
+ }
+
+ var url = self.getUrl("Genres/" + encodeName(name), options);
+
+ return self.ajax({
+ type: "GET",
+ url: url,
+ dataType: "json"
+ });
+ };
+
+ /**
+ * Gets an artist
+ */
+ self.getArtist = function (name, userId) {
+
+ if (!name) {
+ throw new Error("null name");
+ }
+
+ var options = {};
+
+ if (userId) {
+ options.userId = userId;
+ }
+
+ var url = self.getUrl("Artists/" + encodeName(name), options);
return self.ajax({
type: "GET",
@@ -898,13 +934,19 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
/**
* Gets a year
*/
- self.getYear = function (year) {
+ self.getYear = function (yea, userId) {
- if (!year) {
- throw new Error("null year");
+ if (!name) {
+ throw new Error("null name");
}
- var url = self.getUrl("Years/" + year);
+ var options = {};
+
+ if (userId) {
+ options.userId = userId;
+ }
+
+ var url = self.getUrl("Years/" + encodeName(name), options);
return self.ajax({
type: "GET",
@@ -916,13 +958,19 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
/**
* Gets a Person
*/
- self.getPerson = function (name) {
+ self.getPerson = function (name, userId) {
if (!name) {
throw new Error("null name");
}
- var url = self.getUrl("Persons/" + encodeName(name));
+ var options = {};
+
+ if (userId) {
+ options.userId = userId;
+ }
+
+ var url = self.getUrl("Persons/" + encodeName(name), options);
return self.ajax({
type: "GET",
@@ -1131,6 +1179,41 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
return self.getUrl(url, options);
};
+ /**
+ * Constructs a url for a artist image
+ * @param {String} name
+ * @param {Object} options
+ * Options supports the following properties:
+ * width - download the image at a fixed width
+ * height - download the image at a fixed height
+ * maxWidth - download the image at a maxWidth
+ * maxHeight - download the image at a maxHeight
+ * quality - A scale of 0-100. This should almost always be omitted as the default will suffice.
+ * For best results do not specify both width and height together, as aspect ratio might be altered.
+ */
+ self.getArtistImageUrl = function (name, options) {
+
+ if (!name) {
+ throw new Error("null name");
+ }
+
+ options = options || {
+
+ };
+
+ var url = "Artists/" + encodeName(name) + "/Images/" + options.type;
+
+ if (options.index != null) {
+ url += "/" + options.index;
+ }
+
+ // Don't put these on the query string
+ delete options.type;
+ delete options.index;
+
+ return self.getUrl(url, options);
+ };
+
/**
* Constructs a url for a studio image
* @param {String} name
@@ -1524,6 +1607,27 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
});
};
+ /**
+ Gets artists from an item
+ */
+ self.getArtists = function (userId, options) {
+
+ if (!userId) {
+ throw new Error("null userId");
+ }
+
+ options = options || {};
+ options.userId = userId;
+
+ var url = self.getUrl("Artists", options);
+
+ return self.ajax({
+ type: "GET",
+ url: url,
+ dataType: "json"
+ });
+ };
+
/**
Gets genres from an item
*/
@@ -1533,12 +1637,10 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
throw new Error("null userId");
}
- var parentId = options.parentId || "root";
+ options = options || {};
+ options.userId = userId;
- // Don't put these on the query string
- delete options.parentId;
-
- var url = self.getUrl("Users/" + userId + "/Items/" + parentId + "/Genres", options);
+ var url = self.getUrl("Genres", options);
return self.ajax({
type: "GET",
@@ -1556,12 +1658,10 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
throw new Error("null userId");
}
- var parentId = options.parentId || "root";
+ options = options || {};
+ options.userId = userId;
- // Don't put these on the query string
- delete options.parentId;
-
- var url = self.getUrl("Users/" + userId + "/Items/" + parentId + "/Persons", options);
+ var url = self.getUrl("Persons", options);
return self.ajax({
type: "GET",
@@ -1579,12 +1679,10 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
throw new Error("null userId");
}
- var parentId = options.parentId || "root";
+ options = options || {};
+ options.userId = userId;
- // Don't put these on the query string
- delete options.parentId;
-
- var url = self.getUrl("Users/" + userId + "/Items/" + parentId + "/Studios", options);
+ var url = self.getUrl("Studios", options);
return self.ajax({
type: "GET",
@@ -1722,7 +1820,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
* @param {String} name
* @param {Boolean} isFavorite
*/
- self.updateItemByNameFavoriteStatus = function (userId, name, isFavorite) {
+ self.updateFavoriteArtistStatus = function (userId, name, isFavorite) {
if (!userId) {
throw new Error("null userId");
@@ -1732,7 +1830,67 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
throw new Error("null name");
}
- var url = self.getUrl("Users/" + userId + "/ItemsByName/Favorites/" + encodeName(name));
+ var url = self.getUrl("Users/" + userId + "/Favorites/Artists/" + encodeName(name));
+
+ var method = isFavorite ? "POST" : "DELETE";
+
+ return self.ajax({
+ type: method,
+ url: url
+ });
+ };
+
+ self.updateFavoritePersonStatus = function (userId, name, isFavorite) {
+
+ if (!userId) {
+ throw new Error("null userId");
+ }
+
+ if (!name) {
+ throw new Error("null name");
+ }
+
+ var url = self.getUrl("Users/" + userId + "/Favorites/Persons/" + encodeName(name));
+
+ var method = isFavorite ? "POST" : "DELETE";
+
+ return self.ajax({
+ type: method,
+ url: url
+ });
+ };
+
+ self.updateFavoriteStudioStatus = function (userId, name, isFavorite) {
+
+ if (!userId) {
+ throw new Error("null userId");
+ }
+
+ if (!name) {
+ throw new Error("null name");
+ }
+
+ var url = self.getUrl("Users/" + userId + "/Favorites/Studios/" + encodeName(name));
+
+ var method = isFavorite ? "POST" : "DELETE";
+
+ return self.ajax({
+ type: method,
+ url: url
+ });
+ };
+
+ self.updateFavoriteGenreStatus = function (userId, name, isFavorite) {
+
+ if (!userId) {
+ throw new Error("null userId");
+ }
+
+ if (!name) {
+ throw new Error("null name");
+ }
+
+ var url = self.getUrl("Users/" + userId + "/Favorites/Genres/" + encodeName(name));
var method = isFavorite ? "POST" : "DELETE";
@@ -1748,7 +1906,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
* @param {String} name
* @param {Boolean} likes
*/
- self.updateItemByNameRating = function (userId, name, likes) {
+ self.updateArtistRating = function (userId, name, likes) {
if (!userId) {
throw new Error("null userId");
@@ -1758,7 +1916,67 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
throw new Error("null name");
}
- var url = self.getUrl("Users/" + userId + "/ItemsByName/" + encodeName(name) + "/Rating", {
+ var url = self.getUrl("Users/" + userId + "/Ratings/Artists/" + encodeName(name), {
+ likes: likes
+ });
+
+ return self.ajax({
+ type: "POST",
+ url: url
+ });
+ };
+
+ self.updatePersonRating = function (userId, name, likes) {
+
+ if (!userId) {
+ throw new Error("null userId");
+ }
+
+ if (!name) {
+ throw new Error("null name");
+ }
+
+ var url = self.getUrl("Users/" + userId + "/Ratings/Persons/" + encodeName(name), {
+ likes: likes
+ });
+
+ return self.ajax({
+ type: "POST",
+ url: url
+ });
+ };
+
+ self.updateStudioRating = function (userId, name, likes) {
+
+ if (!userId) {
+ throw new Error("null userId");
+ }
+
+ if (!name) {
+ throw new Error("null name");
+ }
+
+ var url = self.getUrl("Users/" + userId + "/Ratings/Studios/" + encodeName(name), {
+ likes: likes
+ });
+
+ return self.ajax({
+ type: "POST",
+ url: url
+ });
+ };
+
+ self.updateGenreRating = function (userId, name, likes) {
+
+ if (!userId) {
+ throw new Error("null userId");
+ }
+
+ if (!name) {
+ throw new Error("null name");
+ }
+
+ var url = self.getUrl("Users/" + userId + "/Ratings/Genres/" + encodeName(name), {
likes: likes
});
@@ -1773,7 +1991,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
* @param {String} userId
* @param {String} name
*/
- self.clearItemByNameRating = function (userId, name) {
+ self.clearArtistRating = function (userId, name) {
if (!userId) {
throw new Error("null userId");
@@ -1783,7 +2001,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
throw new Error("null name");
}
- var url = self.getUrl("Users/" + userId + "/ItemsByName/" + encodeName(name) + "/Rating");
+ var url = self.getUrl("Users/" + userId + "/Ratings/Artists/" + encodeName(name));
return self.ajax({
type: "DELETE",
@@ -1791,12 +2009,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
});
};
- /**
- * Gets the full user data object for an item by name.
- * @param {String} userId
- * @param {String} name
- */
- self.getItembyNameUserData = function (userId, name) {
+ self.clearPersonRating = function (userId, name) {
if (!userId) {
throw new Error("null userId");
@@ -1806,12 +2019,47 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
throw new Error("null name");
}
- var url = self.getUrl("Users/" + userId + "/ItemsByName/" + encodeName(name) + "/UserData");
+ var url = self.getUrl("Users/" + userId + "/Ratings/Persons/" + encodeName(name));
return self.ajax({
- type: "GET",
- url: url,
- dataType: "json"
+ type: "DELETE",
+ url: url
+ });
+ };
+
+ self.clearStudioRating = function (userId, name) {
+
+ if (!userId) {
+ throw new Error("null userId");
+ }
+
+ if (!name) {
+ throw new Error("null name");
+ }
+
+ var url = self.getUrl("Users/" + userId + "/Ratings/Studios/" + encodeName(name));
+
+ return self.ajax({
+ type: "DELETE",
+ url: url
+ });
+ };
+
+ self.clearGenreRating = function (userId, name) {
+
+ if (!userId) {
+ throw new Error("null userId");
+ }
+
+ if (!name) {
+ throw new Error("null name");
+ }
+
+ var url = self.getUrl("Users/" + userId + "/Ratings/Genres/" + encodeName(name));
+
+ return self.ajax({
+ type: "DELETE",
+ url: url
});
};
@@ -1828,7 +2076,9 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
throw new Error("null name");
}
- var url = self.getUrl("Users/" + userId + "/Persons/" + encodeName(name) + "/Counts");
+ var url = self.getUrl("Persons/" + encodeName(name) + "/Counts", {
+ userId: userId
+ });
return self.ajax({
type: "GET",
@@ -1850,7 +2100,33 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
throw new Error("null name");
}
- var url = self.getUrl("Users/" + userId + "/Genres/" + encodeName(name) + "/Counts");
+ var url = self.getUrl("Genres/" + encodeName(name) + "/Counts", {
+ userId: userId
+ });
+
+ return self.ajax({
+ type: "GET",
+ url: url,
+ dataType: "json"
+ });
+ };
+
+ /**
+ Gets a variety of item counts that an artist appears in
+ */
+ self.getArtistItemCounts = function (userId, name) {
+
+ if (!userId) {
+ throw new Error("null userId");
+ }
+
+ if (!name) {
+ throw new Error("null name");
+ }
+
+ var url = self.getUrl("Artists/" + encodeName(name) + "/Counts", {
+ userId: userId
+ });
return self.ajax({
type: "GET",
@@ -1872,7 +2148,9 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
throw new Error("null name");
}
- var url = self.getUrl("Users/" + userId + "/Studios/" + encodeName(name) + "/Counts");
+ var url = self.getUrl("Studios/" + encodeName(name) + "/Counts", {
+ userId: userId
+ });
return self.ajax({
type: "GET",
diff --git a/dashboard-ui/musicalbums.html b/dashboard-ui/musicalbums.html
new file mode 100644
index 000000000..b2a2ac7ff
--- /dev/null
+++ b/dashboard-ui/musicalbums.html
@@ -0,0 +1,72 @@
+
+
+
+ Media Browser
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dashboard-ui/musicartists.html b/dashboard-ui/musicartists.html
new file mode 100644
index 000000000..62c6b8d12
--- /dev/null
+++ b/dashboard-ui/musicartists.html
@@ -0,0 +1,72 @@
+
+
+
+ Media Browser
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dashboard-ui/musicgenres.html b/dashboard-ui/musicgenres.html
index 60c265e0b..123e30039 100644
--- a/dashboard-ui/musicgenres.html
+++ b/dashboard-ui/musicgenres.html
@@ -11,8 +11,8 @@
diff --git a/dashboard-ui/musicrecommended.html b/dashboard-ui/musicrecommended.html
index 81837190a..6fdbe6297 100644
--- a/dashboard-ui/musicrecommended.html
+++ b/dashboard-ui/musicrecommended.html
@@ -11,8 +11,8 @@
diff --git a/dashboard-ui/scripts/Itemdetailpage.js b/dashboard-ui/scripts/Itemdetailpage.js
index 7e828e9f6..abbc3e67f 100644
--- a/dashboard-ui/scripts/Itemdetailpage.js
+++ b/dashboard-ui/scripts/Itemdetailpage.js
@@ -101,16 +101,7 @@
$('#itemTagline', page).hide();
}
- if (item.Overview || item.OverviewHtml) {
- var overview = item.OverviewHtml || item.Overview;
-
- $('#itemOverview', page).html(overview).show();
- $('#itemOverview a').each(function () {
- $(this).attr("target", "_blank");
- });
- } else {
- $('#itemOverview', page).hide();
- }
+ LibraryBrowser.renderOverview($('#itemOverview', page), item);
if (item.CommunityRating) {
$('#itemCommunityRating', page).html(LibraryBrowser.getStarRatingHtml(item)).show().attr('title', item.CommunityRating);
diff --git a/dashboard-ui/scripts/boxset.js b/dashboard-ui/scripts/boxset.js
index 9f43b19a4..c7ed88f3e 100644
--- a/dashboard-ui/scripts/boxset.js
+++ b/dashboard-ui/scripts/boxset.js
@@ -42,16 +42,7 @@
$('#itemTagline', page).hide();
}
- if (item.Overview || item.OverviewHtml) {
- var overview = item.OverviewHtml || item.Overview;
-
- $('#itemOverview', page).html(overview).show();
- $('#itemOverview a').each(function () {
- $(this).attr("target", "_blank");
- });
- } else {
- $('#itemOverview', page).hide();
- }
+ LibraryBrowser.renderOverview($('#itemOverview', page), item);
if (item.CommunityRating) {
$('#itemCommunityRating', page).html(LibraryBrowser.getStarRatingHtml(item)).show().attr('title', item.CommunityRating);
diff --git a/dashboard-ui/scripts/gamedetailpage.js b/dashboard-ui/scripts/gamedetailpage.js
index ebae7af91..1f347a78d 100644
--- a/dashboard-ui/scripts/gamedetailpage.js
+++ b/dashboard-ui/scripts/gamedetailpage.js
@@ -58,16 +58,7 @@
$('#itemTagline', page).hide();
}
- if (item.Overview || item.OverviewHtml) {
- var overview = item.OverviewHtml || item.Overview;
-
- $('#itemOverview', page).html(overview).show();
- $('#itemOverview a').each(function () {
- $(this).attr("target", "_blank");
- });
- } else {
- $('#itemOverview', page).hide();
- }
+ LibraryBrowser.renderOverview($('#itemOverview', page), item);
if (item.CommunityRating) {
$('#itemCommunityRating', page).html(LibraryBrowser.getStarRatingHtml(item)).show().attr('title', item.CommunityRating);
diff --git a/dashboard-ui/scripts/gamesystempage.js b/dashboard-ui/scripts/gamesystempage.js
index 7c33208b1..6dafdf149 100644
--- a/dashboard-ui/scripts/gamesystempage.js
+++ b/dashboard-ui/scripts/gamesystempage.js
@@ -25,16 +25,7 @@
function renderDetails(page, item) {
- if (item.Overview || item.OverviewHtml) {
- var overview = item.OverviewHtml || item.Overview;
-
- $('#itemOverview', page).html(overview).show();
- $('#itemOverview a').each(function () {
- $(this).attr("target", "_blank");
- });
- } else {
- $('#itemOverview', page).hide();
- }
+ LibraryBrowser.renderOverview($('#itemOverview', page), item);
if (item.CommunityRating) {
$('#itemCommunityRating', page).html(LibraryBrowser.getStarRatingHtml(item)).show().attr('title', item.CommunityRating);
diff --git a/dashboard-ui/scripts/itembynamedetailpage.js b/dashboard-ui/scripts/itembynamedetailpage.js
index 69bb373b1..eb1fbf246 100644
--- a/dashboard-ui/scripts/itembynamedetailpage.js
+++ b/dashboard-ui/scripts/itembynamedetailpage.js
@@ -11,38 +11,40 @@
var name = getParameterByName('person');
if (name) {
- getItemPromise = ApiClient.getPerson(name);
+ getItemPromise = ApiClient.getPerson(name, Dashboard.getCurrentUserId());
} else {
name = getParameterByName('studio');
if (name) {
- getItemPromise = ApiClient.getStudio(name);
+ getItemPromise = ApiClient.getStudio(name, Dashboard.getCurrentUserId());
} else {
name = getParameterByName('genre');
if (name) {
- getItemPromise = ApiClient.getGenre(name);
+ getItemPromise = ApiClient.getGenre(name, Dashboard.getCurrentUserId());
}
else {
- throw new Error('Invalid request');
+
+ name = getParameterByName('artist');
+
+ if (name) {
+ getItemPromise = ApiClient.getArtist(name, Dashboard.getCurrentUserId());
+ }
+ else {
+ throw new Error('Invalid request');
+ }
}
}
}
- var getUserDataPromise = ApiClient.getItembyNameUserData(Dashboard.getCurrentUserId(), name);
-
- $.when(getItemPromise, getUserDataPromise).done(function (response1, response2) {
-
- var item = response1[0];
- var userdata = response2[0];
+ getItemPromise.done(function (item) {
currentItem = item;
- item.UserData = userdata;
name = item.Name;
$('#itemImage', page).html(LibraryBrowser.getDetailImageHtml(item));
@@ -70,7 +72,11 @@
}
else if (item.Type == "Studio") {
promise = ApiClient.getStudioItemCounts(Dashboard.getCurrentUserId(), item.Name);
- } else {
+ }
+ else if (item.Type == "Artist") {
+ promise = ApiClient.getArtistItemCounts(Dashboard.getCurrentUserId(), item.Name);
+ }
+ else {
throw new Error("Unknown item type: " + item.Type);
}
@@ -173,16 +179,7 @@
function renderDetails(page, item) {
- if (item.Overview || item.OverviewHtml) {
- var overview = item.OverviewHtml || item.Overview;
-
- $('#itemOverview', page).html(overview).show();
- $('#itemOverview a').each(function () {
- $(this).attr("target", "_blank");
- });
- } else {
- $('#itemOverview', page).hide();
- }
+ LibraryBrowser.renderOverview($('#itemOverview', page), item);
renderUserDataIcons(page, item);
LibraryBrowser.renderLinks($('#itemLinks', page), item);
diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js
index cb436f8d9..ab497ba53 100644
--- a/dashboard-ui/scripts/librarybrowser.js
+++ b/dashboard-ui/scripts/librarybrowser.js
@@ -1,5 +1,7 @@
var LibraryBrowser = (function (window, $) {
+ var defaultBackground = "#999;";
+
return {
getDetaultPageSize: function () {
@@ -26,11 +28,9 @@
if (options.preferBackdrop && item.BackdropImageTags && item.BackdropImageTags.length) {
- html += "
";
@@ -44,14 +44,13 @@
tag: item.ImageTags.Thumb
}) + "' />";
-
}
else if (item.ImageTags && item.ImageTags.Primary) {
var height = 300;
var width = primaryImageAspectRatio ? parseInt(height * primaryImageAspectRatio) : null;
- html += "
";
}
else if (item.MediaType == "Audio" || item.Type == "MusicAlbum" || item.Type == "MusicArtist") {
- html += "
";
+ html += "
";
}
else if (item.MediaType == "Video" || item.Type == "Season" || item.Type == "Series") {
- html += "
";
+ html += "
";
}
else if (item.Type == "Person") {
- html += "
";
+ html += "
";
+ }
+ else if (item.Type == "Artist") {
+
+ html += "
";
}
else if (item.MediaType == "Game") {
- html += "
";
+ html += "
";
}
else {
- html += "
";
+ html += "
";
}
html += '';
@@ -118,7 +119,13 @@
html += '
' + childText + '
';
}
- else if (item.Type == "Genre" || item.Type == "Studio" || item.Type == "Person") {
+ else if (item.Type == "MusicAlbum") {
+
+ childText = item.ChildCount == 1 ? "1 Song" : item.ChildCount + " Songs";
+
+ html += '
' + childText + '
';
+ }
+ else if (item.Type == "Genre" || item.Type == "Studio" || item.Type == "Person" || item.Type == "Artist") {
childText = item.ChildCount == 1 ? "1 " + options.countNameSingular : item.ChildCount + " " + options.countNamePlural;
@@ -128,6 +135,11 @@
html += '
' + LibraryBrowser.getMiscInfoHtml(item) + '
';
}
+ if (item.Type == "MusicAlbum") {
+
+ html += '
' + LibraryBrowser.getMiscInfoHtml(item) + '
';
+ }
+
html += '
' + LibraryBrowser.getUserDataIconsHtml(item) + '
';
html += '
';
@@ -164,16 +176,25 @@
if (item.Type == "Person") {
return "itembynamedetails.html?person=" + item.Name;
}
+ if (item.Type == "Artist") {
+ return "itembynamedetails.html?artist=" + item.Name;
+ }
return item.IsFolder ? (item.Id ? "itemList.html?parentId=" + item.Id : "#") : "itemdetails.html?id=" + item.Id;
},
- getPrimaryImageUrl: function (item, options) {
+ getImageUrl: function (item, type, index, options) {
options = options || {};
- options.type = "Primary";
- options.tag = item.ImageTags.Primary;
+ options.type = type;
+ options.index = index;
+
+ if (type == 'Backdrop') {
+ options.tag = item.BackdropImageTags[index];
+ } else {
+ options.tag = item.ImageTags[type];
+ }
if (item.Type == "Studio") {
@@ -187,6 +208,10 @@
return ApiClient.getGenreImageUrl(item.Name, options);
}
+ if (item.Type == "Artist") {
+
+ return ApiClient.getArtistImageUrl(item.Name, options);
+ }
return ApiClient.getImageUrl(item.Id, options);
@@ -243,11 +268,11 @@
}
else if (item.MediaType == "Audio" || item.Type == "MusicAlbum" || item.Type == "MusicArtist") {
- html += "
";
+ html += "
";
}
else if (item.MediaType == "Video" || item.Type == "Season" || item.Type == "Series") {
- html += "
";
+ html += "
";
}
else {
@@ -316,7 +341,7 @@
tag: item.BackdropImageTags[0]
}) + "' />";
} else {
- html += "
";
+ html += "
";
}
if (showText) {
@@ -353,7 +378,7 @@
return '' + item.RecentlyAddedItemCount + ' New
';
}
- if (!item.IsFolder && item.Type !== "Genre" && item.Type !== "Studio" && item.Type !== "Person") {
+ if (!item.IsFolder && item.Type !== "Genre" && item.Type !== "Studio" && item.Type !== "Person" && item.Type !== "Artist") {
var date = item.DateCreated;
@@ -597,6 +622,9 @@
else if (type == "Genre") {
itemId = item.Name;
}
+ else if (type == "Artist") {
+ itemId = item.Name;
+ }
if (item.MediaType || item.IsFolder) {
if (userData.Played) {
@@ -656,8 +684,17 @@
var markAsFavorite = $link.hasClass('imgFavoriteOff');
- if (type == "Person" || type == "Studio" || type == "Genre") {
- ApiClient.updateItemByNameFavoriteStatus(Dashboard.getCurrentUserId(), id, markAsFavorite);
+ if (type == "Person") {
+ ApiClient.updateFavoritePersonStatus(Dashboard.getCurrentUserId(), id, markAsFavorite);
+ }
+ else if (type == "Studio") {
+ ApiClient.updateFavoriteStudioStatus(Dashboard.getCurrentUserId(), id, markAsFavorite);
+ }
+ else if (type == "Artist") {
+ ApiClient.updateFavoriteArtistStatus(Dashboard.getCurrentUserId(), id, markAsFavorite);
+ }
+ else if (type == "Genre") {
+ ApiClient.updateFavoriteGenreStatus(Dashboard.getCurrentUserId(), id, markAsFavorite);
}
else {
ApiClient.updateFavoriteStatus(Dashboard.getCurrentUserId(), id, markAsFavorite);
@@ -681,24 +718,14 @@
if ($link.hasClass('imgLikeOff')) {
- if (type == "Person" || type == "Studio" || type == "Genre") {
- ApiClient.updateItemByNameRating(Dashboard.getCurrentUserId(), id, true);
- }
- else {
- ApiClient.updateUserItemRating(Dashboard.getCurrentUserId(), id, true);
- }
+ LibraryBrowser.updateUserItemRating(type, id, true);
link.src = "css/images/userdata/thumbs_up_on.png";
$link.addClass('imgLike').removeClass('imgLikeOff');
} else {
- if (type == "Person" || type == "Studio" || type == "Genre") {
- ApiClient.clearItemByNameRating(Dashboard.getCurrentUserId(), id);
- }
- else {
- ApiClient.clearUserItemRating(Dashboard.getCurrentUserId(), id);
- }
+ LibraryBrowser.clearUserItemRating(type, id);
link.src = "css/images/userdata/thumbs_up_off.png";
$link.addClass('imgLikeOff').removeClass('imgLike');
@@ -718,24 +745,14 @@
if ($link.hasClass('imgDislikeOff')) {
- if (type == "Person" || type == "Studio" || type == "Genre") {
- ApiClient.updateItemByNameRating(Dashboard.getCurrentUserId(), id, false);
- }
- else {
- ApiClient.updateUserItemRating(Dashboard.getCurrentUserId(), id, false);
- }
+ LibraryBrowser.updateUserItemRating(type, id, false);
link.src = "css/images/userdata/thumbs_down_on.png";
$link.addClass('imgDislike').removeClass('imgDislikeOff');
} else {
- if (type == "Person" || type == "Studio" || type == "Genre") {
- ApiClient.clearItemByNameRating(Dashboard.getCurrentUserId(), id);
- }
- else {
- ApiClient.clearUserItemRating(Dashboard.getCurrentUserId(), id);
- }
+ LibraryBrowser.clearUserItemRating(type, id);
link.src = "css/images/userdata/thumbs_down_off.png";
$link.addClass('imgDislikeOff').removeClass('imgDislike');
@@ -746,6 +763,44 @@
});
},
+ updateUserItemRating: function (type, id, likes) {
+
+ if (type == "Person") {
+ ApiClient.updatePersonRating(Dashboard.getCurrentUserId(), id, likes);
+ }
+ else if (type == "Studio") {
+ ApiClient.updateStudioRating(Dashboard.getCurrentUserId(), id, likes);
+ }
+ else if (type == "Artist") {
+ ApiClient.updateArtistRating(Dashboard.getCurrentUserId(), id, likes);
+ }
+ else if (type == "Genre") {
+ ApiClient.updateGenreRating(Dashboard.getCurrentUserId(), id, likes);
+ }
+ else {
+ ApiClient.updateUserItemRating(Dashboard.getCurrentUserId(), id, likes);
+ }
+ },
+
+ clearUserItemRating: function (type, id) {
+
+ if (type == "Person") {
+ ApiClient.clearPersonRating(Dashboard.getCurrentUserId(), id);
+ }
+ else if (type == "Studio") {
+ ApiClient.clearStudioRating(Dashboard.getCurrentUserId(), id);
+ }
+ else if (type == "Artist") {
+ ApiClient.clearArtistRating(Dashboard.getCurrentUserId(), id);
+ }
+ else if (type == "Genre") {
+ ApiClient.clearGenreRating(Dashboard.getCurrentUserId(), id);
+ }
+ else {
+ ApiClient.clearUserItemRating(Dashboard.getCurrentUserId(), id);
+ }
+ },
+
getDetailImageHtml: function (item) {
var imageTags = item.ImageTags || {};
@@ -762,21 +817,28 @@
url = ApiClient.getPersonImageUrl(item.Name, {
maxwidth: 800,
tag: imageTags.Primary,
- type: "primary"
+ type: "Primary"
});
}
else if (item.Type == "Genre") {
url = ApiClient.getGenreImageUrl(item.Name, {
maxwidth: 800,
tag: imageTags.Primary,
- type: "primary"
+ type: "Primary"
});
}
else if (item.Type == "Studio") {
url = ApiClient.getStudioImageUrl(item.Name, {
maxwidth: 800,
tag: imageTags.Primary,
- type: "primary"
+ type: "Primary"
+ });
+ }
+ else if (item.Type == "Artist") {
+ url = ApiClient.getArtistImageUrl(item.Name, {
+ maxwidth: 800,
+ tag: imageTags.Primary,
+ type: "Primary"
});
}
else {
@@ -789,19 +851,79 @@
}
else if (item.BackdropImageTags && item.BackdropImageTags.length) {
- url = ApiClient.getImageUrl(item.Id, {
- type: "Backdrop",
- maxwidth: 800,
- tag: item.BackdropImageTags[0]
- });
+ if (item.Type == "Person") {
+ url = ApiClient.getPersonImageUrl(item.Name, {
+ maxwidth: 800,
+ tag: item.BackdropImageTags[0],
+ type: "Backdrop"
+ });
+ }
+ else if (item.Type == "Genre") {
+ url = ApiClient.getGenreImageUrl(item.Name, {
+ maxwidth: 800,
+ tag: item.BackdropImageTags[0],
+ type: "Backdrop"
+ });
+ }
+ else if (item.Type == "Studio") {
+ url = ApiClient.getStudioImageUrl(item.Name, {
+ maxwidth: 800,
+ tag: item.BackdropImageTags[0],
+ type: "Backdrop"
+ });
+ }
+ else if (item.Type == "Artist") {
+ url = ApiClient.getArtistImageUrl(item.Name, {
+ maxwidth: 800,
+ tag: item.BackdropImageTags[0],
+ type: "Backdrop"
+ });
+ }
+ else {
+ url = ApiClient.getImageUrl(item.Id, {
+ type: "Backdrop",
+ maxwidth: 800,
+ tag: item.BackdropImageTags[0]
+ });
+ }
}
else if (imageTags.Thumb) {
- url = ApiClient.getImageUrl(item.Id, {
- type: "Thumb",
- maxwidth: 800,
- tag: item.ImageTags.Thumb
- });
+ if (item.Type == "Person") {
+ url = ApiClient.getPersonImageUrl(item.Name, {
+ maxwidth: 800,
+ tag: imageTags.Thumb,
+ type: "Thumb"
+ });
+ }
+ else if (item.Type == "Genre") {
+ url = ApiClient.getGenreImageUrl(item.Name, {
+ maxwidth: 800,
+ tag: imageTags.Thumb,
+ type: "Thumb"
+ });
+ }
+ else if (item.Type == "Studio") {
+ url = ApiClient.getStudioImageUrl(item.Name, {
+ maxwidth: 800,
+ tag: imageTags.Thumb,
+ type: "Thumb"
+ });
+ }
+ else if (item.Type == "Artist") {
+ url = ApiClient.getArtistImageUrl(item.Name, {
+ maxwidth: 800,
+ tag: imageTags.Thumb,
+ type: "Thumb"
+ });
+ }
+ else {
+ url = ApiClient.getImageUrl(item.Id, {
+ type: "Thumb",
+ maxwidth: 800,
+ tag: item.ImageTags.Thumb
+ });
+ }
}
else if (imageTags.Disc) {
@@ -839,7 +961,7 @@
if (url) {
- var style = useBackgroundColor ? "background-color:" + LibraryBrowser.getMetroColor(item.Id) + ";" : "";
+ var style = useBackgroundColor ? "background-color:" + defaultBackground + ";" : "";
if (maxwidth) {
style += "max-width:" + maxwidth + "px;";
@@ -888,6 +1010,22 @@
return miscInfo.join(' ');
},
+ renderOverview: function (elem, item) {
+
+ if (item.Overview || item.OverviewHtml) {
+ var overview = item.OverviewHtml || item.Overview;
+
+ elem.html(overview).show().trigger('create');
+
+ $('a', elem).each(function () {
+ $(this).attr("target", "_blank");
+ });
+ } else {
+ elem.hide();
+ }
+
+ },
+
renderStudios: function (elem, item) {
if (item.Studios && item.Studios.length) {
@@ -1011,7 +1149,7 @@
}) + "' />";
}
else {
- html += "
";
+ html += "
";
}
if (showText) {
@@ -1185,7 +1323,7 @@
html += '
';
} else {
- var style = "background-color:" + LibraryBrowser.getMetroColor(cast.Name) + ";";
+ var style = "background-color:" + defaultBackground + ";";
html += '
';
}
diff --git a/dashboard-ui/scripts/musicalbums.js b/dashboard-ui/scripts/musicalbums.js
new file mode 100644
index 000000000..7e5189b78
--- /dev/null
+++ b/dashboard-ui/scripts/musicalbums.js
@@ -0,0 +1,106 @@
+(function ($, document) {
+
+ // The base query options
+ var query = {
+
+ SortBy: "SortName",
+ SortOrder: "Ascending",
+ IncludeItemTypes: "MusicAlbum",
+ Recursive: true,
+ Fields: "PrimaryImageAspectRatio,ItemCounts,DateCreated,UserData",
+ Limit: LibraryBrowser.getDetaultPageSize(),
+ StartIndex: 0
+ };
+
+ function reloadItems(page) {
+
+ Dashboard.showLoadingMsg();
+
+ ApiClient.getItems(Dashboard.getCurrentUserId(), query).done(function (result) {
+
+ var html = '';
+
+ $('.listTopPaging', page).html(LibraryBrowser.getPagingHtml(query, result.TotalRecordCount, true)).trigger('create');
+
+ html += LibraryBrowser.getPosterDetailViewHtml({
+ items: result.Items,
+ useAverageAspectRatio: true
+ });
+
+ html += LibraryBrowser.getPagingHtml(query, result.TotalRecordCount);
+
+ $('#items', page).html(html).trigger('create');
+
+ $('.selectPage', page).on('change', function () {
+ query.StartIndex = (parseInt(this.value) - 1) * query.Limit;
+ reloadItems(page);
+ });
+
+ $('.btnNextPage', page).on('click', function () {
+ query.StartIndex += query.Limit;
+ reloadItems(page);
+ });
+
+ $('.btnPreviousPage', page).on('click', function () {
+ query.StartIndex -= query.Limit;
+ reloadItems(page);
+ });
+
+ Dashboard.hideLoadingMsg();
+ });
+ }
+
+ $(document).on('pageinit', "#musicAlbumsPage", function () {
+
+ var page = this;
+
+ $('.radioSortBy', this).on('click', function () {
+ query.SortBy = this.getAttribute('data-sortby');
+ query.StartIndex = 0;
+ reloadItems(page);
+ });
+
+ $('.radioSortOrder', this).on('click', function () {
+ query.SortOrder = this.getAttribute('data-sortorder');
+ query.StartIndex = 0;
+ reloadItems(page);
+ });
+
+ $('.chkStandardFilter', this).on('change', function () {
+
+ var filterName = this.getAttribute('data-filter');
+ var filters = query.Filters || "";
+
+ filters = (',' + filters).replace(',' + filterName, '').substring(1);
+
+ if (this.checked) {
+ filters = filters ? (filters + ',' + filterName) : filterName;
+ }
+
+ query.StartIndex = 0;
+ query.Filters = filters;
+
+ reloadItems(page);
+ });
+
+ }).on('pagebeforeshow', "#musicAlbumsPage", function () {
+
+ reloadItems(this);
+
+ }).on('pageshow', "#musicAlbumsPage", function () {
+
+ // Reset form values using the last used query
+ $('.radioSortBy', this).each(function () {
+
+ this.checked = query.SortBy == this.getAttribute('data-sortby');
+
+ }).checkboxradio('refresh');
+
+ $('.radioSortOrder', this).each(function () {
+
+ this.checked = query.SortOrder == this.getAttribute('data-sortorder');
+
+ }).checkboxradio('refresh');
+ });
+
+})(jQuery, document);
\ No newline at end of file
diff --git a/dashboard-ui/scripts/musicartists.js b/dashboard-ui/scripts/musicartists.js
new file mode 100644
index 000000000..c547e21f3
--- /dev/null
+++ b/dashboard-ui/scripts/musicartists.js
@@ -0,0 +1,109 @@
+(function ($, document) {
+
+ // The base query options
+ var query = {
+
+ SortBy: "SortName",
+ SortOrder: "Ascending",
+ IncludeItemTypes: "Audio",
+ Recursive: true,
+ Fields: "PrimaryImageAspectRatio,ItemCounts,DateCreated,UserData",
+ Limit: LibraryBrowser.getDetaultPageSize(),
+ StartIndex: 0
+ };
+
+ function reloadItems(page) {
+
+ Dashboard.showLoadingMsg();
+
+ ApiClient.getArtists(Dashboard.getCurrentUserId(), query).done(function (result) {
+
+ var html = '';
+
+ $('.listTopPaging', page).html(LibraryBrowser.getPagingHtml(query, result.TotalRecordCount, true)).trigger('create');
+
+ html += LibraryBrowser.getPosterDetailViewHtml({
+ items: result.Items,
+ useAverageAspectRatio: true,
+ countNameSingular: "Song",
+ countNamePlural: "Songs",
+ preferBackdrop: true
+ });
+
+ html += LibraryBrowser.getPagingHtml(query, result.TotalRecordCount);
+
+ $('#items', page).html(html).trigger('create');
+
+ $('.selectPage', page).on('change', function () {
+ query.StartIndex = (parseInt(this.value) - 1) * query.Limit;
+ reloadItems(page);
+ });
+
+ $('.btnNextPage', page).on('click', function () {
+ query.StartIndex += query.Limit;
+ reloadItems(page);
+ });
+
+ $('.btnPreviousPage', page).on('click', function () {
+ query.StartIndex -= query.Limit;
+ reloadItems(page);
+ });
+
+ Dashboard.hideLoadingMsg();
+ });
+ }
+
+ $(document).on('pageinit', "#musicArtistsPage", function () {
+
+ var page = this;
+
+ $('.radioSortBy', this).on('click', function () {
+ query.SortBy = this.getAttribute('data-sortby');
+ query.StartIndex = 0;
+ reloadItems(page);
+ });
+
+ $('.radioSortOrder', this).on('click', function () {
+ query.SortOrder = this.getAttribute('data-sortorder');
+ query.StartIndex = 0;
+ reloadItems(page);
+ });
+
+ $('.chkStandardFilter', this).on('change', function () {
+
+ var filterName = this.getAttribute('data-filter');
+ var filters = query.Filters || "";
+
+ filters = (',' + filters).replace(',' + filterName, '').substring(1);
+
+ if (this.checked) {
+ filters = filters ? (filters + ',' + filterName) : filterName;
+ }
+
+ query.StartIndex = 0;
+ query.Filters = filters;
+
+ reloadItems(page);
+ });
+
+ }).on('pagebeforeshow', "#musicArtistsPage", function () {
+
+ reloadItems(this);
+
+ }).on('pageshow', "#musicArtistsPage", function () {
+
+ // Reset form values using the last used query
+ $('.radioSortBy', this).each(function () {
+
+ this.checked = query.SortBy == this.getAttribute('data-sortby');
+
+ }).checkboxradio('refresh');
+
+ $('.radioSortOrder', this).each(function () {
+
+ this.checked = query.SortOrder == this.getAttribute('data-sortorder');
+
+ }).checkboxradio('refresh');
+ });
+
+})(jQuery, document);
\ No newline at end of file
diff --git a/dashboard-ui/scripts/tvseason.js b/dashboard-ui/scripts/tvseason.js
index 43d7c32c9..451a9d60f 100644
--- a/dashboard-ui/scripts/tvseason.js
+++ b/dashboard-ui/scripts/tvseason.js
@@ -53,16 +53,7 @@
$('#itemTagline', page).hide();
}
- if (item.Overview || item.OverviewHtml) {
- var overview = item.OverviewHtml || item.Overview;
-
- $('#itemOverview', page).html(overview).show();
- $('#itemOverview a').each(function () {
- $(this).attr("target", "_blank");
- });
- } else {
- $('#itemOverview', page).hide();
- }
+ LibraryBrowser.renderOverview($('#itemOverview', page), item);
if (item.CommunityRating) {
$('#itemCommunityRating', page).html(LibraryBrowser.getStarRatingHtml(item)).show().attr('title', item.CommunityRating);
diff --git a/dashboard-ui/scripts/tvseries.js b/dashboard-ui/scripts/tvseries.js
index 9abb7708e..5dc9a56f3 100644
--- a/dashboard-ui/scripts/tvseries.js
+++ b/dashboard-ui/scripts/tvseries.js
@@ -50,16 +50,7 @@
$('#itemTagline', page).hide();
}
- if (item.Overview || item.OverviewHtml) {
- var overview = item.OverviewHtml || item.Overview;
-
- $('#itemOverview', page).html(overview).show();
- $('#itemOverview a').each(function () {
- $(this).attr("target", "_blank");
- });
- } else {
- $('#itemOverview', page).hide();
- }
+ LibraryBrowser.renderOverview($('#itemOverview', page), item);
if (item.CommunityRating) {
$('#itemCommunityRating', page).html(LibraryBrowser.getStarRatingHtml(item)).show().attr('title', item.CommunityRating);
diff --git a/packages.config b/packages.config
index c84847e3e..56ea6b5c9 100644
--- a/packages.config
+++ b/packages.config
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file