diff --git a/package-lock.json b/package-lock.json index 033f0f2..c06aeb7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,31 +8,32 @@ "name": "triggerfrontend", "version": "1.0.0", "dependencies": { + "@gfazioli/mantine-text-animate": "^2.2.5", "@hello-pangea/dnd": "^18.0.1", - "@mantine/core": "^8.2.7", - "@mantine/form": "^8.2.7", - "@mantine/hooks": "^8.2.7", - "@mantine/notifications": "^8.2.7", - "@tanstack/react-query": "^5.85.5", - "@tanstack/react-query-devtools": "^5.85.5", - "@tanstack/react-query-persist-client": "^5.85.5", + "@mantine/core": "^8.2.8", + "@mantine/form": "^8.2.8", + "@mantine/hooks": "^8.2.8", + "@mantine/notifications": "^8.2.8", + "@tanstack/react-query": "^5.85.9", + "@tanstack/react-query-devtools": "^5.85.9", + "@tanstack/react-query-persist-client": "^5.85.9", "idb-keyval": "^6.2.2", "jotai": "^2.13.1", "react": "^19.1.1", "react-dom": "^19.1.1", "react-icons": "^5.5.0", - "react-router-dom": "^7.8.1", + "react-router-dom": "^7.8.2", "recharts": "^3.1.2" }, "devDependencies": { "@types/node": "^24.3.0", - "@types/react": "^19.1.9", - "@types/react-dom": "^19.1.7", - "@vitejs/plugin-react": "^5.0.1", + "@types/react": "^19.1.12", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.2", "@vitest/coverage-v8": "^3.2.4", "@vitest/ui": "^3.2.4", "typescript": "^5.9.2", - "vite": "^7.1.3", + "vite": "^7.1.4", "vite-plugin-dts": "~4.5.4", "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.2.4" @@ -822,6 +823,18 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==" }, + "node_modules/@gfazioli/mantine-text-animate": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@gfazioli/mantine-text-animate/-/mantine-text-animate-2.2.5.tgz", + "integrity": "sha512-g3QhHPn9qmeWr5Xuq59Tze6d4aXI/gyhQkwWWZ64BS1vey9FMms6lsNQm1v4u+p5Uqx/NqrLDDqphn+S0CIgRQ==", + "license": "MIT", + "peerDependencies": { + "@mantine/core": ">=7.0.0", + "@mantine/hooks": ">=7.0.0", + "react": "^18.x || ^19.x", + "react-dom": "^18.x || ^19.x" + } + }, "node_modules/@hello-pangea/dnd": { "version": "18.0.1", "resolved": "https://registry.npmjs.org/@hello-pangea/dnd/-/dnd-18.0.1.tgz", @@ -930,9 +943,9 @@ } }, "node_modules/@mantine/core": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@mantine/core/-/core-8.2.7.tgz", - "integrity": "sha512-gfVDf/qFxt66PrsktYEJt/MZbiNo3KCx6PxKKcskSe/J2g5g1kf4nhhvBFlYaicDX93PfT4MgTnipyfJQ09NDA==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@mantine/core/-/core-8.2.8.tgz", + "integrity": "sha512-dybAXrlQ+QiIhpnVCkdH6P4Sjm9I9RymYXfDp97oj9KfGRMEJGLDdPAwp/2GhXe7UdDkzqD48JCkbfRWF2Q+qA==", "license": "MIT", "dependencies": { "@floating-ui/react": "^0.26.28", @@ -943,15 +956,15 @@ "type-fest": "^4.27.0" }, "peerDependencies": { - "@mantine/hooks": "8.2.7", + "@mantine/hooks": "8.2.8", "react": "^18.x || ^19.x", "react-dom": "^18.x || ^19.x" } }, "node_modules/@mantine/form": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@mantine/form/-/form-8.2.7.tgz", - "integrity": "sha512-bhOygfZMo+vOX37xBhUCCiOdudNMFQzxm/DOHzwIhGsrmgdhyV0Kof/+zDEfj1/09GtjFP9ecYvmnL5zhZv+6w==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@mantine/form/-/form-8.2.8.tgz", + "integrity": "sha512-edigaUCmyxoPcqhMgkgJHXRgbzR1tym88xQNNgfGA1KYc9gr0BTk/3dOa5B93HIVdO9/DEXZwYKN4cjrKPDY+g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -962,34 +975,34 @@ } }, "node_modules/@mantine/hooks": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-8.2.7.tgz", - "integrity": "sha512-DV0RdFBI0g0Bu7CWipIIiPK6d8+pTNXTbIOF4N+VZ6LAIpZPk5ldtb8sGaTVyQtQhEjrChrCxfkrLiNGTOAwiw==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-8.2.8.tgz", + "integrity": "sha512-KK1krCcXizWT6JF8gWexv58imQBbviylAJqSqdZ4zUPgrpe81ehMyfxo5Z9EZsnSwMxkB4RLMhCCJhC5g8GvLA==", "license": "MIT", "peerDependencies": { "react": "^18.x || ^19.x" } }, "node_modules/@mantine/notifications": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-8.2.7.tgz", - "integrity": "sha512-KXtueabwBIbgl1M5vmjzGBt88AOwhxkhmvQhEDC6UvGPtIlf4jw0BT0i3a54AKc1YwSCs0bUd91jKg5Oem2wpw==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-8.2.8.tgz", + "integrity": "sha512-luNksAUkROoMzKCB/30nQ8o38wt54ktylbpBcTrAcjE1q00nH/IEYLS58iUYGf8l/xGBV1KH8jgSik58iqk++A==", "license": "MIT", "dependencies": { - "@mantine/store": "8.2.7", + "@mantine/store": "8.2.8", "react-transition-group": "4.4.5" }, "peerDependencies": { - "@mantine/core": "8.2.7", - "@mantine/hooks": "8.2.7", + "@mantine/core": "8.2.8", + "@mantine/hooks": "8.2.8", "react": "^18.x || ^19.x", "react-dom": "^18.x || ^19.x" } }, "node_modules/@mantine/store": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@mantine/store/-/store-8.2.7.tgz", - "integrity": "sha512-TQye6nRFDOQ+HQovQSjQlFHrivn6NqdiZAuytszOnB9jqgKSzPqQxK0mEynAxJsomaO9K1rrj7clZcPNgZc+Pw==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@mantine/store/-/store-8.2.8.tgz", + "integrity": "sha512-xma5vcJlcR2UN6NZj0Rhskfppmz6wUTY/52EBU9sKZw60e1iiuTX2Bk/sfUa34VKZF4cRS46VLz2qstyCJne4Q==", "license": "MIT", "peerDependencies": { "react": "^18.x || ^19.x" @@ -1186,9 +1199,9 @@ } }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.32", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.32.tgz", - "integrity": "sha512-QReCdvxiUZAPkvp1xpAg62IeNzykOFA6syH2CnClif4YmALN1XKpB39XneL80008UbtMShthSVDKmrx05N1q/g==", + "version": "1.0.0-beta.34", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.34.tgz", + "integrity": "sha512-LyAREkZHP5pMom7c24meKmJCdhf2hEyvam2q0unr3or9ydwDL+DJ8chTF6Av/RFPb3rH8UFBdMzO5MxTZW97oA==", "dev": true, "license": "MIT" }, @@ -1629,9 +1642,9 @@ "license": "MIT" }, "node_modules/@tanstack/query-core": { - "version": "5.85.5", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.85.5.tgz", - "integrity": "sha512-KO0WTob4JEApv69iYp1eGvfMSUkgw//IpMnq+//cORBzXf0smyRwPLrUvEe5qtAEGjwZTXrjxg+oJNP/C00t6w==", + "version": "5.85.9", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.85.9.tgz", + "integrity": "sha512-5fxb9vwyftYE6KFLhhhDyLr8NO75+Wpu7pmTo+TkwKmMX2oxZDoLwcqGP8ItKSpUMwk3urWgQDZfyWr5Jm9LsQ==", "license": "MIT", "funding": { "type": "github", @@ -1649,12 +1662,12 @@ } }, "node_modules/@tanstack/query-persist-client-core": { - "version": "5.85.5", - "resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.85.5.tgz", - "integrity": "sha512-2JQiyiTVaaUu8pwPqOp6tjNa64ZN+0T9eZ3lfksV4le1VuG99fTcAYmZFIydvzwWlSM7GEF/1kpl5bwW2Y1qfQ==", + "version": "5.85.9", + "resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.85.9.tgz", + "integrity": "sha512-er7HfMjn6TQanWG5nudjRNZbo7ahf7IIdWN5kU7L2qRZ2kcw89TQZAZ74GIQsumOXZD7sUcHG2dylveFZNxlZA==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.85.5" + "@tanstack/query-core": "5.85.9" }, "funding": { "type": "github", @@ -1662,12 +1675,12 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.85.5", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.85.5.tgz", - "integrity": "sha512-/X4EFNcnPiSs8wM2v+b6DqS5mmGeuJQvxBglmDxl6ZQb5V26ouD2SJYAcC3VjbNwqhY2zjxVD15rDA5nGbMn3A==", + "version": "5.85.9", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.85.9.tgz", + "integrity": "sha512-2T5zgSpcOZXGkH/UObIbIkGmUPQqZqn7esVQFXLOze622h4spgWf5jmvrqAo9dnI13/hyMcNsF1jsoDcb59nJQ==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.85.5" + "@tanstack/query-core": "5.85.9" }, "funding": { "type": "github", @@ -1678,9 +1691,9 @@ } }, "node_modules/@tanstack/react-query-devtools": { - "version": "5.85.5", - "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.85.5.tgz", - "integrity": "sha512-6Ol6Q+LxrCZlQR4NoI5181r+ptTwnlPG2t7H9Sp3klxTBhYGunONqcgBn2YKRPsaKiYM8pItpKMdMXMEINntMQ==", + "version": "5.85.9", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.85.9.tgz", + "integrity": "sha512-BAdhgwpzxkC1vdyCfiPbbC7FU/t/x6q2d9ZyhON/WykVUdznD69nlppuWpSIlIGipdRG7sF6tRZ6x3GtSq0EUQ==", "license": "MIT", "dependencies": { "@tanstack/query-devtools": "5.84.0" @@ -1690,24 +1703,24 @@ "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "@tanstack/react-query": "^5.85.5", + "@tanstack/react-query": "^5.85.9", "react": "^18 || ^19" } }, "node_modules/@tanstack/react-query-persist-client": { - "version": "5.85.5", - "resolved": "https://registry.npmjs.org/@tanstack/react-query-persist-client/-/react-query-persist-client-5.85.5.tgz", - "integrity": "sha512-KzISZPtJtWZAwH/Ln1FclaiHVwdeV04WX7wUYLe1vw7zyfcPljHeyXlmVf8nxhFm8ujMBdGQVzP2iNn6ehzjQA==", + "version": "5.85.9", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-persist-client/-/react-query-persist-client-5.85.9.tgz", + "integrity": "sha512-h75Xyt/XDtk1oRmli5znQRXclT/iZpseTK7ScqEjaiZmPSREgg2mJb1blo2SB1swSidDNsCtnENLNH43PP0/9w==", "license": "MIT", "dependencies": { - "@tanstack/query-persist-client-core": "5.85.5" + "@tanstack/query-persist-client-core": "5.85.9" }, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "@tanstack/react-query": "^5.85.5", + "@tanstack/react-query": "^5.85.9", "react": "^18 || ^19" } }, @@ -1856,9 +1869,9 @@ } }, "node_modules/@types/react": { - "version": "19.1.9", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.9.tgz", - "integrity": "sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA==", + "version": "19.1.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz", + "integrity": "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1866,9 +1879,9 @@ } }, "node_modules/@types/react-dom": { - "version": "19.1.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.7.tgz", - "integrity": "sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw==", + "version": "19.1.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.9.tgz", + "integrity": "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -1882,16 +1895,16 @@ "license": "MIT" }, "node_modules/@vitejs/plugin-react": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.0.1.tgz", - "integrity": "sha512-DE4UNaBXwtVoDJ0ccBdLVjFTWL70NRuWNCxEieTI3lrq9ORB9aOCQEKstwDXBl87NvFdbqh/p7eINGyj0BthJA==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.0.2.tgz", + "integrity": "sha512-tmyFgixPZCx2+e6VO9TNITWcCQl8+Nl/E8YbAyPVv85QCc7/A3JrdfG2A8gIzvVhWuzMOVrFW1aReaNxrI6tbw==", "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.28.3", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-beta.32", + "@rolldown/pluginutils": "1.0.0-beta.34", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, @@ -3694,9 +3707,9 @@ } }, "node_modules/react-router": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.8.1.tgz", - "integrity": "sha512-5cy/M8DHcG51/KUIka1nfZ2QeylS4PJRs6TT8I4PF5axVsI5JUxp0hC0NZ/AEEj8Vw7xsEoD7L/6FY+zoYaOGA==", + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.8.2.tgz", + "integrity": "sha512-7M2fR1JbIZ/jFWqelpvSZx+7vd7UlBTfdZqf6OSdF9g6+sfdqJDAWcak6ervbHph200ePlu+7G8LdoiC3ReyAQ==", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -3716,12 +3729,12 @@ } }, "node_modules/react-router-dom": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.8.1.tgz", - "integrity": "sha512-NkgBCF3sVgCiAWIlSt89GR2PLaksMpoo3HDCorpRfnCEfdtRPLiuTf+CNXvqZMI5SJLZCLpVCvcZrTdtGW64xQ==", + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.8.2.tgz", + "integrity": "sha512-Z4VM5mKDipal2jQ385H6UBhiiEDlnJPx6jyWsTYoZQdl5TrjxEV2a9yl3Fi60NBJxYzOTGTTHXPi0pdizvTwow==", "license": "MIT", "dependencies": { - "react-router": "7.8.1" + "react-router": "7.8.2" }, "engines": { "node": ">=20.0.0" @@ -4517,9 +4530,9 @@ } }, "node_modules/vite": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.3.tgz", - "integrity": "sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.4.tgz", + "integrity": "sha512-X5QFK4SGynAeeIt+A7ZWnApdUyHYm+pzv/8/A57LqSGcI88U6R6ipOs3uCesdc6yl7nl+zNO0t8LmqAdXcQihw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index b6c3ab4..95fcf79 100644 --- a/package.json +++ b/package.json @@ -10,31 +10,32 @@ "preview": "vite preview" }, "dependencies": { + "@gfazioli/mantine-text-animate": "^2.2.5", "@hello-pangea/dnd": "^18.0.1", - "@mantine/core": "^8.2.7", - "@mantine/form": "^8.2.7", - "@mantine/hooks": "^8.2.7", - "@mantine/notifications": "^8.2.7", - "@tanstack/react-query": "^5.85.5", - "@tanstack/react-query-devtools": "^5.85.5", - "@tanstack/react-query-persist-client": "^5.85.5", + "@mantine/core": "^8.2.8", + "@mantine/form": "^8.2.8", + "@mantine/hooks": "^8.2.8", + "@mantine/notifications": "^8.2.8", + "@tanstack/react-query": "^5.85.9", + "@tanstack/react-query-devtools": "^5.85.9", + "@tanstack/react-query-persist-client": "^5.85.9", "idb-keyval": "^6.2.2", "jotai": "^2.13.1", "react": "^19.1.1", "react-dom": "^19.1.1", "react-icons": "^5.5.0", - "react-router-dom": "^7.8.1", + "react-router-dom": "^7.8.2", "recharts": "^3.1.2" }, "devDependencies": { "@types/node": "^24.3.0", - "@types/react": "^19.1.9", - "@types/react-dom": "^19.1.7", - "@vitejs/plugin-react": "^5.0.1", + "@types/react": "^19.1.12", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.2", "@vitest/coverage-v8": "^3.2.4", "@vitest/ui": "^3.2.4", "typescript": "^5.9.2", - "vite": "^7.1.3", + "vite": "^7.1.4", "vite-plugin-dts": "~4.5.4", "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.2.4" diff --git a/src/App.tsx b/src/App.tsx index 08b7f43..915e2c1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -18,6 +18,7 @@ import { import { Loading, MainLayout } from './components'; import '@mantine/core/styles.css'; import '@mantine/notifications/styles.css'; +import '@gfazioli/mantine-text-animate/styles.css'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import { Homepage, Settings } from 'pages'; import type { Theme, ThemePlaylist } from 'types'; diff --git a/src/components/MainLayout.tsx b/src/components/MainLayout.tsx index af2d8f5..353c887 100644 --- a/src/components/MainLayout.tsx +++ b/src/components/MainLayout.tsx @@ -10,7 +10,7 @@ export function MainLayout() { className={boxClasses.layoutContainer} style={{ '--image-background': - theme.backgroundImage === 'none' + theme.backgroundImage.toLocaleLowerCase() === 'none' ? undefined : `linear-gradient(${theme.backgroundColor}33, ${theme.backgroundColor}33), url(../../api/backgroundImages/${theme.backgroundImage})`, }} diff --git a/src/hooks/useCommonHooks.ts b/src/hooks/useCommonHooks.ts index 98d7121..a775d56 100644 --- a/src/hooks/useCommonHooks.ts +++ b/src/hooks/useCommonHooks.ts @@ -8,7 +8,7 @@ import { useMutationAPI } from './useAPI'; export function useCommonHooks() { const { mutateAsync } = useMutationAPI(); const isMobile = window.matchMedia('(max-width: 600px)').matches; - const [theme, setTheme] = useAtom(appTheme); + const [theme, setTheme] = useAtom(appTheme); const [themeName, setThemeName] = useLocalStorage({ key: 'theme', defaultValue: 'random', diff --git a/src/pages/homepage/components/Search/Search.tsx b/src/pages/homepage/components/Search/Search.tsx index 2d8b9c0..133bd68 100644 --- a/src/pages/homepage/components/Search/Search.tsx +++ b/src/pages/homepage/components/Search/Search.tsx @@ -1,5 +1,13 @@ -import { Group, type OptionsFilter, Overlay, Select, Stack, Text } from '@mantine/core'; -import { useDisclosure } from '@mantine/hooks'; +import { + Card, + Group, + type OptionsFilter, + Overlay, + Select, + Stack, + Text, +} from '@mantine/core'; +import { useDisclosure, useElementSize } from '@mantine/hooks'; import { HelpModal, WeatherModal } from 'components'; import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks'; import { useEffect, useState } from 'react'; @@ -9,6 +17,7 @@ import * as vsc from 'react-icons/vsc'; import { selectClasses } from 'styles'; import type { Application, + Bookmark, CurrentWeather, ExtendedForecast, Provider, @@ -29,6 +38,7 @@ export default function Search({ closeWeatherModal: () => void; openWeatherModal: () => void; }) { + const { ref, height } = useElementSize(); const allIcons: any = { ...fa6, ...vsc, ...si }; const { data: providerData, isFetched: providerDataIsFetched } = useQueryAPI({ endpoint: 'api/providers', @@ -37,11 +47,15 @@ export default function Search({ const { data: applicationData, isFetching: isApplicationDataFetching } = useQueryAPI({ endpoint: 'api/enabledApplications', }); + const { data: bookmarkData, isFetched: bookmarksIsFetched } = useQueryAPI({ + endpoint: 'api/bookmarks', + }); const { data: defaultProviderData, isFetched: defaultProviderDataIsFetched } = useQueryAPI({ endpoint: 'api/providers/default', }); const [applications, setApplications] = useState([]); + const [bookmarks, setBookmarks] = useState([]); const searchEndpoint = 'api/searchHistory'; const { data: historyData, isFetched: historyDataIsFetched } = useQueryAPI({ endpoint: searchEndpoint, @@ -52,7 +66,7 @@ export default function Search({ const [providerModalOpened, { open: openProviderModal, close: closeProviderModal }] = useDisclosure(false); const [dropdownOpened, { open: openDropdown, close: closeDropdown }] = useDisclosure(); - const [listIndex, setListIndex] = useState(0); + const [listIndex, setListIndex] = useState(-1); const { isMobile, urlPattern, @@ -73,9 +87,12 @@ export default function Search({ } = useCommonHooks(); const [placeholderValue, setPlaceholderValue] = useState(''); const [value, setValue] = useState(0); + const [historyMult, setHistoryMult] = useState(1); const handleResetSearch = () => { setSearchValue(''); + setListIndex(-1); + setHistoryMult(1); setProviderLabel(defaultProviderLabel); setProviderURL(defaultProviderURL); }; @@ -137,7 +154,7 @@ export default function Search({ if (/^(https?:\/\/).*/i.test(item.target.value)) window.location = item.target.value; else open(`https://${item.target.value}`, '_self'); - } else { + } else if (item.target.value !== '') { mutateAsync({ method: 'POST', endpoint: searchEndpoint, @@ -145,13 +162,15 @@ export default function Search({ }).then(() => { open(`${providerURL}${subtext}`, '_self'); }); + } else { + open(`${providerURL}${subtext}`, '_self'); } } }; const handleKeyUp = (item: any) => { if (item.code === 'Escape') { - setListIndex(0); + setListIndex(-1); handleResetSearch(); setPlaceholderValue(''); if (dropdownOpened) { @@ -277,17 +296,28 @@ export default function Search({ }; }); } - return options - .filter((option: any) => { - return splittedSearch.every((searchWord) => - option.value - .toLowerCase() - .trim() - .split(' ') - .some((word: string) => word.includes(searchWord)), - ); - }) - .slice(0, 10); + return [ + ...options + .filter((option: any) => { + return splittedSearch.every((searchWord) => + option.value + .toLowerCase() + .trim() + .split(' ') + .some((word: string) => word.includes(searchWord)), + ); + }) + .slice(0, 10 * historyMult), + { + label: 'Load more history...', + value: 'load', + id: 0, + dateTimeStamp: '', + prefix: '', + provider: '', + searchTerm: '', + }, + ]; }; useEffect(() => { @@ -302,11 +332,23 @@ export default function Search({ } }, [applicationData, isApplicationDataFetching]); + useEffect(() => { + if (bookmarkData && bookmarksIsFetched) { + setBookmarks( + bookmarkData.filter( + (bookmark: Bookmark) => + bookmark.enabled === 1 && + bookmark.name.toLowerCase().includes(searchValue.toLowerCase()), + ), + ); + } + }, [bookmarksIsFetched, bookmarkData, searchValue]); + useEffect(() => { if (historyData && historyDataIsFetched) { setSearchHistory(historyData); if (filteredHistory.length === 0) { - setFilteredHistory(historyData.slice(0, 10)); + setFilteredHistory(historyData.slice(0, 10 * historyMult)); } } }, [historyData, historyDataIsFetched]); @@ -323,15 +365,13 @@ export default function Search({ useEffect(() => { const splittedSearch = searchValue.toLowerCase().trim().split(' '); - const filtered = searchHistory - .filter((item: SearchHistoryItem) => { - const option = `${item.prefix} ${item.searchTerm}`; - const words = option.toLowerCase().trim().split(' '); - return splittedSearch.every((searchWord) => - words.some((word: string) => word.includes(searchWord)), - ); - }) - .slice(0, 10); + const filtered = searchHistory.filter((item: SearchHistoryItem) => { + const option = `${item.prefix} ${item.searchTerm}`; + const words = option.toLowerCase().trim().split(' '); + return splittedSearch.every((searchWord) => + words.some((word: string) => word.includes(searchWord)), + ); + }); setFilteredHistory(filtered); }, [searchValue]); @@ -344,7 +384,6 @@ export default function Search({ setDefaultProviderLabel(defaultProviderData[0]?.name ?? 'Google Search'); } }, [defaultProviderData, defaultProviderDataIsFetched]); - return ( <> {dropdownOpened && } @@ -358,8 +397,12 @@ export default function Search({ display: 'inline-block', gap: 0, }} + align='center' + justify='center' + w={'100%'} > !a.backgroundImage.toLowerCase().includes('none'), - ).length === 0, - }, - { - value: 'No Backgrounds', - label: 'No Backgrounds', - disabled: - allThemes.filter((a: any) => - a.backgroundImage.toLowerCase().includes('none'), - ).length === 0, - }, - ...(themePlaylistData - ?.map((playlist: ThemePlaylist) => { - return { - value: playlist.name, - label: playlist.name, - disabled: JSON.parse(playlist.themeList).length === 0, - }; - }) - .toSorted((a: ComboboxItem, b: ComboboxItem) => - a.label.localeCompare(b.label), - ) ?? []), - ]} - w='92%' - classNames={{ - root: selectClasses.menuSelectRoot, - input: selectClasses.menuSelectInput, - label: selectClasses.menuSelectLabel, - options: selectClasses.menuSelectOptions, - option: selectClasses.menuSelectOption, - }} - comboboxProps={{ - withinPortal: false, - position: 'top', - }} - onChange={(_value, option: ComboboxItem) => { - setCurrentThemePlaylist(option.value); - if (option.value !== 'Time of Day') { - setThemeName('random'); - } else { - const themeList = JSON.parse( - themePlaylistData.find((t: ThemePlaylist) => t.name === 'Time of Day') - .themeList, - ); - setThemeName( - allThemeData.find( - (t: Theme) => - t.id === Number(themeList[Math.floor(new Date().getHours() / 6)]), - ).name, - ); + +