1
0
Fork 0
mirror of https://github.com/pawelmalak/flame.git synced 2025-08-03 09:55:18 +02:00
flame/client/src/components/SearchBar/SearchBar.tsx

109 lines
2.8 KiB
TypeScript
Raw Normal View History

import { useRef, useEffect, KeyboardEvent } from 'react';
// Redux
import { connect } from 'react-redux';
import { createNotification } from '../../store/actions';
// Typescript
import { Config, GlobalState, NewNotification } from '../../interfaces';
// CSS
import classes from './SearchBar.module.css';
// Utils
2021-10-06 12:01:07 +02:00
import { searchParser, urlParser, redirectUrl } from '../../utility';
interface ComponentProps {
createNotification: (notification: NewNotification) => void;
2021-09-06 12:24:01 +02:00
setLocalSearch: (query: string) => void;
config: Config;
loading: boolean;
}
const SearchBar = (props: ComponentProps): JSX.Element => {
const { setLocalSearch, createNotification, config, loading } = props;
2021-09-06 12:24:01 +02:00
const inputRef = useRef<HTMLInputElement>(document.createElement('input'));
// Search bar autofocus
useEffect(() => {
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);
}, []);
2021-10-13 13:31:01 +02:00
const clearSearch = () => {
inputRef.current.value = '';
setLocalSearch('');
};
const searchHandler = (e: KeyboardEvent<HTMLInputElement>) => {
2021-10-06 12:01:07 +02:00
const { isLocal, search, query, isURL, sameTab } = searchParser(
inputRef.current.value
);
2021-09-06 12:47:17 +02:00
2021-10-06 12:01:07 +02:00
if (isLocal) {
setLocalSearch(search);
2021-09-06 12:47:17 +02:00
}
2021-10-13 13:31:01 +02:00
if (e.code === 'Enter' || e.code === 'NumpadEnter') {
2021-10-06 12:01:07 +02:00
if (!query.prefix) {
2021-10-13 13:31:01 +02:00
// Prefix not found -> emit notification
2021-09-06 12:24:01 +02:00
createNotification({
title: 'Error',
2021-09-06 12:24:01 +02:00
message: 'Prefix not found',
});
2021-10-06 12:01:07 +02:00
} else if (isURL) {
2021-10-13 13:31:01 +02:00
// URL or IP passed -> redirect
2021-10-06 12:01:07 +02:00
const url = urlParser(inputRef.current.value)[1];
redirectUrl(url, sameTab);
} else if (isLocal) {
2021-10-13 13:31:01 +02:00
// Local query -> filter apps and bookmarks
2021-10-06 12:01:07 +02:00
setLocalSearch(search);
2021-09-06 12:47:17 +02:00
} else {
2021-10-13 13:31:01 +02:00
// Valid query -> redirect to search results
2021-10-06 12:01:07 +02:00
const url = `${query.template}${search}`;
redirectUrl(url, sameTab);
}
2021-10-13 13:31:01 +02:00
} else if (e.code === 'Escape') {
clearSearch();
}
2021-09-06 12:24:01 +02:00
};
return (
2021-10-13 13:31:01 +02:00
<div className={classes.SearchContainer}>
<input
ref={inputRef}
type="text"
className={classes.SearchBar}
onKeyUp={(e) => searchHandler(e)}
onDoubleClick={clearSearch}
2021-10-13 13:31:01 +02:00
/>
</div>
2021-09-06 12:24:01 +02:00
);
};
const mapStateToProps = (state: GlobalState) => {
return {
config: state.config.config,
loading: state.config.loading,
};
};
export default connect(mapStateToProps, { createNotification })(SearchBar);