From c71f9629672dfac0650eb47564ea65b6adc4ad2c Mon Sep 17 00:00:00 2001 From: ajnart Date: Tue, 22 Nov 2022 18:00:23 +0900 Subject: [PATCH 1/8] Working on spotlight module --- package.json | 1 + src/modules/index.ts | 1 + src/modules/spotlight/SpotlightModule.tsx | 107 ++++++++++++++++++++++ src/modules/spotlight/index.tsx | 1 + yarn.lock | 24 +++++ 5 files changed, 134 insertions(+) create mode 100644 src/modules/spotlight/SpotlightModule.tsx create mode 100644 src/modules/spotlight/index.tsx diff --git a/package.json b/package.json index b81ca8858..47e1b68cb 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "@mantine/next": "^5.2.3", "@mantine/notifications": "^5.7.2", "@mantine/prism": "^5.0.0", + "@mantine/spotlight": "^5.8.2", "@nivo/core": "^0.79.0", "@nivo/line": "^0.79.1", "@tabler/icons": "^1.78.0", diff --git a/src/modules/index.ts b/src/modules/index.ts index f3b7292a7..c4e86eadf 100644 --- a/src/modules/index.ts +++ b/src/modules/index.ts @@ -8,3 +8,4 @@ export * from './weather'; export * from './docker'; export * from './overseerr'; export * from './usenet'; +export * from './spotlight'; diff --git a/src/modules/spotlight/SpotlightModule.tsx b/src/modules/spotlight/SpotlightModule.tsx new file mode 100644 index 000000000..c6526257b --- /dev/null +++ b/src/modules/spotlight/SpotlightModule.tsx @@ -0,0 +1,107 @@ +import { Button, Group } from '@mantine/core'; +import { IconSearch, IconBrandYoutube, IconDownload, IconMovie } from '@tabler/icons'; +import { SpotlightProvider, openSpotlight } from '@mantine/spotlight'; +import type { SpotlightAction } from '@mantine/spotlight'; +import { useState } from 'react'; +import { IModule } from '../ModuleTypes'; + +export const SpotlightModule: IModule = { + title: 'Spotlight', + icon: IconSearch, + component: SpotlightModuleComponent, + id: 'spotlight', +}; + +interface SearchEngine { + name: string; + enabled: boolean; + description: string; + icon: React.ReactNode; + url: string; + shortcut: string; +} +const searchEngines: SearchEngine[] = [ + { + name: 'Google', + enabled: true, + description: 'Search using your search engine (defined in settings)', + icon: , + url: 'https://www.google.com/search?q=', + shortcut: 'g', + }, + { + name: 'Youtube', + enabled: true, + description: 'Search Youtube', + icon: , + url: 'https://www.youtube.com/results?search_query=', + shortcut: 'y', + }, + { + name: 'Download', + enabled: true, + description: 'Search for torrents', + icon: , + url: 'https://1337x.to/search/', + shortcut: 't', + }, + { + name: 'Movies', + icon: , + enabled: false, + description: 'Search for movies using Overseerr', + url: 'https://www.imdb.com/find?q=', + shortcut: 'm', + }, +]; + +function SpotlightControl() { + return ( + + + + ); +} + +export function SpotlightModuleComponent(props: any) { + const [selectedSearchEngine, setSearchEngine] = useState(searchEngines[0]); + const actions: SpotlightAction[] = searchEngines.map((engine) => ({ + title: engine.name, + description: engine.description, + icon: engine.icon, + onTrigger: () => { + setSearchEngine(engine); + }, + closeOnTrigger: false, + })); + return ( + + useSearchBrowser(researchString, selectedSearchEngine, setSearchEngine, searchEngines) + } + > + + + ); +} +function useSearchBrowser( + search: string, + selectedSearchEngine: SearchEngine, + setSearchEngine: React.Dispatch>, + searchEngines: SearchEngine[] +): void { + // First check if the value of search contains any shortcut + const foundSearchEngine = searchEngines.find((engine) => search.includes(`!${engine.shortcut}`)); + if (foundSearchEngine) { + // If a shortcut is found, use it + setSearchEngine(foundSearchEngine); + search.replace(`!${foundSearchEngine.shortcut}`, ''); + } else { + // If no shortcut is found, do nothing (for now) + } +} diff --git a/src/modules/spotlight/index.tsx b/src/modules/spotlight/index.tsx new file mode 100644 index 000000000..27e68ef6c --- /dev/null +++ b/src/modules/spotlight/index.tsx @@ -0,0 +1 @@ +export { SpotlightModule } from './SpotlightModule'; diff --git a/yarn.lock b/yarn.lock index 87dd94f19..d04d88e82 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1231,6 +1231,20 @@ __metadata: languageName: node linkType: hard +"@mantine/spotlight@npm:^5.8.2": + version: 5.8.2 + resolution: "@mantine/spotlight@npm:5.8.2" + dependencies: + "@mantine/utils": 5.8.2 + peerDependencies: + "@mantine/core": 5.8.2 + "@mantine/hooks": 5.8.2 + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 162eec73807649015d56359c8cdd565447b7ace86fd66705047657320be73e52e27119dc5f3b3e85367f316181b8cf9afeb18f9993cf396718fa20b5d1edccc1 + languageName: node + linkType: hard + "@mantine/ssr@npm:5.2.3": version: 5.2.3 resolution: "@mantine/ssr@npm:5.2.3" @@ -1301,6 +1315,15 @@ __metadata: languageName: node linkType: hard +"@mantine/utils@npm:5.8.2": + version: 5.8.2 + resolution: "@mantine/utils@npm:5.8.2" + peerDependencies: + react: ">=16.8.0" + checksum: bb6b1de7e8bee92751410e634e7e475ea38eef4d822ee955aa885a739c4379c8d8cbdc12aee570b6c1dcf83ae1202297f1f1c3d78b11de3e3ffe64076edd3a71 + languageName: node + linkType: hard + "@motionone/animation@npm:^10.12.0": version: 10.13.1 resolution: "@motionone/animation@npm:10.13.1" @@ -4835,6 +4858,7 @@ __metadata: "@mantine/next": ^5.2.3 "@mantine/notifications": ^5.7.2 "@mantine/prism": ^5.0.0 + "@mantine/spotlight": ^5.8.2 "@next/bundle-analyzer": ^12.1.4 "@next/eslint-plugin-next": ^12.1.4 "@nivo/core": ^0.79.0 From 940513dc32fec53aa8ea7ab4a3c8a085d2af1527 Mon Sep 17 00:00:00 2001 From: ajnart Date: Tue, 29 Nov 2022 16:22:27 +0900 Subject: [PATCH 2/8] Advancement in the new spotlight --- src/modules/spotlight/SpotlightModule.tsx | 195 +++++++++++++++------- 1 file changed, 135 insertions(+), 60 deletions(-) diff --git a/src/modules/spotlight/SpotlightModule.tsx b/src/modules/spotlight/SpotlightModule.tsx index c6526257b..3fb03528e 100644 --- a/src/modules/spotlight/SpotlightModule.tsx +++ b/src/modules/spotlight/SpotlightModule.tsx @@ -1,8 +1,21 @@ -import { Button, Group } from '@mantine/core'; -import { IconSearch, IconBrandYoutube, IconDownload, IconMovie } from '@tabler/icons'; -import { SpotlightProvider, openSpotlight } from '@mantine/spotlight'; -import type { SpotlightAction } from '@mantine/spotlight'; -import { useState } from 'react'; +import { + ActionIcon, + Group, + Kbd, + Select, + Text, + TextInput, +} from '@mantine/core'; +import { + IconSearch, + IconBrandYoutube, + IconDownload, + IconMovie, + IconBrandGoogle, +} from '@tabler/icons'; +import { forwardRef, useState } from 'react'; +import { useHotkeys } from '@mantine/hooks'; +import { showNotification } from '@mantine/notifications'; import { IModule } from '../ModuleTypes'; export const SpotlightModule: IModule = { @@ -12,95 +25,157 @@ export const SpotlightModule: IModule = { id: 'spotlight', }; -interface SearchEngine { - name: string; - enabled: boolean; - description: string; - icon: React.ReactNode; - url: string; - shortcut: string; -} -const searchEngines: SearchEngine[] = [ +const searchEngines = [ { - name: 'Google', - enabled: true, + label: 'Google', + disabled: false, description: 'Search using your search engine (defined in settings)', icon: , url: 'https://www.google.com/search?q=', shortcut: 'g', }, { - name: 'Youtube', - enabled: true, + label: 'Youtube', + disabled: false, description: 'Search Youtube', icon: , url: 'https://www.youtube.com/results?search_query=', shortcut: 'y', }, { - name: 'Download', - enabled: true, + label: 'Download', + disabled: false, description: 'Search for torrents', icon: , url: 'https://1337x.to/search/', shortcut: 't', }, { - name: 'Movies', + label: 'Movies', + disabled: true, + description: 'Search for movies using Overseerr', icon: , - enabled: false, + url: 'https://www.imdb.com/find?q=', + shortcut: 'm', + }, +]; + +const data: ItemProps[] = [ + { + icon: , + disabled: false, + label: 'Google', + value: 'google', + description: 'Search using your search engine (defined in settings)', + url: 'https://www.google.com/search?q=', + shortcut: 'g', + }, + + { + icon: , + disabled: false, + label: 'Download', + value: 'download', + description: 'Search for torrents', + url: 'https://1337x.to/search/', + shortcut: 't', + }, + { + icon: , + disabled: false, + label: 'Youtube', + value: 'youtube', + description: 'Search Youtube', + url: 'https://www.youtube.com/results?search_query=', + shortcut: 'y', + }, + { + icon: , + disabled: true, + label: 'Movies', + value: 'movies', description: 'Search for movies using Overseerr', url: 'https://www.imdb.com/find?q=', shortcut: 'm', }, ]; -function SpotlightControl() { +interface ItemProps extends React.ComponentPropsWithoutRef<'div'> { + label: string; + disabled: boolean; + value: string; + description: string; + icon: React.ReactNode; + url: string; + shortcut: string; +} + +export function SpotlightModuleComponent(props: any) { + const [selectedSearchEngine, setSearchEngine] = useState(data[0]); + + const SelectItem = forwardRef( + ({ icon, label, description, shortcut, ...others }: ItemProps, ref) => ( +
+ + + {icon} +
+ {label} + + {description} + +
+
+ {shortcut} +
+
+ ) + ); + + const [opened, setOpened] = useState(false); + useHotkeys([['mod+K', () => setOpened(!opened)]]); return ( - - + + - setSearchEngine( - data.find((item) => item.label.toLowerCase().includes(search.toLowerCase())) || - selectedSearchEngine - ) - } - withinPortal - defaultValue={selectedSearchEngine.value} - itemComponent={SelectItem} - data={data} - maxDropdownHeight={400} - /> - - - ); -} - -function tryMatchSearch( - query: string, - selectedSearchEngine: ItemProps, - setSearchEngine: React.Dispatch>, - searchEngines: ItemProps[] -): void { - // First check if the value of search contains any shortcut. Make sure it is not disabled - const foundSearchEngine = searchEngines.find( - (engine) => query.includes(`!${engine.shortcut}`) && !engine.disabled - ); - if (foundSearchEngine) { - // If a shortcut is found, use it. Except if it is disabled - setSearchEngine(foundSearchEngine); - showNotification({ - radius: 'lg', - disallowClose: true, - id: 'spotlight', - autoClose: 1000, - icon: {foundSearchEngine.icon}, - message: `Using ${foundSearchEngine.label} as search engine`, - }); - } else { - // If no shortcut is found, do nothing (for now) - } -} diff --git a/src/modules/spotlight/index.tsx b/src/modules/spotlight/index.tsx deleted file mode 100644 index 27e68ef6c..000000000 --- a/src/modules/spotlight/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { SpotlightModule } from './SpotlightModule'; diff --git a/yarn.lock b/yarn.lock index d04d88e82..87dd94f19 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1231,20 +1231,6 @@ __metadata: languageName: node linkType: hard -"@mantine/spotlight@npm:^5.8.2": - version: 5.8.2 - resolution: "@mantine/spotlight@npm:5.8.2" - dependencies: - "@mantine/utils": 5.8.2 - peerDependencies: - "@mantine/core": 5.8.2 - "@mantine/hooks": 5.8.2 - react: ">=16.8.0" - react-dom: ">=16.8.0" - checksum: 162eec73807649015d56359c8cdd565447b7ace86fd66705047657320be73e52e27119dc5f3b3e85367f316181b8cf9afeb18f9993cf396718fa20b5d1edccc1 - languageName: node - linkType: hard - "@mantine/ssr@npm:5.2.3": version: 5.2.3 resolution: "@mantine/ssr@npm:5.2.3" @@ -1315,15 +1301,6 @@ __metadata: languageName: node linkType: hard -"@mantine/utils@npm:5.8.2": - version: 5.8.2 - resolution: "@mantine/utils@npm:5.8.2" - peerDependencies: - react: ">=16.8.0" - checksum: bb6b1de7e8bee92751410e634e7e475ea38eef4d822ee955aa885a739c4379c8d8cbdc12aee570b6c1dcf83ae1202297f1f1c3d78b11de3e3ffe64076edd3a71 - languageName: node - linkType: hard - "@motionone/animation@npm:^10.12.0": version: 10.13.1 resolution: "@motionone/animation@npm:10.13.1" @@ -4858,7 +4835,6 @@ __metadata: "@mantine/next": ^5.2.3 "@mantine/notifications": ^5.7.2 "@mantine/prism": ^5.0.0 - "@mantine/spotlight": ^5.8.2 "@next/bundle-analyzer": ^12.1.4 "@next/eslint-plugin-next": ^12.1.4 "@nivo/core": ^0.79.0 From be1901d40dad1f140c4110c9f701b0e8427997d2 Mon Sep 17 00:00:00 2001 From: Thomas Camlong <49837342+ajnart@users.noreply.github.com> Date: Tue, 29 Nov 2022 21:06:11 +0900 Subject: [PATCH 8/8] Update SearchModule.tsx --- src/modules/search/SearchModule.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/search/SearchModule.tsx b/src/modules/search/SearchModule.tsx index 2974e3c29..0842272a4 100644 --- a/src/modules/search/SearchModule.tsx +++ b/src/modules/search/SearchModule.tsx @@ -48,7 +48,7 @@ const useStyles = createStyles((theme) => ({ }, })); -export function SearchModuleComponent(props: any) { +export function SearchModuleComponent() { const { config } = useConfig(); const { t } = useTranslation('modules/search'); const [searchQuery, setSearchQuery] = useState('');