diff --git a/components/Navbar.tsx b/components/Navbar.tsx index 8dbedd5..3c24540 100644 --- a/components/Navbar.tsx +++ b/components/Navbar.tsx @@ -2,6 +2,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { IconName } from '@fortawesome/fontawesome-svg-core' import { Dialog, Transition } from '@headlessui/react' import toast, { Toaster } from 'react-hot-toast' +import { useHotkeys } from 'react-hotkeys-hook' import Link from 'next/link' import Image from 'next/image' @@ -10,15 +11,20 @@ import { Fragment, useEffect, useState } from 'react' import siteConfig from '../config/site.json' import SearchModal from './SearchModal' +import useDeviceOS from '../utils/useDeviceOS' const Navbar = () => { const router = useRouter() + const os = useDeviceOS() + const [tokenPresent, setTokenPresent] = useState(false) const [isOpen, setIsOpen] = useState(false) const [searchOpen, setSearchOpen] = useState(false) const openSearchBox = () => setSearchOpen(true) + useHotkeys(`${os === 'mac' ? 'cmd' : 'ctrl'}+k`, openSearchBox) + useEffect(() => { const storedToken = () => { for (const r of siteConfig.protectedRoutes) { @@ -60,11 +66,20 @@ const Navbar = () => {
{siteConfig.links.length !== 0 && diff --git a/components/SearchModal.tsx b/components/SearchModal.tsx index dcf6196..5b9e7ae 100644 --- a/components/SearchModal.tsx +++ b/components/SearchModal.tsx @@ -2,13 +2,11 @@ import axios from 'axios' import AwesomeDebouncePromise from 'awesome-debounce-promise' import { useAsync } from 'react-async-hook' import useConstant from 'use-constant' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { Dispatch, FC, Fragment, SetStateAction, useState } from 'react' import { Dialog, Transition } from '@headlessui/react' - import Link from 'next/link' -import Image from 'next/image' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { OdSearchResult } from '../types' import { getFileIcon } from '../utils/getFileIcon' diff --git a/package-lock.json b/package-lock.json index 66f8251..0797d6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "react-copy-to-clipboard": "^5.0.3", "react-dom": "^17.0.2", "react-hot-toast": "^2.0.0", + "react-hotkeys-hook": "^3.4.4", "react-markdown": "^6.0.2", "react-player": "^2.9.0", "react-reader": "^0.20.4", @@ -3446,6 +3447,11 @@ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, + "node_modules/hotkeys-js": { + "version": "3.8.7", + "resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.8.7.tgz", + "integrity": "sha512-ckAx3EkUr5XjDwjEHDorHxRO2Kb7z6Z2Sxul4MbBkN8Nho7XDslQsgMJT+CiJ5Z4TgRxxvKHEpuLE3imzqy4Lg==" + }, "node_modules/html-void-elements": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.0.tgz", @@ -5803,6 +5809,18 @@ "react-dom": ">=16" } }, + "node_modules/react-hotkeys-hook": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/react-hotkeys-hook/-/react-hotkeys-hook-3.4.4.tgz", + "integrity": "sha512-vaORq07rWgmuF3owWRhgFV/3VL8/l2q9lz0WyVEddJnWTtKW+AOgU5YgYKuwN6h6h7bCcLG3MFsJIjCrM/5DvQ==", + "dependencies": { + "hotkeys-js": "3.8.7" + }, + "peerDependencies": { + "react": ">=16.8.1", + "react-dom": ">=16.8.1" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -10034,6 +10052,11 @@ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, + "hotkeys-js": { + "version": "3.8.7", + "resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.8.7.tgz", + "integrity": "sha512-ckAx3EkUr5XjDwjEHDorHxRO2Kb7z6Z2Sxul4MbBkN8Nho7XDslQsgMJT+CiJ5Z4TgRxxvKHEpuLE3imzqy4Lg==" + }, "html-void-elements": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.0.tgz", @@ -11761,6 +11784,14 @@ "goober": "^2.0.35" } }, + "react-hotkeys-hook": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/react-hotkeys-hook/-/react-hotkeys-hook-3.4.4.tgz", + "integrity": "sha512-vaORq07rWgmuF3owWRhgFV/3VL8/l2q9lz0WyVEddJnWTtKW+AOgU5YgYKuwN6h6h7bCcLG3MFsJIjCrM/5DvQ==", + "requires": { + "hotkeys-js": "3.8.7" + } + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", diff --git a/package.json b/package.json index eadb520..376f2de 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "react-copy-to-clipboard": "^5.0.3", "react-dom": "^17.0.2", "react-hot-toast": "^2.0.0", + "react-hotkeys-hook": "^3.4.4", "react-markdown": "^6.0.2", "react-player": "^2.9.0", "react-reader": "^0.20.4", diff --git a/utils/useDeviceOS.ts b/utils/useDeviceOS.ts new file mode 100644 index 0000000..232e03f --- /dev/null +++ b/utils/useDeviceOS.ts @@ -0,0 +1,21 @@ +import { useEffect, useState } from 'react' + +export default function useDeviceOS(): string { + const [os, setOS] = useState('') + + useEffect(() => { + const userAgent = window.navigator.userAgent + + if (userAgent.indexOf('Windows') > -1) { + setOS('windows') + } else if (userAgent.indexOf('Mac OS') > -1) { + setOS('mac') + } else if (userAgent.indexOf('Linux') > -1) { + setOS('linux') + } else { + setOS('other') + } + }, []) + + return os +}