Search bar redirect to local search results
This commit is contained in:
parent
3d3e2eed8c
commit
da13ca6092
4 changed files with 66 additions and 25 deletions
|
@ -1,4 +1,5 @@
|
|||
### v1.7.2 (TBA)
|
||||
- Pressing Enter while search bar is focused will now redirect to first result of local search ([#121](https://github.com/pawelmalak/flame/issues/121))
|
||||
- Use search bar shortcuts when it's not focused ([#124](https://github.com/pawelmalak/flame/issues/124))
|
||||
- Fixed bug with Weather API still logging with module being disabled ([#125](https://github.com/pawelmalak/flame/issues/125))
|
||||
- Added option to disable search bar autofocus ([#127](https://github.com/pawelmalak/flame/issues/127))
|
||||
|
|
|
@ -55,17 +55,21 @@ const Home = (props: ComponentProps): JSX.Element => {
|
|||
|
||||
// Local search query
|
||||
const [localSearch, setLocalSearch] = useState<null | string>(null);
|
||||
const [appSearchResult, setAppSearchResult] = useState<null | App[]>(null);
|
||||
const [bookmarkSearchResult, setBookmarkSearchResult] = useState<
|
||||
null | Category[]
|
||||
>(null);
|
||||
|
||||
// Load applications
|
||||
useEffect(() => {
|
||||
if (apps.length === 0) {
|
||||
if (!apps.length) {
|
||||
getApps();
|
||||
}
|
||||
}, [getApps]);
|
||||
|
||||
// Load bookmark categories
|
||||
useEffect(() => {
|
||||
if (categories.length === 0) {
|
||||
if (!categories.length) {
|
||||
getCategories();
|
||||
}
|
||||
}, [getCategories]);
|
||||
|
@ -87,22 +91,37 @@ const Home = (props: ComponentProps): JSX.Element => {
|
|||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
// Search bookmarks
|
||||
const searchBookmarks = (query: string): Category[] => {
|
||||
const category = { ...categories[0] };
|
||||
category.name = 'Search Results';
|
||||
category.bookmarks = categories
|
||||
.map(({ bookmarks }) => bookmarks)
|
||||
.flat()
|
||||
.filter(({ name }) => new RegExp(query, 'i').test(name));
|
||||
useEffect(() => {
|
||||
if (localSearch) {
|
||||
// Search through apps
|
||||
setAppSearchResult([
|
||||
...apps.filter(({ name }) => new RegExp(localSearch, 'i').test(name)),
|
||||
]);
|
||||
|
||||
return [category];
|
||||
};
|
||||
// Search through bookmarks
|
||||
const category = { ...categories[0] };
|
||||
|
||||
category.name = 'Search Results';
|
||||
category.bookmarks = categories
|
||||
.map(({ bookmarks }) => bookmarks)
|
||||
.flat()
|
||||
.filter(({ name }) => new RegExp(localSearch, 'i').test(name));
|
||||
|
||||
setBookmarkSearchResult([category]);
|
||||
} else {
|
||||
setAppSearchResult(null);
|
||||
setBookmarkSearchResult(null);
|
||||
}
|
||||
}, [localSearch]);
|
||||
|
||||
return (
|
||||
<Container>
|
||||
{!props.config.hideSearch ? (
|
||||
<SearchBar setLocalSearch={setLocalSearch} />
|
||||
<SearchBar
|
||||
setLocalSearch={setLocalSearch}
|
||||
appSearchResult={appSearchResult}
|
||||
bookmarkSearchResult={bookmarkSearchResult}
|
||||
/>
|
||||
) : (
|
||||
<div></div>
|
||||
)}
|
||||
|
@ -130,11 +149,9 @@ const Home = (props: ComponentProps): JSX.Element => {
|
|||
) : (
|
||||
<AppGrid
|
||||
apps={
|
||||
!localSearch
|
||||
!appSearchResult
|
||||
? apps.filter(({ isPinned }) => isPinned)
|
||||
: apps.filter(({ name }) =>
|
||||
new RegExp(localSearch, 'i').test(name)
|
||||
)
|
||||
: appSearchResult
|
||||
}
|
||||
totalApps={apps.length}
|
||||
searching={!!localSearch}
|
||||
|
@ -154,9 +171,9 @@ const Home = (props: ComponentProps): JSX.Element => {
|
|||
) : (
|
||||
<BookmarkGrid
|
||||
categories={
|
||||
!localSearch
|
||||
!bookmarkSearchResult
|
||||
? categories.filter(({ isPinned }) => isPinned)
|
||||
: searchBookmarks(localSearch)
|
||||
: bookmarkSearchResult
|
||||
}
|
||||
totalCategories={categories.length}
|
||||
searching={!!localSearch}
|
||||
|
|
|
@ -5,7 +5,13 @@ import { connect } from 'react-redux';
|
|||
import { createNotification } from '../../store/actions';
|
||||
|
||||
// Typescript
|
||||
import { Config, GlobalState, NewNotification } from '../../interfaces';
|
||||
import {
|
||||
App,
|
||||
Category,
|
||||
Config,
|
||||
GlobalState,
|
||||
NewNotification,
|
||||
} from '../../interfaces';
|
||||
|
||||
// CSS
|
||||
import classes from './SearchBar.module.css';
|
||||
|
@ -16,12 +22,21 @@ import { searchParser, urlParser, redirectUrl } from '../../utility';
|
|||
interface ComponentProps {
|
||||
createNotification: (notification: NewNotification) => void;
|
||||
setLocalSearch: (query: string) => void;
|
||||
appSearchResult: App[] | null;
|
||||
bookmarkSearchResult: Category[] | null;
|
||||
config: Config;
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
const SearchBar = (props: ComponentProps): JSX.Element => {
|
||||
const { setLocalSearch, createNotification, config, loading } = props;
|
||||
const {
|
||||
setLocalSearch,
|
||||
createNotification,
|
||||
config,
|
||||
loading,
|
||||
appSearchResult,
|
||||
bookmarkSearchResult,
|
||||
} = props;
|
||||
|
||||
const inputRef = useRef<HTMLInputElement>(document.createElement('input'));
|
||||
|
||||
|
@ -73,8 +88,12 @@ const SearchBar = (props: ComponentProps): JSX.Element => {
|
|||
const url = urlParser(inputRef.current.value)[1];
|
||||
redirectUrl(url, sameTab);
|
||||
} else if (isLocal) {
|
||||
// Local query -> filter apps and bookmarks
|
||||
setLocalSearch(search);
|
||||
// Local query -> redirect if at least 1 result found
|
||||
if (appSearchResult?.length) {
|
||||
redirectUrl(appSearchResult[0].url, sameTab);
|
||||
} else if (bookmarkSearchResult?.length) {
|
||||
redirectUrl(bookmarkSearchResult[0].bookmarks[0].url, sameTab);
|
||||
}
|
||||
} else {
|
||||
// Valid query -> redirect to search results
|
||||
const url = `${query.template}${search}`;
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import { urlParser } from '.';
|
||||
|
||||
export const redirectUrl = (url: string, sameTab: boolean) => {
|
||||
const parsedUrl = urlParser(url)[1];
|
||||
|
||||
if (sameTab) {
|
||||
document.location.replace(url);
|
||||
document.location.replace(parsedUrl);
|
||||
} else {
|
||||
window.open(url);
|
||||
window.open(parsedUrl);
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue