mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
de-normalize item by name data. create counts during library scan for fast access.
This commit is contained in:
parent
abef9d9254
commit
b2d73b92eb
14 changed files with 102 additions and 237 deletions
138
ApiClient.js
138
ApiClient.js
|
@ -3171,144 +3171,6 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
Gets a variety of item counts that a person appears in
|
|
||||||
*/
|
|
||||||
self.getPersonItemCounts = function (userId, name) {
|
|
||||||
|
|
||||||
if (!userId) {
|
|
||||||
throw new Error("null userId");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
throw new Error("null name");
|
|
||||||
}
|
|
||||||
|
|
||||||
var url = self.getUrl("Persons/" + self.encodeName(name) + "/Counts", {
|
|
||||||
userId: userId
|
|
||||||
});
|
|
||||||
|
|
||||||
return self.ajax({
|
|
||||||
type: "GET",
|
|
||||||
url: url,
|
|
||||||
dataType: "json"
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
Gets a variety of item counts that a genre appears in
|
|
||||||
*/
|
|
||||||
self.getGenreItemCounts = function (userId, name) {
|
|
||||||
|
|
||||||
if (!userId) {
|
|
||||||
throw new Error("null userId");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
throw new Error("null name");
|
|
||||||
}
|
|
||||||
|
|
||||||
var url = self.getUrl("Genres/" + self.encodeName(name) + "/Counts", {
|
|
||||||
userId: userId
|
|
||||||
});
|
|
||||||
|
|
||||||
return self.ajax({
|
|
||||||
type: "GET",
|
|
||||||
url: url,
|
|
||||||
dataType: "json"
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
self.getMusicGenreItemCounts = function (userId, name) {
|
|
||||||
|
|
||||||
if (!userId) {
|
|
||||||
throw new Error("null userId");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
throw new Error("null name");
|
|
||||||
}
|
|
||||||
|
|
||||||
var url = self.getUrl("MusicGenres/" + self.encodeName(name) + "/Counts", {
|
|
||||||
userId: userId
|
|
||||||
});
|
|
||||||
|
|
||||||
return self.ajax({
|
|
||||||
type: "GET",
|
|
||||||
url: url,
|
|
||||||
dataType: "json"
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
self.getGameGenreItemCounts = function (userId, name) {
|
|
||||||
|
|
||||||
if (!userId) {
|
|
||||||
throw new Error("null userId");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
throw new Error("null name");
|
|
||||||
}
|
|
||||||
|
|
||||||
var url = self.getUrl("GameGenres/" + self.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/" + self.encodeName(name) + "/Counts", {
|
|
||||||
userId: userId
|
|
||||||
});
|
|
||||||
|
|
||||||
return self.ajax({
|
|
||||||
type: "GET",
|
|
||||||
url: url,
|
|
||||||
dataType: "json"
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
Gets a variety of item counts that a studio appears in
|
|
||||||
*/
|
|
||||||
self.getStudioItemCounts = function (userId, name) {
|
|
||||||
|
|
||||||
if (!userId) {
|
|
||||||
throw new Error("null userId");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
throw new Error("null name");
|
|
||||||
}
|
|
||||||
|
|
||||||
var url = self.getUrl("Studios/" + self.encodeName(name) + "/Counts", {
|
|
||||||
userId: userId
|
|
||||||
});
|
|
||||||
|
|
||||||
return self.ajax({
|
|
||||||
type: "GET",
|
|
||||||
url: url,
|
|
||||||
dataType: "json"
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears a user's personal rating for an item
|
* Clears a user's personal rating for an item
|
||||||
* @param {String} userId
|
* @param {String} userId
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
|
|
||||||
html += LibraryBrowser.getPosterDetailViewHtml({
|
html += LibraryBrowser.getPosterDetailViewHtml({
|
||||||
items: result.Items,
|
items: result.Items,
|
||||||
countNameSingular: "Game",
|
|
||||||
countNamePlural: "Games",
|
|
||||||
context: "games"
|
context: "games"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
|
|
||||||
html += LibraryBrowser.getPosterDetailViewHtml({
|
html += LibraryBrowser.getPosterDetailViewHtml({
|
||||||
items: result.Items,
|
items: result.Items,
|
||||||
countNameSingular: "Game",
|
|
||||||
countNamePlural: "Games",
|
|
||||||
context: "games"
|
context: "games"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -147,104 +147,77 @@
|
||||||
|
|
||||||
function renderTabs(page, item) {
|
function renderTabs(page, item) {
|
||||||
|
|
||||||
var promise;
|
var html = '<fieldset data-role="controlgroup" data-type="horizontal" class="libraryTabs">';
|
||||||
|
|
||||||
if (item.Type == "Person") {
|
html += '<legend></legend>';
|
||||||
promise = ApiClient.getPersonItemCounts(Dashboard.getCurrentUserId(), item.Name);
|
|
||||||
}
|
if (item.MovieCount) {
|
||||||
else if (item.Type == "Genre") {
|
|
||||||
promise = ApiClient.getGenreItemCounts(Dashboard.getCurrentUserId(), item.Name);
|
html += '<input type="radio" name="ibnItems" id="radioMovies" class="context-movies" value="on" data-mini="true">';
|
||||||
}
|
html += '<label for="radioMovies">Movies (' + item.MovieCount + ')</label>';
|
||||||
else if (item.Type == "MusicGenre") {
|
|
||||||
promise = ApiClient.getMusicGenreItemCounts(Dashboard.getCurrentUserId(), item.Name);
|
|
||||||
}
|
|
||||||
else if (item.Type == "GameGenre") {
|
|
||||||
promise = ApiClient.getGameGenreItemCounts(Dashboard.getCurrentUserId(), item.Name);
|
|
||||||
}
|
|
||||||
else if (item.Type == "Studio") {
|
|
||||||
promise = ApiClient.getStudioItemCounts(Dashboard.getCurrentUserId(), item.Name);
|
|
||||||
}
|
|
||||||
else if (item.Type == "Artist") {
|
|
||||||
promise = ApiClient.getArtistItemCounts(Dashboard.getCurrentUserId(), item.Name);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error("Unknown item type: " + item.Type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
promise.done(function (result) {
|
if (item.SeriesCount) {
|
||||||
|
|
||||||
var html = '<fieldset data-role="controlgroup" data-type="horizontal" class="libraryTabs">';
|
html += '<input type="radio" name="ibnItems" id="radioShows" class="context-tv" value="on" data-mini="true">';
|
||||||
|
html += '<label for="radioShows">TV Shows (' + item.SeriesCount + ')</label>';
|
||||||
|
}
|
||||||
|
|
||||||
html += '<legend></legend>';
|
if (item.EpisodeCount) {
|
||||||
|
|
||||||
if (result.MovieCount) {
|
html += '<input type="radio" name="ibnItems" id="radioEpisodes" class="context-tv" value="on" data-mini="true">';
|
||||||
|
html += '<label for="radioEpisodes">Episodes (' + item.EpisodeCount + ')</label>';
|
||||||
|
}
|
||||||
|
|
||||||
html += '<input type="radio" name="ibnItems" id="radioMovies" class="context-movies" value="on" data-mini="true">';
|
if (item.TrailerCount) {
|
||||||
html += '<label for="radioMovies">Movies (' + result.MovieCount + ')</label>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.SeriesCount) {
|
html += '<input type="radio" name="ibnItems" id="radioTrailers" class="context-movies" value="on" data-mini="true">';
|
||||||
|
html += '<label for="radioTrailers">Trailers (' + item.TrailerCount + ')</label>';
|
||||||
|
}
|
||||||
|
|
||||||
html += '<input type="radio" name="ibnItems" id="radioShows" class="context-tv" value="on" data-mini="true">';
|
if (item.GameCount) {
|
||||||
html += '<label for="radioShows">TV Shows (' + result.SeriesCount + ')</label>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.EpisodeCount) {
|
html += '<input type="radio" name="ibnItems" id="radioGames" class="context-games" value="on" data-mini="true">';
|
||||||
|
html += '<label for="radioGames">Games (' + item.GameCount + ')</label>';
|
||||||
|
}
|
||||||
|
|
||||||
html += '<input type="radio" name="ibnItems" id="radioEpisodes" class="context-tv" value="on" data-mini="true">';
|
if (item.AlbumCount) {
|
||||||
html += '<label for="radioEpisodes">Episodes (' + result.EpisodeCount + ')</label>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.TrailerCount) {
|
html += '<input type="radio" name="ibnItems" id="radioAlbums" class="context-music" value="on" data-mini="true">';
|
||||||
|
html += '<label for="radioAlbums">Albums (' + item.AlbumCount + ')</label>';
|
||||||
|
}
|
||||||
|
|
||||||
html += '<input type="radio" name="ibnItems" id="radioTrailers" class="context-movies" value="on" data-mini="true">';
|
if (item.SongCount) {
|
||||||
html += '<label for="radioTrailers">Trailers (' + result.TrailerCount + ')</label>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.GameCount) {
|
html += '<input type="radio" name="ibnItems" id="radioSongs" class="context-music" value="on" data-mini="true">';
|
||||||
|
html += '<label for="radioSongs">Songs (' + item.SongCount + ')</label>';
|
||||||
|
}
|
||||||
|
|
||||||
html += '<input type="radio" name="ibnItems" id="radioGames" class="context-games" value="on" data-mini="true">';
|
if (item.MusicVideoCount) {
|
||||||
html += '<label for="radioGames">Games (' + result.GameCount + ')</label>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.AlbumCount) {
|
html += '<input type="radio" name="ibnItems" id="radioMusicVideos" class="context-music" value="on" data-mini="true">';
|
||||||
|
html += '<label for="radioMusicVideos">Music Videos (' + item.MusicVideoCount + ')</label>';
|
||||||
|
}
|
||||||
|
|
||||||
html += '<input type="radio" name="ibnItems" id="radioAlbums" class="context-music" value="on" data-mini="true">';
|
html += '</fieldset>';
|
||||||
html += '<label for="radioAlbums">Albums (' + result.AlbumCount + ')</label>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.SongCount) {
|
var elem = $('#itemTabs', page).html(html).trigger('create');
|
||||||
|
|
||||||
html += '<input type="radio" name="ibnItems" id="radioSongs" class="context-music" value="on" data-mini="true">';
|
bindRadioEvents(page);
|
||||||
html += '<label for="radioSongs">Songs (' + result.SongCount + ')</label>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.MusicVideoCount) {
|
var context = getParameterByName('context');
|
||||||
|
var selectedRadio = null;
|
||||||
|
|
||||||
html += '<input type="radio" name="ibnItems" id="radioMusicVideos" class="context-music" value="on" data-mini="true">';
|
if (context) {
|
||||||
html += '<label for="radioMusicVideos">Music Videos (' + result.MusicVideoCount + ')</label>';
|
selectedRadio = $('.context-' + context + ':first', elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
html += '</fieldset>';
|
if (selectedRadio && selectedRadio.length) {
|
||||||
|
selectedRadio.attr("checked", "checked").checkboxradio("refresh").trigger('click');
|
||||||
|
} else {
|
||||||
|
$('input:first', elem).attr("checked", "checked").checkboxradio("refresh").trigger('click');
|
||||||
|
}
|
||||||
|
|
||||||
var elem = $('#itemTabs', page).html(html).trigger('create');
|
|
||||||
|
|
||||||
bindRadioEvents(page);
|
|
||||||
|
|
||||||
var context = getParameterByName('context');
|
|
||||||
var selectedRadio = null;
|
|
||||||
|
|
||||||
if (context) {
|
|
||||||
selectedRadio = $('.context-' + context + ':first', elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedRadio && selectedRadio.length) {
|
|
||||||
selectedRadio.attr("checked", "checked").checkboxradio("refresh").trigger('click');
|
|
||||||
} else {
|
|
||||||
$('input:first', elem).attr("checked", "checked").checkboxradio("refresh").trigger('click');
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindRadioEvents(page) {
|
function bindRadioEvents(page) {
|
||||||
|
|
|
@ -199,9 +199,7 @@
|
||||||
}
|
}
|
||||||
else if (item.Type == "Genre" || item.Type == "Studio" || item.Type == "Person" || item.Type == "Artist" || item.Type == "MusicGenre" || item.Type == "GameGenre") {
|
else if (item.Type == "Genre" || item.Type == "Studio" || item.Type == "Person" || item.Type == "Artist" || item.Type == "MusicGenre" || item.Type == "GameGenre") {
|
||||||
|
|
||||||
childText = item.ChildCount == 1 ? "1 " + options.countNameSingular : item.ChildCount + " " + options.countNamePlural;
|
html += LibraryBrowser.getItemCountsHtml(options, item);
|
||||||
|
|
||||||
html += '<p class="itemMiscInfo">' + childText + '</p>';
|
|
||||||
}
|
}
|
||||||
else if (item.Type == "Game") {
|
else if (item.Type == "Game") {
|
||||||
|
|
||||||
|
@ -236,6 +234,56 @@
|
||||||
return html;
|
return html;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getItemCountsHtml: function (options, item) {
|
||||||
|
|
||||||
|
var childText;
|
||||||
|
|
||||||
|
if (options.context == "movies") {
|
||||||
|
|
||||||
|
if (item.MovieCount) {
|
||||||
|
|
||||||
|
childText = item.MovieCount == 1 ? "1 Movie" : item.MovieCount + " Movies";
|
||||||
|
}
|
||||||
|
else if (item.TrailerCount) {
|
||||||
|
|
||||||
|
childText = item.TrailerCount == 1 ? "1 Trailer" : item.TrailerCount + " Trailers";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (options.context == "tv") {
|
||||||
|
|
||||||
|
if (item.SeriesCount) {
|
||||||
|
|
||||||
|
childText = item.SeriesCount == 1 ? "1 Show" : item.SeriesCount + " Shows";
|
||||||
|
}
|
||||||
|
else if (item.EpisodeCount) {
|
||||||
|
|
||||||
|
childText = item.EpisodeCount == 1 ? "1 Episode" : item.EpisodeCount + " Episodes";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (options.context == "games") {
|
||||||
|
|
||||||
|
if (item.GameCount) {
|
||||||
|
|
||||||
|
childText = item.GameCount == 1 ? "1 Game" : item.GameCount + " Games";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (options.context == "music") {
|
||||||
|
|
||||||
|
if (item.SongCount) {
|
||||||
|
|
||||||
|
childText = item.SongCount == 1 ? "1 Song" : item.SongCount + " Songs";
|
||||||
|
}
|
||||||
|
else if (item.MusicVideoCount) {
|
||||||
|
|
||||||
|
childText = item.MusicVideoCount == 1 ? "1 Music Video" : item.MusicVideoCount + " Music Videos";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return childText ? '<p class="itemMiscInfo">' + childText + '</p>' : '';
|
||||||
|
},
|
||||||
|
|
||||||
getSongHeaderCellHtml: function (text, cssClass, enableSorting, sortField, selectedSortField, sortDirection) {
|
getSongHeaderCellHtml: function (text, cssClass, enableSorting, sortField, selectedSortField, sortDirection) {
|
||||||
|
|
||||||
var html = cssClass ? '<th class="' + cssClass + '">' : '<th>';
|
var html = cssClass ? '<th class="' + cssClass + '">' : '<th>';
|
||||||
|
@ -1008,6 +1056,8 @@
|
||||||
options += getOption(100);
|
options += getOption(100);
|
||||||
options += getOption(200);
|
options += getOption(200);
|
||||||
options += getOption(300);
|
options += getOption(300);
|
||||||
|
options += getOption(400);
|
||||||
|
options += getOption(500);
|
||||||
|
|
||||||
html += '<label class="labelPageSize" for="' + id + '">Limit: </label><select class="selectPageSize" id="' + id + '" data-enhance="false" data-role="none">' + options + '</select>';
|
html += '<label class="labelPageSize" for="' + id + '">Limit: </label><select class="selectPageSize" id="' + id + '" data-enhance="false" data-role="none">' + options + '</select>';
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
|
|
||||||
html += LibraryBrowser.getPosterDetailViewHtml({
|
html += LibraryBrowser.getPosterDetailViewHtml({
|
||||||
items: result.Items,
|
items: result.Items,
|
||||||
countNameSingular: "Movie",
|
|
||||||
countNamePlural: "Movies",
|
|
||||||
context: "movies"
|
context: "movies"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
|
|
||||||
html += LibraryBrowser.getPosterDetailViewHtml({
|
html += LibraryBrowser.getPosterDetailViewHtml({
|
||||||
items: result.Items,
|
items: result.Items,
|
||||||
countNameSingular: "Movie",
|
|
||||||
countNamePlural: "Movies",
|
|
||||||
context: "movies"
|
context: "movies"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
|
|
||||||
html += LibraryBrowser.getPosterDetailViewHtml({
|
html += LibraryBrowser.getPosterDetailViewHtml({
|
||||||
items: result.Items,
|
items: result.Items,
|
||||||
countNameSingular: "Movie",
|
|
||||||
countNamePlural: "Movies",
|
|
||||||
context: "movies"
|
context: "movies"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
|
|
||||||
html += LibraryBrowser.getPosterDetailViewHtml({
|
html += LibraryBrowser.getPosterDetailViewHtml({
|
||||||
items: result.Items,
|
items: result.Items,
|
||||||
countNameSingular: "Song",
|
|
||||||
countNamePlural: "Songs",
|
|
||||||
preferBackdrop: false,
|
preferBackdrop: false,
|
||||||
context: "music",
|
context: "music",
|
||||||
shape: "square"
|
shape: "square"
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
|
|
||||||
html += LibraryBrowser.getPosterDetailViewHtml({
|
html += LibraryBrowser.getPosterDetailViewHtml({
|
||||||
items: result.Items,
|
items: result.Items,
|
||||||
countNameSingular: "Song",
|
|
||||||
countNamePlural: "Songs",
|
|
||||||
context: "music"
|
context: "music"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
|
|
||||||
html += LibraryBrowser.getPosterDetailViewHtml({
|
html += LibraryBrowser.getPosterDetailViewHtml({
|
||||||
items: result.Items,
|
items: result.Items,
|
||||||
countNameSingular: "Show",
|
|
||||||
countNamePlural: "Shows",
|
|
||||||
context: "tv"
|
context: "tv"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
|
|
||||||
html += LibraryBrowser.getPosterDetailViewHtml({
|
html += LibraryBrowser.getPosterDetailViewHtml({
|
||||||
items: result.Items,
|
items: result.Items,
|
||||||
countNameSingular: "Show",
|
|
||||||
countNamePlural: "Shows",
|
|
||||||
context: "tv"
|
context: "tv"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
|
|
||||||
html += LibraryBrowser.getPosterDetailViewHtml({
|
html += LibraryBrowser.getPosterDetailViewHtml({
|
||||||
items: result.Items,
|
items: result.Items,
|
||||||
countNameSingular: "Show",
|
|
||||||
countNamePlural: "Shows",
|
|
||||||
context: "tv"
|
context: "tv"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.174" targetFramework="net45" />
|
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.175" targetFramework="net45" />
|
||||||
<package id="ServiceStack.Common" version="3.9.58" targetFramework="net45" />
|
<package id="ServiceStack.Common" version="3.9.58" targetFramework="net45" />
|
||||||
<package id="ServiceStack.Text" version="3.9.58" targetFramework="net45" />
|
<package id="ServiceStack.Text" version="3.9.58" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
Loading…
Add table
Add a link
Reference in a new issue