2013-04-27 06:05:33 -07:00
|
|
|
|
(function ($, document, window, clearTimeout, setTimeout) {
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-04-27 06:05:33 -07:00
|
|
|
|
var searchHintTimeout;
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-04-27 06:05:33 -07:00
|
|
|
|
function clearSearchHintTimeout() {
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-04-27 06:05:33 -07:00
|
|
|
|
if (searchHintTimeout) {
|
|
|
|
|
|
|
|
|
|
clearTimeout(searchHintTimeout);
|
|
|
|
|
searchHintTimeout = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-27 09:18:42 -07:00
|
|
|
|
function updateSearchHints(page, searchTerm) {
|
2013-04-27 06:05:33 -07:00
|
|
|
|
|
|
|
|
|
if (!searchTerm) {
|
|
|
|
|
|
2013-12-27 09:18:42 -07:00
|
|
|
|
$('#searchHints', page).empty();
|
2013-04-27 06:05:33 -07:00
|
|
|
|
clearSearchHintTimeout();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
clearSearchHintTimeout();
|
|
|
|
|
|
|
|
|
|
searchHintTimeout = setTimeout(function () {
|
|
|
|
|
|
|
|
|
|
requestSearchHints(page, searchTerm);
|
|
|
|
|
|
|
|
|
|
}, 100);
|
|
|
|
|
}
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-04-27 06:05:33 -07:00
|
|
|
|
function requestSearchHints(page, searchTerm) {
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-04-27 06:05:33 -07:00
|
|
|
|
var currentTimeout = searchHintTimeout;
|
|
|
|
|
|
2013-04-28 13:23:37 -07:00
|
|
|
|
ApiClient.getSearchHints({ userId: Dashboard.getCurrentUserId(), searchTerm: searchTerm, limit: 10 }).done(function (result) {
|
2013-04-27 06:05:33 -07:00
|
|
|
|
|
|
|
|
|
if (currentTimeout != searchHintTimeout) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2013-12-27 09:18:42 -07:00
|
|
|
|
|
2013-04-27 06:05:33 -07:00
|
|
|
|
renderSearchHintResult(page, result.SearchHints);
|
2013-04-26 13:53:54 -07:00
|
|
|
|
});
|
2013-04-27 06:05:33 -07:00
|
|
|
|
}
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-04-27 06:05:33 -07:00
|
|
|
|
function preg_quote(str, delimiter) {
|
|
|
|
|
// http://kevin.vanzonneveld.net
|
|
|
|
|
// + original by: booeyOH
|
|
|
|
|
// + improved by: Ates Goral (http://magnetiq.com)
|
|
|
|
|
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
|
|
|
|
// + bugfixed by: Onno Marsman
|
|
|
|
|
// + improved by: Brett Zamir (http://brett-zamir.me)
|
|
|
|
|
// * example 1: preg_quote("$40");
|
|
|
|
|
// * returns 1: '\$40'
|
|
|
|
|
// * example 2: preg_quote("*RRRING* Hello?");
|
|
|
|
|
// * returns 2: '\*RRRING\* Hello\?'
|
|
|
|
|
// * example 3: preg_quote("\\.+*?[^]$(){}=!<>|:");
|
|
|
|
|
// * returns 3: '\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:'
|
|
|
|
|
return (str + '').replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
|
|
|
|
|
}
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-04-27 06:05:33 -07:00
|
|
|
|
function getHintDisplayName(data, term) {
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-04-27 06:05:33 -07:00
|
|
|
|
var regexp = new RegExp("(" + preg_quote(term) + ")", 'gi');
|
|
|
|
|
|
|
|
|
|
return data.replace(regexp, "<b>$1</b>");
|
2013-04-26 13:53:54 -07:00
|
|
|
|
}
|
|
|
|
|
|
2013-04-27 06:05:33 -07:00
|
|
|
|
function getSearchHintHtml(hint) {
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-04-27 06:05:33 -07:00
|
|
|
|
var html = '';
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-11-26 09:22:11 -07:00
|
|
|
|
var context;
|
2013-12-27 09:18:42 -07:00
|
|
|
|
|
2013-11-26 09:22:11 -07:00
|
|
|
|
if (hint.Type == "Episode" || hint.Type == "Season" || hint.Type == "Series") {
|
|
|
|
|
context = "tv";
|
|
|
|
|
}
|
|
|
|
|
else if (hint.Type == "Game" || hint.Type == "GameSystem") {
|
|
|
|
|
context = "games";
|
|
|
|
|
}
|
|
|
|
|
else if (hint.Type == "MusicArtist" || hint.Type == "MusicAlbum") {
|
|
|
|
|
context = "music";
|
|
|
|
|
}
|
|
|
|
|
else if (hint.Type == "Movie" || hint.Type == "BoxSet" || hint.Type == "Trailer") {
|
|
|
|
|
context = "movie";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html += '<a class="searchHint" href="' + LibraryBrowser.getHref(hint, context) + '">';
|
2013-04-27 06:05:33 -07:00
|
|
|
|
|
|
|
|
|
var imgUrl;
|
|
|
|
|
|
|
|
|
|
if (hint.PrimaryImageTag) {
|
|
|
|
|
|
|
|
|
|
hint.ImageTags = { Primary: hint.PrimaryImageTag };
|
|
|
|
|
imgUrl = LibraryBrowser.getImageUrl(hint, "Primary", 0, { maxwidth: 150, maxheight: 150 });
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (hint.MediaType == "Game") {
|
|
|
|
|
|
2013-12-27 09:31:45 -07:00
|
|
|
|
imgUrl = "css/images/items/searchhintsv2/game.png";
|
2013-04-27 06:05:33 -07:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (hint.Type == "Episode" || hint.Type == "Season" || hint.Type == "Series") {
|
|
|
|
|
|
2013-12-27 09:31:45 -07:00
|
|
|
|
imgUrl = "css/images/items/searchhintsv2/tv.png";
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
|
|
|
|
}
|
2013-11-21 13:48:26 -07:00
|
|
|
|
else if (hint.Type == "Audio" || hint.Type == "MusicAlbum" || hint.Type == "MusicArtist") {
|
2013-04-27 06:05:33 -07:00
|
|
|
|
|
2013-12-27 09:31:45 -07:00
|
|
|
|
imgUrl = "css/images/items/searchhintsv2/music.png";
|
2013-04-27 06:05:33 -07:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (hint.Type == "Person") {
|
|
|
|
|
|
2013-12-27 09:31:45 -07:00
|
|
|
|
imgUrl = "css/images/items/searchhintsv2/person.png";
|
2013-04-27 06:05:33 -07:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
|
2013-12-27 09:31:45 -07:00
|
|
|
|
imgUrl = "css/images/items/searchhintsv2/film.png";
|
2013-04-27 06:05:33 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html += '<img class="searchHintImage" src="' + imgUrl + '" />';
|
|
|
|
|
|
|
|
|
|
html += '<div class="searchHintContent"><div class="searchHintContentInner">';
|
|
|
|
|
|
|
|
|
|
html += '<div class="searchHintName">' + getHintDisplayName(hint.Name, hint.MatchedTerm) + '</div>';
|
|
|
|
|
|
|
|
|
|
if (hint.Type == "Audio") {
|
|
|
|
|
|
|
|
|
|
html += '<div class="searchHintSecondaryText">' + [hint.AlbumArtist, hint.Album].join(" - ") + '</div>';
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (hint.Type == "MusicAlbum") {
|
|
|
|
|
|
|
|
|
|
html += '<div class="searchHintSecondaryText">' + hint.AlbumArtist + '</div>';
|
|
|
|
|
|
2013-12-07 08:52:38 -07:00
|
|
|
|
}
|
|
|
|
|
else if (hint.Type == "MusicArtist") {
|
|
|
|
|
|
|
|
|
|
html += '<div class="searchHintSecondaryText">Artist</div>';
|
|
|
|
|
|
2013-05-18 10:07:20 -07:00
|
|
|
|
}
|
|
|
|
|
else if (hint.Type == "Movie") {
|
|
|
|
|
|
|
|
|
|
html += '<div class="searchHintSecondaryText">Movie</div>';
|
|
|
|
|
|
2013-05-27 18:59:26 -07:00
|
|
|
|
}
|
|
|
|
|
else if (hint.Type == "MusicVideo") {
|
|
|
|
|
|
|
|
|
|
html += '<div class="searchHintSecondaryText">Music Video</div>';
|
|
|
|
|
|
2013-05-18 10:07:20 -07:00
|
|
|
|
}
|
|
|
|
|
else if (hint.Type == "Episode") {
|
|
|
|
|
|
|
|
|
|
html += '<div class="searchHintSecondaryText">Episode</div>';
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (hint.Type == "Series") {
|
|
|
|
|
|
|
|
|
|
html += '<div class="searchHintSecondaryText">Series</div>';
|
|
|
|
|
|
2013-04-27 06:05:33 -07:00
|
|
|
|
}
|
|
|
|
|
else {
|
2013-10-01 08:16:38 -07:00
|
|
|
|
html += '<div class="searchHintSecondaryText">' + (hint.Type) + '</div>';
|
2013-04-27 06:05:33 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var text;
|
|
|
|
|
|
|
|
|
|
if (hint.EpisodeCount) {
|
|
|
|
|
|
|
|
|
|
text = hint.EpisodeCount == 1 ? "1 Episode" : hint.EpisodeCount + " Episodes";
|
|
|
|
|
|
|
|
|
|
html += '<div class="searchHintSecondaryText">' + text + '</div>';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (hint.SongCount) {
|
|
|
|
|
|
|
|
|
|
text = hint.SongCount == 1 ? "1 Song" : hint.SongCount + " Songs";
|
|
|
|
|
|
|
|
|
|
html += '<div class="searchHintSecondaryText">' + text + '</div>';
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-27 10:12:23 -07:00
|
|
|
|
else if (hint.ProductionYear && hint.MediaType != "Audio" && hint.Type != "Episode") {
|
|
|
|
|
html += '<div class="searchHintSecondaryText">' + hint.ProductionYear + '</div>';
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-27 06:05:33 -07:00
|
|
|
|
else if (hint.RunTimeTicks) {
|
2013-06-07 10:29:33 -07:00
|
|
|
|
html += '<div class="searchHintSecondaryText">' + Dashboard.getDisplayTime(hint.RunTimeTicks) + '</div>';
|
2013-04-27 06:05:33 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html += '</div></div>';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
html += '</a>';
|
|
|
|
|
|
|
|
|
|
return html;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function renderSearchHintResult(page, hints) {
|
|
|
|
|
|
|
|
|
|
var html = '';
|
|
|
|
|
|
|
|
|
|
for (var i = 0, length = hints.length; i < length; i++) {
|
|
|
|
|
html += getSearchHintHtml(hints[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$('#searchHints', page).html(html);
|
2013-04-26 13:53:54 -07:00
|
|
|
|
}
|
2013-12-27 09:18:42 -07:00
|
|
|
|
|
|
|
|
|
function getSearchPanel(page) {
|
|
|
|
|
|
|
|
|
|
var panel = $('#searchPanel', page);
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-12-27 09:18:42 -07:00
|
|
|
|
if (!panel.length) {
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-12-27 09:18:42 -07:00
|
|
|
|
var html = '';
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-12-27 09:18:42 -07:00
|
|
|
|
html += '<div data-role="panel" id="searchPanel" class="searchPanel" data-position="right" data-display="overlay" data-position-fixed="true" data-theme="b">';
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-12-27 09:18:42 -07:00
|
|
|
|
html += '<h3>';
|
|
|
|
|
html += 'Search';
|
|
|
|
|
html += '</h3>';
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-12-27 09:18:42 -07:00
|
|
|
|
html += '<input id="txtSearch" class="txtSearch" type="search" data-theme="a" />';
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-12-27 09:18:42 -07:00
|
|
|
|
html += '<div id="searchHints" class="searchHints"></div>';
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-12-27 09:18:42 -07:00
|
|
|
|
html += '</div>';
|
2013-04-27 06:05:33 -07:00
|
|
|
|
|
2013-12-27 09:18:42 -07:00
|
|
|
|
$(page).append(html);
|
2013-04-27 06:05:33 -07:00
|
|
|
|
|
2013-12-27 09:18:42 -07:00
|
|
|
|
panel = $('#searchPanel', page).panel({}).trigger('create');
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-12-27 09:18:42 -07:00
|
|
|
|
$('#txtSearch', panel).on("keyup", function (e) {
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-12-27 09:18:42 -07:00
|
|
|
|
// Down
|
|
|
|
|
if (e.keyCode == 40) {
|
|
|
|
|
|
|
|
|
|
var first = $('.searchHint', panel)[0];
|
|
|
|
|
|
|
|
|
|
if (first) {
|
|
|
|
|
first.focus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}).on("keyup", function (e) {
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-12-27 09:18:42 -07:00
|
|
|
|
if (e.keyCode != 40) {
|
|
|
|
|
var value = this.value;
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-12-27 09:18:42 -07:00
|
|
|
|
updateSearchHints(panel, value);
|
|
|
|
|
}
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
|
|
|
|
});
|
2013-12-27 10:12:23 -07:00
|
|
|
|
|
|
|
|
|
$('#searchHints', page).on("keydown", '.searchHint', function (e) {
|
2013-05-21 14:13:57 -07:00
|
|
|
|
|
|
|
|
|
// Down
|
|
|
|
|
if (e.keyCode == 40) {
|
|
|
|
|
|
|
|
|
|
var next = $(this).next()[0];
|
|
|
|
|
|
|
|
|
|
if (next) {
|
|
|
|
|
next.focus();
|
|
|
|
|
}
|
2013-05-21 20:42:25 -07:00
|
|
|
|
return false;
|
2013-05-21 14:13:57 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Up
|
|
|
|
|
if (e.keyCode == 38) {
|
|
|
|
|
|
|
|
|
|
var prev = $(this).prev()[0];
|
|
|
|
|
|
|
|
|
|
if (prev) {
|
|
|
|
|
prev.focus();
|
|
|
|
|
} else {
|
2013-12-27 10:12:23 -07:00
|
|
|
|
$('#txtSearch', page)[0].focus();
|
2013-05-21 14:13:57 -07:00
|
|
|
|
}
|
2013-05-21 20:42:25 -07:00
|
|
|
|
return false;
|
2013-05-21 14:13:57 -07:00
|
|
|
|
}
|
|
|
|
|
});
|
2013-12-27 10:12:23 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return panel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function search() {
|
|
|
|
|
|
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
|
|
self.showSearchPanel = function (page) {
|
|
|
|
|
|
|
|
|
|
var panel = getSearchPanel(page);
|
2013-05-21 14:13:57 -07:00
|
|
|
|
|
2013-12-27 10:12:23 -07:00
|
|
|
|
$(panel).panel('toggle');
|
2013-04-26 13:53:54 -07:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
window.Search = new search();
|
2013-04-28 10:21:56 -07:00
|
|
|
|
|
2013-04-27 08:29:02 -07:00
|
|
|
|
$(document).on('pagehide', ".libraryPage", function () {
|
2013-04-27 07:00:22 -07:00
|
|
|
|
|
|
|
|
|
$('#txtSearch', this).val('');
|
2013-12-27 10:12:23 -07:00
|
|
|
|
$('#searchHints', this).empty();
|
2013-04-27 07:00:22 -07:00
|
|
|
|
});
|
|
|
|
|
|
2013-04-26 13:53:54 -07:00
|
|
|
|
|
2013-04-27 06:05:33 -07:00
|
|
|
|
})(jQuery, document, window, clearTimeout, setTimeout);
|