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