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
+}