diff --git a/package.json b/package.json index a385bfcf..c9ae4536 100644 --- a/package.json +++ b/package.json @@ -113,6 +113,7 @@ "@tailwindcss/typography": "^0.5.10", "@tanstack/table-core": "^8.11.7", "@types/hast": "^3.0.3", + "@types/is-hotkey": "^0.1.10", "@types/lodash": "^4.14.202", "@types/mdast": "^4.0.3", "@types/micromatch": "^4.0.6", @@ -127,6 +128,7 @@ "client-zip": "^2.4.4", "eslint": "^8", "eslint-config-next": "14.2.1", + "is-hotkey": "^0.2.0", "kysely-codegen": "^0.11.0", "lodash": "^4.17.21", "lucide-react": "^0.342.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2b03224f..46c206d9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -315,6 +315,9 @@ importers: '@types/hast': specifier: ^3.0.3 version: 3.0.3 + '@types/is-hotkey': + specifier: ^0.1.10 + version: 0.1.10 '@types/lodash': specifier: ^4.14.202 version: 4.14.202 @@ -357,6 +360,9 @@ importers: eslint-config-next: specifier: 14.2.1 version: 14.2.1(eslint@8.56.0)(typescript@5.3.3) + is-hotkey: + specifier: ^0.2.0 + version: 0.2.0 kysely-codegen: specifier: ^0.11.0 version: 0.11.0(kysely@0.27.2)(mysql2@3.7.1)(pg@8.11.5) @@ -5360,6 +5366,10 @@ packages: hoist-non-react-statics: 3.3.2 dev: false + /@types/is-hotkey@0.1.10: + resolution: {integrity: sha512-RvC8KMw5BCac1NvRRyaHgMMEtBaZ6wh0pyPTBu7izn4Sj/AX9Y4aXU5c7rX8PnM/knsuUpC1IeoBkANtxBypsQ==} + dev: true + /@types/js-yaml@4.0.9: resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} dev: false @@ -7929,7 +7939,7 @@ packages: eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.19.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.19.1)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.19.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.56.0) eslint-plugin-react: 7.33.2(eslint@8.56.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.56.0) @@ -7960,7 +7970,7 @@ packages: enhanced-resolve: 5.15.0 eslint: 8.56.0 eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.19.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.19.1)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.19.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) fast-glob: 3.3.2 get-tsconfig: 4.7.2 is-core-module: 2.13.1 @@ -8055,6 +8065,41 @@ packages: - supports-color dev: true + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.19.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 6.19.0(eslint@8.56.0)(typescript@5.3.3) + array-includes: 3.1.7 + array.prototype.findlastindex: 1.2.3 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.56.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.19.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) + hasown: 2.0.0 + is-core-module: 2.13.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.7 + object.groupby: 1.0.1 + object.values: 1.1.7 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.19.1)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} @@ -9466,6 +9511,10 @@ packages: /is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + /is-hotkey@0.2.0: + resolution: {integrity: sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==} + dev: true + /is-map@2.0.2: resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} dev: true diff --git a/src/components/message-input.tsx b/src/components/message-input.tsx index ecf5438e..cedd2e2e 100644 --- a/src/components/message-input.tsx +++ b/src/components/message-input.tsx @@ -6,6 +6,7 @@ import type { ChatEngine } from '@/core/repositories/chat_engine'; import type { Page } from '@/lib/database'; import { fetcher } from '@/lib/fetch'; import { cn } from '@/lib/utils'; +import isHotkey from 'is-hotkey'; import { ArrowRightIcon } from 'lucide-react'; import { useSession } from 'next-auth/react'; import { type ChangeEvent, type RefObject, useCallback, useRef, useState } from 'react'; @@ -48,7 +49,7 @@ export function MessageInput ({ { - if (!e.nativeEvent.isComposing && e.key === 'Enter' && !disabled) { + if (!e.nativeEvent.isComposing && isHotkey('mod+Enter', e) && !disabled) { e.preventDefault(); buttonRef.current?.click(); }