mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Move search suggestions to react component
This commit is contained in:
parent
1c0c25d655
commit
6058a512c4
3 changed files with 76 additions and 39 deletions
|
@ -3,6 +3,7 @@ import React, { useState } from 'react';
|
||||||
|
|
||||||
import SearchFields from '../search/SearchFields';
|
import SearchFields from '../search/SearchFields';
|
||||||
import SearchResults from '../search/SearchResultsComponent';
|
import SearchResults from '../search/SearchResultsComponent';
|
||||||
|
import SearchSuggestions from '../search/SearchSuggestions';
|
||||||
|
|
||||||
const SearchPage = ({ serverId, parentId, collectionType }) => {
|
const SearchPage = ({ serverId, parentId, collectionType }) => {
|
||||||
const [ query, setQuery ] = useState(null);
|
const [ query, setQuery ] = useState(null);
|
||||||
|
@ -10,6 +11,12 @@ const SearchPage = ({ serverId, parentId, collectionType }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SearchFields onSearch={setQuery} />
|
<SearchFields onSearch={setQuery} />
|
||||||
|
{!query &&
|
||||||
|
<SearchSuggestions
|
||||||
|
serverId={serverId || ApiClient.serverId()}
|
||||||
|
parentId={parentId}
|
||||||
|
/>
|
||||||
|
}
|
||||||
<SearchResults
|
<SearchResults
|
||||||
serverId={serverId || ApiClient.serverId()}
|
serverId={serverId || ApiClient.serverId()}
|
||||||
parentId={parentId}
|
parentId={parentId}
|
||||||
|
|
69
src/components/search/SearchSuggestions.js
Normal file
69
src/components/search/SearchSuggestions.js
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import { appRouter } from '../appRouter';
|
||||||
|
import globalize from '../../scripts/globalize';
|
||||||
|
import ServerConnections from '../ServerConnections';
|
||||||
|
|
||||||
|
// There seems to be some compatibility issues here between
|
||||||
|
// React and our legacy web components, so we need to inject
|
||||||
|
// them as an html string for now =/
|
||||||
|
const createSuggestionLink = ({name, href}) => ({
|
||||||
|
__html: `<a
|
||||||
|
is='emby-linkbutton'
|
||||||
|
class='button-link'
|
||||||
|
style='display: inline-block; padding: 0.5em 1em;'
|
||||||
|
href='${href}'
|
||||||
|
>${name}</a>`
|
||||||
|
});
|
||||||
|
|
||||||
|
const SearchSuggestions = ({ serverId, parentId }) => {
|
||||||
|
const [ suggestions, setSuggestions ] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const apiClient = ServerConnections.getApiClient(serverId);
|
||||||
|
|
||||||
|
apiClient.getItems(apiClient.getCurrentUserId(), {
|
||||||
|
SortBy: 'IsFavoriteOrLiked,Random',
|
||||||
|
IncludeItemTypes: 'Movie,Series,MusicArtist',
|
||||||
|
Limit: 20,
|
||||||
|
Recursive: true,
|
||||||
|
ImageTypeLimit: 0,
|
||||||
|
EnableImages: false,
|
||||||
|
ParentId: parentId,
|
||||||
|
EnableTotalRecordCount: false
|
||||||
|
}).then(result => setSuggestions(result.Items));
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className='verticalSection searchSuggestions'
|
||||||
|
style={{ textAlign: 'center' }}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<h2 className='sectionTitle padded-left padded-right'>
|
||||||
|
{globalize.translate('Suggestions')}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='searchSuggestionsList padded-left padded-right'>
|
||||||
|
{suggestions.map(item => (
|
||||||
|
<div
|
||||||
|
key={`suggestion-${item.Id}`}
|
||||||
|
dangerouslySetInnerHTML={createSuggestionLink({
|
||||||
|
name: item.Name,
|
||||||
|
href: appRouter.getRouteUrl(item)
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
SearchSuggestions.propTypes = {
|
||||||
|
parentId: PropTypes.string,
|
||||||
|
serverId: PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SearchSuggestions;
|
|
@ -1,49 +1,12 @@
|
||||||
import layoutManager from '../layoutManager';
|
import layoutManager from '../layoutManager';
|
||||||
import globalize from '../../scripts/globalize';
|
import globalize from '../../scripts/globalize';
|
||||||
import cardBuilder from '../cardbuilder/cardBuilder';
|
import cardBuilder from '../cardbuilder/cardBuilder';
|
||||||
import { appRouter } from '../appRouter';
|
|
||||||
import '../../elements/emby-scroller/emby-scroller';
|
import '../../elements/emby-scroller/emby-scroller';
|
||||||
import '../../elements/emby-itemscontainer/emby-itemscontainer';
|
import '../../elements/emby-itemscontainer/emby-itemscontainer';
|
||||||
import '../../elements/emby-button/emby-button';
|
import '../../elements/emby-button/emby-button';
|
||||||
import ServerConnections from '../ServerConnections';
|
import ServerConnections from '../ServerConnections';
|
||||||
import template from './searchresults.template.html';
|
import template from './searchresults.template.html';
|
||||||
|
|
||||||
function loadSuggestions(instance, context, apiClient) {
|
|
||||||
const options = {
|
|
||||||
|
|
||||||
SortBy: 'IsFavoriteOrLiked,Random',
|
|
||||||
IncludeItemTypes: 'Movie,Series,MusicArtist',
|
|
||||||
Limit: 20,
|
|
||||||
Recursive: true,
|
|
||||||
ImageTypeLimit: 0,
|
|
||||||
EnableImages: false,
|
|
||||||
ParentId: instance.options.parentId,
|
|
||||||
EnableTotalRecordCount: false
|
|
||||||
};
|
|
||||||
|
|
||||||
apiClient.getItems(apiClient.getCurrentUserId(), options).then(function (result) {
|
|
||||||
if (instance.mode !== 'suggestions') {
|
|
||||||
result.Items = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const html = result.Items.map(function (i) {
|
|
||||||
const href = appRouter.getRouteUrl(i);
|
|
||||||
|
|
||||||
let itemHtml = '<div><a is="emby-linkbutton" class="button-link" style="display:inline-block;padding:.5em 1em;" href="' + href + '">';
|
|
||||||
itemHtml += i.Name;
|
|
||||||
itemHtml += '</a></div>';
|
|
||||||
return itemHtml;
|
|
||||||
}).join('');
|
|
||||||
|
|
||||||
const searchSuggestions = context.querySelector('.searchSuggestions');
|
|
||||||
searchSuggestions.querySelector('.searchSuggestionsList').innerHTML = html;
|
|
||||||
|
|
||||||
if (result.Items.length) {
|
|
||||||
searchSuggestions.classList.remove('hide');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSearchHints(instance, apiClient, query) {
|
function getSearchHints(instance, apiClient, query) {
|
||||||
if (!query.searchTerm) {
|
if (!query.searchTerm) {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
|
@ -149,10 +112,8 @@ function getSearchHints(instance, apiClient, query) {
|
||||||
function search(instance, apiClient, context, value) {
|
function search(instance, apiClient, context, value) {
|
||||||
if (value || layoutManager.tv) {
|
if (value || layoutManager.tv) {
|
||||||
instance.mode = 'search';
|
instance.mode = 'search';
|
||||||
context.querySelector('.searchSuggestions').classList.add('hide');
|
|
||||||
} else {
|
} else {
|
||||||
instance.mode = 'suggestions';
|
instance.mode = 'suggestions';
|
||||||
loadSuggestions(instance, context, apiClient);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instance.options.collectionType === 'livetv') {
|
if (instance.options.collectionType === 'livetv') {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue