diff --git a/dashboard-ui/css/search.css b/dashboard-ui/css/search.css deleted file mode 100644 index 368d570e06..0000000000 --- a/dashboard-ui/css/search.css +++ /dev/null @@ -1,193 +0,0 @@ -.searchHints { - margin-top: 1em; -} - -.searchHint { - display: block; - text-decoration: none; - color: #fff; - border-bottom: 1px solid #444; -} - - .searchHint:hover { - background-color: #444; - } - - .searchHint:focus { - background-color: #444; - } - -.searchHintImage { - display: inline-block; - width: 20%; - vertical-align: middle; - margin: 4px 0; -} - -.searchHintContent { - vertical-align: top; - display: inline-block; - width: 80%; -} - -.searchHintName { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - color: #fff; - font-weight: normal !important; -} - -.searchHintSecondaryText { - color: #fff; - margin-top: 3px; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - font-weight: 300; -} - -.searchHintContentInner { - padding: 2px 5px; -} - -@-moz-keyframes spinPulse { - 0% { - -moz-transform: rotate(160deg); - opacity: 0; - box-shadow: 0 0 1px #2187e7; - } - - 50% { - -moz-transform: rotate(145deg); - opacity: 1; - } - - 100% { - -moz-transform: rotate(-320deg); - opacity: 0; - } -} - -@-moz-keyframes spinoffPulse { - 0% { - -moz-transform: rotate(0deg); - } - - 100% { - -moz-transform: rotate(360deg); - } -} - -@-webkit-keyframes spinPulse { - 0% { - -webkit-transform: rotate(160deg); - opacity: 0; - box-shadow: 0 0 1px #2187e7; - } - - 50% { - -webkit-transform: rotate(145deg); - opacity: 1; - } - - 100% { - -webkit-transform: rotate(-320deg); - opacity: 0; - } -} - -@-webkit-keyframes spinoffPulse { - 0% { - -webkit-transform: rotate(0deg); - } - - 100% { - -webkit-transform: rotate(360deg); - } -} - -.headerSearchInput { - margin: 0 !important; - background: #222 !important; - border: 0 !important; - color: #eee !important; - border-radius: 0 !important; - padding: 7px 0 6px 0 !important; - text-indent: 10px !important; - font-family: inherit; - outline: none; - vertical-align: middle; - width: 85% !important; - display: inline-block !important; - height: 100%!important; -} - -.viewMenuSearch { - position: fixed; - top: 0; - left: 0%; - right: 0; - background: #000000; - z-index: 1000; -} - -@media all and (min-width: 600px) { - .headerSearchInput { - width: 90% !important; - } -} - -@media all and (min-width: 800px) { - .headerSearchInput { - width: 93% !important; - } -} - -@media all and (min-width: 1200px) { - .headerSearchInput { - width: 96% !important; - } -} - -.viewMenuSearch:not(.hide) { - display: inline-block; -} - -.viewMenuSearchForm { - max-width: none; - padding: 5px; -} - -.searchResultsOverlay { - position: fixed; - top: 50px; - left: 0; - right: 0; - bottom: 0; - z-index: 1000; - border: 0 !important; -} - -.searchResultsContainer { - padding: .5em; -} - -@media all and (min-width: 800px) { - .searchResultsContainer { - padding-left: 1em; - padding-right: 1em; - } -} - -@media all and (min-height: 800px) { - .searchResultsContainer { - padding-top: 1em; - padding-bottom: 1em; - } -} - -.btnCloseSearch { - padding-top: 0; - padding-bottom: 0; -} diff --git a/dashboard-ui/devices/ios/ios.css b/dashboard-ui/devices/ios/ios.css index 26eb494f1e..733b87cb74 100644 --- a/dashboard-ui/devices/ios/ios.css +++ b/dashboard-ui/devices/ios/ios.css @@ -135,10 +135,6 @@ h1, h1 a { border-radius: 10px; } -.viewMenuSearch { - background: #1c1c1c; -} - .bottomFab { bottom: 120px !important; } diff --git a/dashboard-ui/scripts/librarymenu.js b/dashboard-ui/scripts/librarymenu.js index 6f3c5e910e..81bde53b17 100644 --- a/dashboard-ui/scripts/librarymenu.js +++ b/dashboard-ui/scripts/librarymenu.js @@ -24,13 +24,7 @@ html += ''; if (AppInfo.enableSearchInTopMenu) { - html += ''; - html += '
'; - html += '
'; - html += ''; - html += ''; - html += '
'; - html += '
'; + html += ''; } html += ''; @@ -175,6 +169,10 @@ }); } + function showSearch() { + Dashboard.navigate('search.html'); + } + function onHeaderUserButtonClick(e) { Dashboard.showUserFlyout(e.target); } @@ -252,6 +250,11 @@ headerVoiceButton.addEventListener('click', showVoice); } + var headerSearchButton = document.querySelector('.headerSearchButton'); + if (headerSearchButton) { + headerSearchButton.addEventListener('click', showSearch); + } + var headerUserButton = document.querySelector('.headerUserButton'); if (headerUserButton) { headerUserButton.addEventListener('click', onHeaderUserButtonClick); diff --git a/dashboard-ui/scripts/search.js b/dashboard-ui/scripts/search.js deleted file mode 100644 index f086e990cc..0000000000 --- a/dashboard-ui/scripts/search.js +++ /dev/null @@ -1,266 +0,0 @@ -define(['libraryBrowser', 'events', 'scrollStyles', 'scripts/librarymenu'], function (libraryBrowser, events) { - - var searchHintTimeout; - - function clearSearchHintTimeout() { - - if (searchHintTimeout) { - - clearTimeout(searchHintTimeout); - searchHintTimeout = null; - } - } - - function getAdditionalTextLines(hint) { - - if (hint.Type == "Audio") { - - return [[hint.AlbumArtist, hint.Album].join(" - ")]; - - } - else if (hint.Type == "MusicAlbum") { - - return [hint.AlbumArtist]; - - } - else if (hint.Type == "MusicArtist") { - - return [Globalize.translate('LabelArtist')]; - - } - else if (hint.Type == "Movie") { - - return [Globalize.translate('LabelMovie')]; - - } - else if (hint.Type == "MusicVideo") { - - return [Globalize.translate('LabelMusicVideo')]; - } - else if (hint.Type == "Episode") { - - return [Globalize.translate('LabelEpisode')]; - - } - else if (hint.Type == "Series") { - - return [Globalize.translate('Series')]; - } - else if (hint.Type == "BoxSet") { - - return [Globalize.translate('LabelCollection')]; - } - else if (hint.ChannelName) { - - return [hint.ChannelName]; - } - - return [hint.Type]; - } - - function search() { - - var self = this; - - self.showSearchPanel = function () { - - showSearchMenu(); - }; - } - window.Search = new search(); - - function renderSearchResultsInOverlay(elem, hints) { - - // Massage the objects to look like regular items - hints = hints.map(function (i) { - - i.Id = i.ItemId; - i.ImageTags = {}; - i.UserData = {}; - - if (i.PrimaryImageTag) { - i.ImageTags.Primary = i.PrimaryImageTag; - } - return i; - }); - - var html = libraryBrowser.getPosterViewHtml({ - items: hints, - shape: "auto", - lazy: true, - overlayText: false, - showTitle: true, - centerImage: true, - centerText: true, - textLines: getAdditionalTextLines, - overlayPlayButton: true - }); - - var itemsContainer = elem.querySelector('.itemsContainer'); - itemsContainer.innerHTML = html; - ImageLoader.lazyChildren(itemsContainer); - } - - function requestSearchHintsForOverlay(elem, searchTerm) { - - var currentTimeout = searchHintTimeout; - Dashboard.showLoadingMsg(); - - ApiClient.getSearchHints({ - - userId: Dashboard.getCurrentUserId(), - searchTerm: (searchTerm || '').trim(), - limit: 30 - - }).then(function (result) { - - if (currentTimeout == searchHintTimeout) { - renderSearchResultsInOverlay(elem, result.SearchHints); - } - - Dashboard.hideLoadingMsg(); - }, function () { - Dashboard.hideLoadingMsg(); - }); - } - - function updateSearchOverlay(elem, searchTerm) { - - if (!searchTerm) { - - var itemsContainer = elem.querySelector('.itemsContainer'); - if (itemsContainer) { - itemsContainer.innerHTML = ''; - } - clearSearchHintTimeout(); - return; - } - - clearSearchHintTimeout(); - - searchHintTimeout = setTimeout(function () { - - requestSearchHintsForOverlay(elem, searchTerm); - - }, 300); - } - - function getSearchOverlay(createIfNeeded) { - - var elem = document.querySelector('.searchResultsOverlay'); - - if (createIfNeeded && !elem) { - - var div = document.createElement('div'); - div.className = 'searchResultsOverlay ui-body-b smoothScrollY background-theme-b'; - - div.innerHTML = '
'; - - document.body.appendChild(div); - libraryBrowser.createCardMenus(div); - - elem = div; - } - - return elem; - } - - var isVisible; - - function onHeaderSearchChange(val) { - - var elem; - - if (val) { - - elem = getSearchOverlay(true); - - if (!isVisible) { - fadeIn(elem, 1); - } - isVisible = true; - - document.body.classList.add('bodyWithPopupOpen'); - - updateSearchOverlay(elem, val); - - } else { - elem = getSearchOverlay(false); - - if (elem) { - updateSearchOverlay(elem, ''); - - if (isVisible) { - fadeOut(elem, 1); - isVisible = false; - } - document.body.classList.remove('bodyWithPopupOpen'); - } - } - } - - function fadeIn(elem, iterations) { - - var keyframes = [ - { opacity: '0', offset: 0 }, - { opacity: '1', offset: 1 }]; - var timing = { duration: 200, iterations: iterations, fill: 'both' }; - - if (elem.animate) { - elem.animate(keyframes, timing); - } - } - - function fadeOut(elem, iterations) { - var keyframes = [ - { opacity: '1', offset: 0 }, - { opacity: '0', offset: 1 }]; - var timing = { duration: 600, iterations: iterations, fill: 'both' }; - - var onfinish = function () { - elem.parentNode.removeChild(elem); - }; - - if (elem.animate) { - elem.animate(keyframes, timing).onfinish = onfinish; - } else { - onfinish(); - } - } - - function bindSearchEvents() { - - require(['searchmenu'], function (searchmenu) { - events.on(window.SearchMenu, 'closed', closeSearchResults); - events.on(window.SearchMenu, 'change', function (e, value) { - onHeaderSearchChange(value); - }); - }); - } - - function closeSearchResults() { - - onHeaderSearchChange(''); - hideSearchMenu(); - } - - function showSearchMenu() { - require(['searchmenu'], function (searchmenu) { - window.SearchMenu.show(); - }); - } - - function hideSearchMenu() { - require(['searchmenu'], function (searchmenu) { - window.SearchMenu.hide(); - }); - } - - document.addEventListener('viewbeforehide', closeSearchResults); - - bindSearchEvents(); - - // dismiss search UI if user clicks a play button on a search result - events.on(MediaController, 'beforeplaybackstart', closeSearchResults); - -}); \ No newline at end of file diff --git a/dashboard-ui/scripts/searchmenu.js b/dashboard-ui/scripts/searchmenu.js deleted file mode 100644 index 03e20b28f3..0000000000 --- a/dashboard-ui/scripts/searchmenu.js +++ /dev/null @@ -1,73 +0,0 @@ -define([], function () { - - function fadeIn(elem, iterations) { - - var keyframes = [ - { opacity: '0', offset: 0 }, - { opacity: '1', offset: 1 }]; - var timing = { duration: 200, iterations: iterations }; - return elem.animate(keyframes, timing); - } - - function searchMenu() { - - var self = this; - var headerSearchInput = document.querySelector('.headerSearchInput'); - - self.show = function () { - - require(['css!css/search.css'], function () { - - headerSearchInput.value = ''; - - document.querySelector('.btnCloseSearch').classList.add('hide'); - var elem = document.querySelector('.viewMenuSearch'); - - elem.classList.remove('hide'); - - var onFinish = function() { - headerSearchInput.focus(); - document.querySelector('.btnCloseSearch').classList.remove('hide'); - }; - - if (elem.animate) { - fadeIn(elem, 1).onfinish = onFinish; - } else { - onFinish(); - } - - }); - }; - - self.hide = function () { - - var viewMenuSearch = document.querySelector('.viewMenuSearch'); - - if (!viewMenuSearch) { - return; - } - - if (!viewMenuSearch.classList.contains('hide')) { - document.querySelector('.btnCloseSearch').classList.add('hide'); - viewMenuSearch.classList.add('hide'); - } - }; - - document.querySelector('.viewMenuSearchForm').addEventListener('submit', function (e) { - e.preventDefault(); - return false; - }); - - document.querySelector('.btnCloseSearch').addEventListener('click', function () { - self.hide(); - Events.trigger(self, 'closed'); - }); - - headerSearchInput.addEventListener('input', function (e) { - Events.trigger(self, 'change', [this.value]); - }); - } - - window.SearchMenu = new searchMenu(); - return Window.SearchMenu; -}); \ No newline at end of file diff --git a/dashboard-ui/scripts/searchpage.js b/dashboard-ui/scripts/searchpage.js index ff62c4b1e1..9356084ddf 100644 --- a/dashboard-ui/scripts/searchpage.js +++ b/dashboard-ui/scripts/searchpage.js @@ -1,4 +1,4 @@ -define([], function () { +define(['libraryBrowser', 'focusManager', 'emby-input', 'paper-icon-button-light', 'material-icons'], function (libraryBrowser, focusManager) { function loadSuggestions(page) { @@ -29,13 +29,160 @@ }); } - pageIdOn('pageshow', "searchPage", function () { + return function (view, params) { - var page = this; - loadSuggestions(page); + var textSuggestions = view.querySelector('.textSuggestions'); + var searchResults = view.querySelector('.searchResults'); + var searchHintTimeout; - Search.showSearchPanel(); - }); + function clearSearchHintTimeout() { + if (searchHintTimeout) { + clearTimeout(searchHintTimeout); + searchHintTimeout = null; + } + } + + function showTextSuggestions() { + if (AppInfo.enableAppLayouts) { + textSuggestions.classList.remove('hide'); + } + } + + function getAdditionalTextLines(hint) { + + if (hint.Type == "Audio") { + + return [[hint.AlbumArtist, hint.Album].join(" - ")]; + + } + else if (hint.Type == "MusicAlbum") { + + return [hint.AlbumArtist]; + + } + else if (hint.Type == "MusicArtist") { + + return [Globalize.translate('LabelArtist')]; + + } + else if (hint.Type == "Movie") { + + return [Globalize.translate('LabelMovie')]; + + } + else if (hint.Type == "MusicVideo") { + + return [Globalize.translate('LabelMusicVideo')]; + } + else if (hint.Type == "Episode") { + + return [Globalize.translate('LabelEpisode')]; + + } + else if (hint.Type == "Series") { + + return [Globalize.translate('Series')]; + } + else if (hint.Type == "BoxSet") { + + return [Globalize.translate('LabelCollection')]; + } + else if (hint.ChannelName) { + + return [hint.ChannelName]; + } + + return [hint.Type]; + } + + function renderSearchResultsInOverlay(hints) { + + // Massage the objects to look like regular items + hints = hints.map(function (i) { + + i.Id = i.ItemId; + i.ImageTags = {}; + i.UserData = {}; + + if (i.PrimaryImageTag) { + i.ImageTags.Primary = i.PrimaryImageTag; + } + return i; + }); + + var html = libraryBrowser.getPosterViewHtml({ + items: hints, + shape: "auto", + lazy: true, + overlayText: false, + showTitle: true, + centerImage: true, + centerText: true, + textLines: getAdditionalTextLines, + overlayPlayButton: true + }); + + var itemsContainer = searchResults; + itemsContainer.innerHTML = html; + searchResults.classList.remove('hide'); + textSuggestions.classList.add('hide'); + ImageLoader.lazyChildren(itemsContainer); + } + + function requestSearchHintsForOverlay(searchTerm) { + + var currentTimeout = searchHintTimeout; + Dashboard.showLoadingMsg(); + + ApiClient.getSearchHints({ + + userId: Dashboard.getCurrentUserId(), + searchTerm: (searchTerm || '').trim(), + limit: 30 + + }).then(function (result) { + + if (currentTimeout == searchHintTimeout) { + renderSearchResultsInOverlay(result.SearchHints); + } + + Dashboard.hideLoadingMsg(); + }, function () { + Dashboard.hideLoadingMsg(); + }); + } + + function onSearchChange(val) { + + if (!val) { + clearSearchHintTimeout(); + searchResults.classList.add('hide'); + searchResults.innerHTML = ''; + showTextSuggestions(); + return; + } + + clearSearchHintTimeout(); + + searchHintTimeout = setTimeout(function () { + requestSearchHintsForOverlay(val); + }, 300); + } + + if (AppInfo.enableAppLayouts) { + showTextSuggestions(); + loadSuggestions(view); + } + + view.addEventListener('viewshow', function () { + focusManager.focus(view.querySelector('.txtSearch')); + }); + + view.querySelector('.txtSearch').addEventListener('input', function () { + onSearchChange(this.value); + }); + + }; }); \ No newline at end of file diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index aa97c715f3..c50171f74d 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -830,7 +830,7 @@ var Dashboard = { Dashboard.onBrowseCommand(cmd.Arguments); break; case 'GoToSearch': - Search.showSearchPanel(); + Dashboard.navigate('search.html'); break; case 'DisplayMessage': { @@ -2212,12 +2212,6 @@ var AppInfo = {}; define("detailtablecss", ['css!css/detailtable.css']); define("tileitemcss", ['css!css/tileitem.css']); - if (Dashboard.isRunningInCordova() && browserInfo.safari) { - define("searchmenu", ["cordova/searchmenu"]); - } else { - define("searchmenu", ["scripts/searchmenu"]); - } - define("buttonenabled", ["legacy/buttonenabled"]); var deps = []; @@ -2902,7 +2896,8 @@ var AppInfo = {}; defineRoute({ path: '/search.html', dependencies: [], - autoFocus: false + autoFocus: false, + controller: 'scripts/searchpage' }); defineRoute({ @@ -3159,7 +3154,6 @@ var AppInfo = {}; deps.push('devices/ie/ie'); } - deps.push('scripts/search'); deps.push('scripts/librarylist'); deps.push('scripts/librarymenu'); diff --git a/dashboard-ui/search.html b/dashboard-ui/search.html index 0b2053342f..c06f5ad10d 100644 --- a/dashboard-ui/search.html +++ b/dashboard-ui/search.html @@ -1,12 +1,25 @@ -
+
-
+
-

${TabSuggestions}

+
+
+ search +
+ +
+
+
-
+
+

${TabSuggestions}

+ +
+
+ +
\ No newline at end of file