diff --git a/.husky/pre-commit b/.husky/pre-commit index d2ae35e84b..3723623171 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - yarn lint-staged diff --git a/.storybook/manager.js b/.storybook/manager.js index c82fceac05..a8b23a6a9a 100644 --- a/.storybook/manager.js +++ b/.storybook/manager.js @@ -1,8 +1,8 @@ // .storybook/manager.js -import { addons } from '@storybook/addons'; +import { addons } from '@storybook/manager-api'; import theme from './QDCTheme'; addons.setConfig({ theme, -}); \ No newline at end of file +}); diff --git a/quranic-calendar.json b/data/quranic-calendar.json similarity index 100% rename from quranic-calendar.json rename to data/quranic-calendar.json diff --git a/next.config.js b/next.config.js index 7434d430a8..2bbf9b0666 100644 --- a/next.config.js +++ b/next.config.js @@ -7,19 +7,32 @@ const withBundleAnalyzer = require('@next/bundle-analyzer')({ enabled: process.env.ANALYZE_BUNDLE === 'true', }); const { withSentryConfig } = require('@sentry/nextjs'); -const withPlugins = require('next-compose-plugins'); const withFonts = require('next-fonts'); const withPWA = require('next-pwa'); -const nextTranslate = require('next-translate'); -const withTM = require('next-transpile-modules')(['remotion', '@remotion/cli', '@remotion/player']); +const nextTranslate = require('next-translate-plugin'); const securityHeaders = require('./configs/SecurityHeaders.js'); const runtimeCaching = require('./pwa-runtime-config.js'); const isDev = process.env.NEXT_PUBLIC_VERCEL_ENV === 'development'; const isProduction = process.env.NEXT_PUBLIC_VERCEL_ENV === 'production'; -const config = { - productionBrowserSourceMaps: true, // {@see https://nextjs.org/docs/advanced-features/source-maps} +const withPWAConfig = withPWA({ + dest: 'public', + disable: !isProduction, + mode: isProduction ? 'production' : 'development', + publicExcludes: [ + '!fonts/**/!(sura_names|ProximaVara)*', // exclude pre-caching all fonts that are not sura_names or ProximaVara + '!icons/**', // exclude all icons + '!images/**/!(background|homepage)*', // don't pre-cache except background.jpg and homepage.png + ], + runtimeCaching, +}); + +/** @type {import('next').NextConfig} */ +const nextConfig = { + reactStrictMode: true, + productionBrowserSourceMaps: true, + swcMinify: true, images: { formats: ['image/avif', 'image/webp'], domains: [ @@ -31,18 +44,6 @@ const config = { 'images.quran.com', ], }, - pwa: { - disable: !isProduction, - dest: 'public', - mode: isProduction ? 'production' : 'development', - runtimeCaching, - publicExcludes: [ - '!fonts/**/!(sura_names|ProximaVara)*', // exclude pre-caching all fonts that are not sura_names or ProximaVara - '!icons/**', // exclude all icons - '!images/**/!(background|homepage)*', // don't pre-cache except background.jpg and homepage.png - ], - }, - // this is needed to support importing audioWorklet nodes. {@see https://github.com/webpack/webpack/issues/11543#issuecomment-826897590} webpack: (webpackConfig) => { webpackConfig.resolve = { ...webpackConfig.resolve, @@ -88,18 +89,7 @@ const config = { return webpackConfig; }, - SentryWebpackPluginOptions: { - // Additional config options for the Sentry Webpack plugin. Keep in mind that - // the following options are set automatically, and overriding them is not - // recommended: - // release, url, org, project, authToken, configFile, stripPrefix, - // urlPrefix, include, ignore - - silent: true, // Suppresses all logs - // For all available options, see: - // https://github.com/getsentry/sentry-webpack-plugin#options. - }, - async headers() { + headers: async () => { return isDev ? [] : [ @@ -136,39 +126,50 @@ const config = { }, ]; }, - async redirects() { - return [ - { - source: '/:surah/:from(\\d{1,})\\::to(\\d{1,})', // 1/2:3 => 1/2-3 - destination: '/:surah/:from-:to', - permanent: true, - }, - { - source: '/:surah\\::from(\\d{1,})\\::to(\\d{1,})', // 1:2:3 => 1/2-3 - destination: '/:surah/:from-:to', - permanent: true, - }, - { - source: '/:surah(\\d{1,})-:from\\::to', // 1-2:3 => 1/2-3 - destination: '/:surah/:from-:to', - permanent: true, - }, - { - source: '/:surah(\\d{1,})-:from(\\d{1,})-:to(\\d{1,})', // 1-2-3 => 1/2-3 - destination: '/:surah/:from-:to', - permanent: true, - }, - { - source: '/:surah(\\d{1,})\\::from(\\d{1,})-:to(\\d{1,})', // 1:2-3 => 1/2-3 - destination: '/:surah/:from-:to', - permanent: true, - }, - ]; + redirects: async () => [ + { + source: '/:surah/:from(\\d{1,})\\::to(\\d{1,})', // 1/2:3 => 1/2-3 + destination: '/:surah/:from-:to', + permanent: true, + }, + { + source: '/:surah\\::from(\\d{1,})\\::to(\\d{1,})', // 1:2:3 => 1/2-3 + destination: '/:surah/:from-:to', + permanent: true, + }, + { + source: '/:surah(\\d{1,})-:from\\::to', // 1-2:3 => 1/2-3 + destination: '/:surah/:from-:to', + permanent: true, + }, + { + source: '/:surah(\\d{1,})-:from(\\d{1,})-:to(\\d{1,})', // 1-2-3 => 1/2-3 + destination: '/:surah/:from-:to', + permanent: true, + }, + { + source: '/:surah(\\d{1,})\\::from(\\d{1,})-:to(\\d{1,})', // 1:2-3 => 1/2-3 + destination: '/:surah/:from-:to', + permanent: true, + }, + ], + compiler: { + removeConsole: !isDev, }, }; -// eslint-disable-next-line max-lines -module.exports = withPlugins( - [withTM, withBundleAnalyzer, withPWA, withFonts, nextTranslate, withSentryConfig], - config, +// Apply plugins +const configWithPlugins = withBundleAnalyzer(withFonts(nextTranslate(withPWAConfig(nextConfig)))); + +// Apply Sentry configuration +module.exports = withSentryConfig( + configWithPlugins, + { + silent: true, + }, + { + hideSourceMaps: !isDev, + // Additional config options for the Sentry Webpack plugin + // ... (any additional Sentry options) + }, ); diff --git a/package.json b/package.json index 29f1b931f6..0b27b54090 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "postpack": "pinst --enable" }, "dependencies": { - "@babel/eslint-parser": "^7.19.1", + "@babel/eslint-parser": "^7.25.1", "@milkdown/core": "^7.5.0", "@milkdown/ctx": "^7.5.0", "@milkdown/kit": "^7.5.5", @@ -46,31 +46,31 @@ "@milkdown/react": "^7.5.0", "@milkdown/transformer": "^7.5.0", "@milkdown/utils": "^7.5.0", - "@next/bundle-analyzer": "^12.3.1", + "@next/bundle-analyzer": "^14.2.7", "@novu/headless": "0.24.0", - "@radix-ui/react-checkbox": "^1.0.0", - "@radix-ui/react-collapsible": "^1.0.0", - "@radix-ui/react-dialog": "^1.0.5", - "@radix-ui/react-direction": "^1.0.1", - "@radix-ui/react-dropdown-menu": "^2.0.6", - "@radix-ui/react-hover-card": "^1.0.7", - "@radix-ui/react-id": "^1.0.1", + "@radix-ui/react-checkbox": "^1.1.1", + "@radix-ui/react-collapsible": "^1.1.0", + "@radix-ui/react-dialog": "^1.1.1", + "@radix-ui/react-direction": "^1.1.0", + "@radix-ui/react-dropdown-menu": "^2.1.1", + "@radix-ui/react-hover-card": "^1.1.1", + "@radix-ui/react-id": "^1.1.0", "@radix-ui/react-polymorphic": "^0.0.14", - "@radix-ui/react-popover": "^1.0.7", - "@radix-ui/react-progress": "^1.0.3", - "@radix-ui/react-radio-group": "^1.1.3", - "@radix-ui/react-separator": "^1.0.3", - "@radix-ui/react-slider": "^1.1.2", - "@radix-ui/react-switch": "^1.0.3", - "@radix-ui/react-tabs": "^1.0.4", - "@radix-ui/react-tooltip": "^1.0.7", - "@radix-ui/react-visually-hidden": "^1.0.3", - "@reduxjs/toolkit": "^1.8.5", - "@remotion/bundler": "4.0.126", - "@remotion/cli": "4.0.126", - "@remotion/eslint-plugin": "4.0.126", - "@remotion/lambda": "4.0.126", - "@remotion/player": "4.0.126", + "@radix-ui/react-popover": "^1.1.1", + "@radix-ui/react-progress": "^1.1.0", + "@radix-ui/react-radio-group": "^1.2.0", + "@radix-ui/react-separator": "^1.1.0", + "@radix-ui/react-slider": "^1.2.0", + "@radix-ui/react-switch": "^1.1.0", + "@radix-ui/react-tabs": "^1.1.0", + "@radix-ui/react-tooltip": "^1.1.2", + "@radix-ui/react-visually-hidden": "^1.1.0", + "@reduxjs/toolkit": "^2.2.7", + "@remotion/bundler": "4.0.206", + "@remotion/cli": "4.0.206", + "@remotion/eslint-plugin": "4.0.206", + "@remotion/lambda": "4.0.206", + "@remotion/player": "4.0.206", "@sanity/client": "^5.2.1", "@sanity/image-url": "^1.0.2", "@sentry/nextjs": "^7.77.0", @@ -88,66 +88,68 @@ "humps": "^2.0.1", "js-cookie": "^3.0.1", "lodash": "^4.17.21", - "next": "^12.1.5", + "next": "^14.2.6", "next-compose-plugins": "^2.2.0", "next-fonts": "^1.0.3", "next-pwa": "^5.6.0", - "next-seo": "^5.5.0", - "next-translate": "^1.6.0", - "next-transpile-modules": "9.0.0", + "next-seo": "^6.5.0", + "next-translate": "^2.6.2", + "next-translate-plugin": "^2.6.2", "node-fetch": "2", "querystring": "^0.2.1", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.3.1", + "react-dom": "^18.3.1", "react-hook-form": "^7.36.1", - "react-hotkeys-hook": "^3.4.7", + "react-hotkeys-hook": "^4.5.0", "react-joyride": "^2.7.2", - "react-redux": "^8.0.4", + "react-redux": "^9.1.2", "react-toastify": "^9.0.8", "react-virtuoso": "^2.19.0", - "redux": "^4.2.0", + "redux": "^5.0.1", "redux-persist": "^6.0.0", "refresh-fetch": "^0.8.0", "remark-directive": "^3.0.0", - "remotion": "4.0.126", + "remotion": "4.0.206", "swr": "1.2.1", "xstate": "^4.33.6" }, "devDependencies": { "@lokalise/node-api": "^12.7.0", "@next/eslint-plugin-next": "^12.3.1", - "@playwright/test": "^1.26.0", - "@storybook/addon-a11y": "^7.6.4", - "@storybook/addon-actions": "^7.6.4", - "@storybook/addon-essentials": "^7.6.4", - "@storybook/addon-links": "^7.6.4", - "@storybook/addon-storysource": "^7.6.4", - "@storybook/addon-styling-webpack": "^0.0.5", - "@storybook/nextjs": "^7.6.4", - "@storybook/react": "^7.6.4", - "@svgr/webpack": "^6.3.1", + "@playwright/test": "^1.46.1", + "@storybook/addon-a11y": "^8.2.9", + "@storybook/addon-actions": "^8.2.9", + "@storybook/addon-essentials": "^8.2.9", + "@storybook/addon-links": "^8.2.9", + "@storybook/addon-storysource": "^8.2.9", + "@storybook/addon-styling-webpack": "^1.0.0", + "@storybook/nextjs": "^8.2.9", + "@storybook/react": "^8.2.9", + "@svgr/webpack": "^8.1.0", "@testing-library/react": "^13.4.0", - "@types/cookie": "^0.5.1", + "@types/cookie": "^0.6.0", "@types/js-cookie": "^3.0.2", - "@types/lodash": "^4.14.184", - "@types/node": "^20.10.4", + "@types/lodash": "^4.17.7", + "@types/node": "^22.5.0", "@types/node-fetch": "^2.6.2", - "@types/qs": "^6.9.7", - "@types/react": "^18.2.45", - "@types/react-dom": "^18.2.17", + "@types/qs": "^6.9.15", + "@types/react": "^18.3.4", + "@types/react-dom": "^18.3.0", "@types/react-redux": "^7.1.23", "@types/refresh-fetch": "^0.6.1", "@types/wicg-mediasession": "^1.1.3", "@typescript-eslint/eslint-plugin": "^6.14.0", "@typescript-eslint/parser": "^6.14.0", - "@vitejs/plugin-react": "^2.1.0", - "@vitest/coverage-c8": "^0.23.4", + "@vitejs/plugin-react": "^4.3.1", + "@vitest/coverage-c8": "^0.33.0", + "@vitest/coverage-v8": "^2.0.5", "adm-zip": "^0.5.9", + "browserify-fs": "^1.0.0", "cross-env": "^7.0.3", "dotenv": "^16.0.2", "eslint": "^8.24.0", "eslint-config-airbnb": "^19.0.4", - "eslint-config-next": "^14.0.4", + "eslint-config-next": "^14.2.6", "eslint-config-prettier": "^8.5.0", "eslint-plugin-i18next": "^6.0.0-4", "eslint-plugin-import": "^2.26.0", @@ -160,30 +162,31 @@ "eslint-plugin-sonarjs": "^0.15.0", "eslint-plugin-storybook": "^0.6.15", "eslint-plugin-unicorn": "^43.0.2", - "husky": "^9.0.11", + "husky": "^9.1.5", "inquirer": "^8.0.0", "inquirer-file-tree-selection-prompt": "^1", "jsdom": "^20.0.0", - "lint-staged": "^13.0.3", + "lint-staged": "^15.2.9", "next-sitemap": "^3.1.22", "pinst": "^3.0.0", - "postcss": "8", + "postcss": "8.4.41", "postcss-scss": "^4.0.5", "prettier": "^2.7.1", "react-docgen-typescript-loader": "^3.7.2", "replace-in-file": "^6.3.5", - "sass": "^1.55.0", - "sass-loader": "^13.0.2", - "storybook": "^7.6.4", - "storybook-addon-rtl": "^1.0.0", + "require-npm": "^1.4.1", + "sass": "^1.77.8", + "sass-loader": "^16.0.1", + "storybook": "^8.2.9", + "storybook-addon-rtl": "^1.0.1", "stylelint": "14.12.1", "stylelint-prettier": "^2.0.0", "stylelint-scss": "^4.3.0", "stylelint-use-logical": "^2.0.0", - "superagent": "^10.1.0", - "typescript": "^4.8.3", - "vite": "^3.2.5", - "vitest": "^0.23.4" + "superagent": "^8.0.0", + "typescript": "^5.5.4", + "vite": "^5.4.2", + "vitest": "^2.0.5" }, "husky": { "hooks": { diff --git a/src/audioInput/MicInputProcessor.ts b/public/worklets/MicInputProcessor.js similarity index 71% rename from src/audioInput/MicInputProcessor.ts rename to public/worklets/MicInputProcessor.js index 9fe31986c3..91ca4811f0 100644 --- a/src/audioInput/MicInputProcessor.ts +++ b/public/worklets/MicInputProcessor.js @@ -1,5 +1,5 @@ class MicInputProcessor extends AudioWorkletProcessor { - process(inputs: Float32Array[][]) { + process(inputs) { // get the first channel of the first input since the processor might have multiple inputs and multiple channels for each input. // then after converting the data, send it to the AudioWorkletNode that is listening to messages from the processors. this.port.postMessage(convertFloat32ToInt16(inputs[0][0])); @@ -7,9 +7,9 @@ class MicInputProcessor extends AudioWorkletProcessor { } } -const convertFloat32ToInt16 = (buffer: Float32Array): Int16Array => { - let float32BufferLength: number = buffer.length; - const int16ArrayBuffer: Int16Array = new Int16Array(float32BufferLength); +const convertFloat32ToInt16 = (buffer) => { + let float32BufferLength = buffer.length; + const int16ArrayBuffer = new Int16Array(float32BufferLength); // eslint-disable-next-line no-plusplus while (float32BufferLength--) { int16ArrayBuffer[float32BufferLength] = Math.min(1, buffer[float32BufferLength]) * 0x7fff; @@ -19,4 +19,3 @@ const convertFloat32ToInt16 = (buffer: Float32Array): Int16Array => { }; registerProcessor('MicInputProcessor', MicInputProcessor); -export default MicInputProcessor; diff --git a/remotion.config.ts b/remotion.config.ts index e45390988c..2dbb749826 100644 --- a/remotion.config.ts +++ b/remotion.config.ts @@ -1,32 +1,16 @@ import path from 'path'; import { Config } from '@remotion/cli/config'; -// eslint-disable-next-line import/no-extraneous-dependencies -import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; + +import getRemotionWebpackConfig from './src/utils/media/webpackConfig.mjs'; Config.setPublicDir(path.join(process.cwd(), 'public', 'publicMin')); -// @ts-ignore -Config.overrideWebpackConfig((config) => { - return { - ...config, - module: { - ...config.module, - rules: [ - ...(config.module?.rules ? config.module.rules : []), - { - test: /.s[ac]ss$/i, - use: [ - { loader: 'style-loader' }, - { loader: 'css-loader' }, - { loader: 'sass-loader', options: { sourceMap: true } }, - ], - }, - ], - }, - resolve: { - ...config.resolve, - plugins: [...(config.resolve?.plugins ?? []), new TsconfigPathsPlugin()], - }, - }; -}); +Config.overrideWebpackConfig((config) => + getRemotionWebpackConfig(config, { + stream: require.resolve('stream-browserify'), + zlib: require.resolve('browserify-zlib'), + fs: require.resolve('browserify-fs'), + path: require.resolve('path-browserify'), + }), +); diff --git a/scripts/media/deploy.mjs b/scripts/media/deploy.mjs index ac584c7a7f..de3d3e26c6 100644 --- a/scripts/media/deploy.mjs +++ b/scripts/media/deploy.mjs @@ -1,11 +1,16 @@ +import { createRequire } from 'module'; import path, { dirname } from 'path'; import { fileURLToPath } from 'url'; import { deployFunction, deploySite, getOrCreateBucket } from '@remotion/lambda'; // eslint-disable-next-line import/no-extraneous-dependencies import dotenv from 'dotenv'; -// eslint-disable-next-line import/no-extraneous-dependencies -import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; +import requireNPM from 'require-npm'; + +import getRemotionWebpackConfig from '../../src/utils/media/webpackConfig.mjs'; + +const require = createRequire(import.meta.url); +requireNPM.decorate(require); const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); @@ -48,28 +53,13 @@ const { serveUrl } = await deploySite({ console.log(`Webpack bundling progress: ${progress}%`); }, // eslint-disable-next-line react-func/max-lines-per-function - webpackOverride: (webpackConfig) => { - return { - ...webpackConfig, - resolve: { - ...webpackConfig.resolve, - plugins: [...(webpackConfig.resolve?.plugins ?? []), new TsconfigPathsPlugin()], - }, - module: { - ...webpackConfig.module, - rules: [ - ...(webpackConfig.module?.rules ? webpackConfig.module.rules : []), - { - test: /.s[ac]ss$/i, - use: [ - { loader: 'style-loader' }, - { loader: 'css-loader' }, - { loader: 'sass-loader', options: { sourceMap: true } }, - ], - }, - ], - }, - }; + webpackOverride: (config) => { + return getRemotionWebpackConfig(config, { + stream: require.resolve('stream-browserify'), + zlib: require.resolve('browserify-zlib'), + fs: require.resolve('browserify-fs'), + path: require.resolve('path-browserify'), + }); }, }, }); diff --git a/src/api.ts b/src/api.ts index 06f3f93786..f70a27c84c 100644 --- a/src/api.ts +++ b/src/api.ts @@ -2,6 +2,7 @@ import { camelizeKeys } from 'humps'; import { NextApiRequest } from 'next'; +import { MushafLines, QuranFont } from '@/types/QuranReader'; import { SearchRequestParams, SearchMode } from '@/types/Search/SearchRequestParams'; import NewSearchResponse from '@/types/Search/SearchResponse'; import { @@ -51,7 +52,6 @@ import { WordByWordTranslationsResponse, } from 'types/ApiResponses'; import AudioData from 'types/AudioData'; -import { MushafLines, QuranFont } from 'types/QuranReader'; export const SEARCH_FETCH_OPTIONS = { headers: { diff --git a/src/components/Collection/CollectionList/CollectionList.tsx b/src/components/Collection/CollectionList/CollectionList.tsx index 1e7cd18069..3c8fca3568 100644 --- a/src/components/Collection/CollectionList/CollectionList.tsx +++ b/src/components/Collection/CollectionList/CollectionList.tsx @@ -116,7 +116,7 @@ const CollectionList = () => {
- +
{t('collection:all-saved-verses')}
@@ -138,7 +138,7 @@ const CollectionList = () => { return (
- +
{collection.name}
diff --git a/src/components/CommandBar/CommandBarBody/index.tsx b/src/components/CommandBar/CommandBarBody/index.tsx index 0d8c3d24d2..8b6eb35075 100644 --- a/src/components/CommandBar/CommandBarBody/index.tsx +++ b/src/components/CommandBar/CommandBarBody/index.tsx @@ -18,12 +18,12 @@ import useDebounce from '@/hooks/useDebounce'; import IconSearch from '@/icons/search.svg'; import { selectRecentNavigations } from '@/redux/slices/CommandBar/state'; import { selectIsCommandBarVoiceFlowStarted } from '@/redux/slices/voiceSearch'; +import { SearchNavigationResult, SearchNavigationType } from '@/types/SearchNavigationResult'; import SearchQuerySource from '@/types/SearchQuerySource'; import { makeSearchResultsUrl } from '@/utils/apiPaths'; import { areArraysEqual } from '@/utils/array'; import { logButtonClick, logTextSearchQuery } from '@/utils/eventLogger'; import { SearchResponse } from 'types/ApiResponses'; -import { SearchNavigationType } from 'types/SearchNavigationResult'; const NAVIGATE_TO = [ { @@ -62,7 +62,10 @@ const DEBOUNCING_PERIOD_MS = 1500; const CommandBarBody: React.FC = () => { const { t } = useTranslation('common'); - const recentNavigations = useSelector(selectRecentNavigations, areArraysEqual); + const recentNavigations = useSelector( + selectRecentNavigations, + areArraysEqual, + ) as SearchNavigationResult[]; const isVoiceSearchFlowStarted = useSelector(selectIsCommandBarVoiceFlowStarted, shallowEqual); const [searchQuery, setSearchQuery] = useState(null); // Debounce search query to avoid having to call the API on every type. The API will be called once the user stops typing. diff --git a/src/components/CommandBar/CommandsList/index.tsx b/src/components/CommandBar/CommandsList/index.tsx index 523b0e5ad6..503cb2cc25 100644 --- a/src/components/CommandBar/CommandsList/index.tsx +++ b/src/components/CommandBar/CommandsList/index.tsx @@ -87,7 +87,7 @@ const CommandsList: React.FC = ({ commandGroups: { groups, numberOfComman onUpKeyClicked, { enabled: numberOfCommands && selectedCommandIndex !== 0, - enableOnTags: ['INPUT'], + enableOnFormTags: ['INPUT'], }, [scrollToSelectedCommand], ); @@ -96,7 +96,7 @@ const CommandsList: React.FC = ({ commandGroups: { groups, numberOfComman onDownKeyClicked, { enabled: numberOfCommands && selectedCommandIndex !== numberOfCommands - 1, - enableOnTags: ['INPUT'], + enableOnFormTags: ['INPUT'], }, [scrollToSelectedCommand], ); @@ -114,7 +114,7 @@ const CommandsList: React.FC = ({ commandGroups: { groups, numberOfComman }); navigateToLink(navigateTo); }, - { enabled: selectedCommandIndex !== null, enableOnTags: ['INPUT'] }, + { enabled: selectedCommandIndex !== null, enableOnFormTags: ['INPUT'] }, [selectedCommandIndex, groups, navigateToLink], ); const onRemoveCommandClicked = ( diff --git a/src/components/CommandBar/index.tsx b/src/components/CommandBar/index.tsx index f167b03638..83354c9f3e 100644 --- a/src/components/CommandBar/index.tsx +++ b/src/components/CommandBar/index.tsx @@ -57,10 +57,15 @@ const CommandBar: React.FC = () => { }, [dispatch], ); - useHotkeys('cmd+k, ctrl+k, cmd+p, ctrl+p', toggleShowCommandBar, { enableOnTags: ['INPUT'] }, [ + useHotkeys( + 'meta+k, ctrl+k, meta+p, ctrl+p', + toggleShowCommandBar, + { enableOnFormTags: ['INPUT'] }, + [dispatch], + ); + useHotkeys('Escape', closeCommandBar, { enabled: isOpen, enableOnFormTags: ['INPUT'] }, [ dispatch, ]); - useHotkeys('Escape', closeCommandBar, { enabled: isOpen, enableOnTags: ['INPUT'] }, [dispatch]); return ( closeCommandBar()}> diff --git a/src/components/DeveloperUtility/FontAdjustment.tsx b/src/components/DeveloperUtility/FontAdjustment.tsx index 6a73e19538..086d7a7991 100644 --- a/src/components/DeveloperUtility/FontAdjustment.tsx +++ b/src/components/DeveloperUtility/FontAdjustment.tsx @@ -16,7 +16,7 @@ import { decreaseTranslationFontScale, increaseTranslationFontScale, } from '@/redux/slices/QuranReader/styles'; -import { QuranFont } from 'types/QuranReader'; +import { QuranFont } from '@/types/QuranReader'; /** * Adjusts the font type and styles diff --git a/src/components/DeveloperUtility/ReadingPreferenceAdjustment.tsx b/src/components/DeveloperUtility/ReadingPreferenceAdjustment.tsx index 43872b64ee..afdb124d74 100644 --- a/src/components/DeveloperUtility/ReadingPreferenceAdjustment.tsx +++ b/src/components/DeveloperUtility/ReadingPreferenceAdjustment.tsx @@ -7,7 +7,7 @@ import { selectReadingPreference, setReadingPreference, } from '@/redux/slices/QuranReader/readingPreferences'; -import { ReadingPreference } from 'types/QuranReader'; +import { ReadingPreference } from '@/types/QuranReader'; const ReadingPreferenceAdjustment = () => { const dispatch = useDispatch(); diff --git a/src/components/DeveloperUtility/TafsirsAdjustment.tsx b/src/components/DeveloperUtility/TafsirsAdjustment.tsx index 042c6aeb21..53f78aa99d 100644 --- a/src/components/DeveloperUtility/TafsirsAdjustment.tsx +++ b/src/components/DeveloperUtility/TafsirsAdjustment.tsx @@ -67,7 +67,7 @@ const TafsirsAdjustment = () => { multiple className={styles.select} onChange={onSelectedTafsirsChange} - defaultValue={selectedTafsirs} + defaultValue={selectedTafsirs as string[]} > {tafsirs.map((tafsir) => (