|
@@ -5,7 +5,13 @@ import { connect } from 'react-redux';
|
|
|
import { createNotification } from '../../store/actions';
|
|
|
|
|
|
// Typescript
|
|
|
-import { NewNotification } from '../../interfaces';
|
|
|
+import {
|
|
|
+ App,
|
|
|
+ Category,
|
|
|
+ Config,
|
|
|
+ GlobalState,
|
|
|
+ NewNotification,
|
|
|
+} from '../../interfaces';
|
|
|
|
|
|
// CSS
|
|
|
import classes from './SearchBar.module.css';
|
|
@@ -16,15 +22,44 @@ 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 } = props;
|
|
|
+ const {
|
|
|
+ setLocalSearch,
|
|
|
+ createNotification,
|
|
|
+ config,
|
|
|
+ loading,
|
|
|
+ appSearchResult,
|
|
|
+ bookmarkSearchResult,
|
|
|
+ } = props;
|
|
|
|
|
|
const inputRef = useRef<HTMLInputElement>(document.createElement('input'));
|
|
|
|
|
|
+ // Search bar autofocus
|
|
|
useEffect(() => {
|
|
|
- inputRef.current.focus();
|
|
|
+ if (!loading && !config.disableAutofocus) {
|
|
|
+ inputRef.current.focus();
|
|
|
+ }
|
|
|
+ }, [config]);
|
|
|
+
|
|
|
+ // Listen for keyboard events outside of search bar
|
|
|
+ useEffect(() => {
|
|
|
+ const keyOutsideFocus = (e: any) => {
|
|
|
+ const { key } = e as KeyboardEvent;
|
|
|
+
|
|
|
+ if (key === 'Escape') {
|
|
|
+ clearSearch();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ window.addEventListener('keydown', keyOutsideFocus);
|
|
|
+
|
|
|
+ return () => window.removeEventListener('keydown', keyOutsideFocus);
|
|
|
}, []);
|
|
|
|
|
|
const clearSearch = () => {
|
|
@@ -53,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}`;
|
|
@@ -78,4 +117,11 @@ const SearchBar = (props: ComponentProps): JSX.Element => {
|
|
|
);
|
|
|
};
|
|
|
|
|
|
-export default connect(null, { createNotification })(SearchBar);
|
|
|
+const mapStateToProps = (state: GlobalState) => {
|
|
|
+ return {
|
|
|
+ config: state.config.config,
|
|
|
+ loading: state.config.loading,
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+export default connect(mapStateToProps, { createNotification })(SearchBar);
|