From da13ca6092c2e41b77138654f1f87fe089a92842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Wed, 27 Oct 2021 11:52:57 +0200 Subject: [PATCH] Search bar redirect to local search results --- CHANGELOG.md | 1 + client/src/components/Home/Home.tsx | 55 ++++++++++++------- client/src/components/SearchBar/SearchBar.tsx | 27 +++++++-- client/src/utility/redirectUrl.ts | 8 ++- 4 files changed, 66 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f57ca1..3eae525 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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)) diff --git a/client/src/components/Home/Home.tsx b/client/src/components/Home/Home.tsx index 18d81bc..4a0adbe 100644 --- a/client/src/components/Home/Home.tsx +++ b/client/src/components/Home/Home.tsx @@ -55,17 +55,21 @@ const Home = (props: ComponentProps): JSX.Element => { // Local search query const [localSearch, setLocalSearch] = useState(null); + const [appSearchResult, setAppSearchResult] = useState(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 ( {!props.config.hideSearch ? ( - + ) : (
)} @@ -130,11 +149,9 @@ const Home = (props: ComponentProps): JSX.Element => { ) : ( 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 => { ) : ( isPinned) - : searchBookmarks(localSearch) + : bookmarkSearchResult } totalCategories={categories.length} searching={!!localSearch} diff --git a/client/src/components/SearchBar/SearchBar.tsx b/client/src/components/SearchBar/SearchBar.tsx index c20b457..7a91525 100644 --- a/client/src/components/SearchBar/SearchBar.tsx +++ b/client/src/components/SearchBar/SearchBar.tsx @@ -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(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}`; diff --git a/client/src/utility/redirectUrl.ts b/client/src/utility/redirectUrl.ts index 81eca10..533f5d2 100644 --- a/client/src/utility/redirectUrl.ts +++ b/client/src/utility/redirectUrl.ts @@ -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); } };