From 999602bae3a2b267a68fd2d8e55282bbfe979501 Mon Sep 17 00:00:00 2001 From: Baidyanath Sarkar <73095526+badrivlog@users.noreply.github.com> Date: Sun, 19 Nov 2023 16:31:34 +0530 Subject: [PATCH 1/4] fix: resolve mobile keyboard fluctuation during search (#9248) * fix: resolve mobile keyboard fluctuation during search fixed the issue where the mobile keyboard would intermittently disappear and reappear during searches by replacing the usage of `router.replace` with `window.history.replaceState`. * Revert "fix: resolve mobile keyboard fluctuation during search" This reverts commit 6cd81f02183e15d3e27d5513a58082b59354ced6. these changes are not robust solution for this issue * fix: replace useEffect with useLayoutEffect hook * refactor: use optional chaining instead of if statement * revert useLayoutEffect hook solution * fix: implemented URL search params search functionality When a user searches for user profile and submit the search form or clicked on the tag, the URL params will be updated, data will be fetched on the server, and the search page will re-render with the new data. * fix: input field ui * fix: keyword params * fix: rename variable searchTerm to searchInputVal * fix: use next/router instead next/navigation * refactor: small useEffect improvements * fix: add search button * fix: username * fix: search test --------- Co-authored-by: Eddie Jaoude --- pages/search.js | 165 ++++++++++++++++++++++++------------------- tests/search.spec.js | 6 ++ 2 files changed, 100 insertions(+), 71 deletions(-) diff --git a/pages/search.js b/pages/search.js index 573ba5ec179..5a0cb5adeb4 100755 --- a/pages/search.js +++ b/pages/search.js @@ -16,6 +16,7 @@ import { searchTagNameInInput, } from "@services/utils/search/tags"; import { PROJECT_NAME } from "@constants/index"; +import Button from "@components/Button"; async function fetchUsersByKeyword(keyword) { const res = await fetch( @@ -72,16 +73,16 @@ export default function Search({ data: { tags, recentlyUpdatedUsers, filteredUsers }, BASE_URL, }) { - const router = useRouter(); - const { username, keyword, userSearchParam } = router.query; + const { replace, query, pathname } = useRouter(); + const { username, keyword, userSearchParam } = query; const [notFound, setNotFound] = useState(); - const [users, setUsers] = useState(keyword ? filteredUsers : recentlyUpdatedUsers); - const [inputValue, setInputValue] = useState( - username || keyword || userSearchParam || "", + const [users, setUsers] = useState( + keyword ? filteredUsers : recentlyUpdatedUsers, ); const [currentPage, setCurrentPage] = useState(1); const searchInputRef = useRef(null); + const searchTerm = username || keyword || userSearchParam; useEffect(() => { if (username) { @@ -95,14 +96,24 @@ export default function Search({ }, []); useEffect(() => { - if (!inputValue) { - //Setting the users as null when the input field is empty - setUsers(recentlyUpdatedUsers); - //Removing the not found field when the input field is empty - setNotFound(); - router.replace( + const onKeyDownHandler = (e) => { + if ((e.ctrlKey || e.metaKey) && e.key === "k") { + e.preventDefault(); + searchInputRef.current?.focus(); + } + }; + document.addEventListener("keydown", onKeyDownHandler); + + return () => { + document.removeEventListener("keydown", onKeyDownHandler); + }; + }, []); + + useEffect(() => { + if (!searchTerm) { + replace( { - pathname: "/search", + pathname, }, undefined, { shallow: true }, @@ -110,14 +121,6 @@ export default function Search({ return; } - // checks if there is no keyword between 2 commas and removes the second comma and also checks if the input starts with comma and removes it. - setInputValue(inputValue.replace(/,(\s*),/g, ",").replace(/^,/, "")); - - // If the inputValue has not changed and is the same as the keyword passed from the server - if (keyword && inputValue === keyword) { - return; - } - async function fetchUsers(value) { try { const res = await fetch( @@ -139,55 +142,65 @@ export default function Search({ } } - const timer = setTimeout(() => { - router.replace( - { - pathname: "/search", - query: { userSearchParam: inputValue }, - }, - undefined, - { shallow: true }, - ); - fetchUsers(inputValue); - }, 500); - - return () => clearTimeout(timer); - }, [inputValue]); + if (searchTerm) { + fetchUsers(searchTerm); + } + }, [searchTerm]); - useEffect(() => { - const onKeyDownHandler = (e) => { - if ((e.ctrlKey || e.metaKey) && e.key === "k") { - e.preventDefault(); - searchInputRef.current?.focus(); - } - }; - document.addEventListener("keydown", onKeyDownHandler); + const handleSearchSubmit = async (e) => { + e.preventDefault(); - return () => { - document.removeEventListener("keydown", onKeyDownHandler); - }; - }, []); + const params = new URLSearchParams({ query: searchTerm }); - const search = (keyword) => { - const cleanedInput = cleanSearchInput(inputValue); + function removeComma(value) { + return value.replace(/,(\s*),/g, ",").replace(/^,/, ""); + } + const searchInputVal = removeComma( + cleanSearchInput(searchInputRef.current.value), + ); - if (!cleanedInput.length) { - return setInputValue(keyword); + if (!searchInputVal) { + params.delete("query"); + } else { + params.set("query", searchInputVal); } - const items = cleanedInput.split(", "); + replace( + { + pathname, + query: { userSearchParam: params.get("query") }, + }, + undefined, + { shallow: true }, + ); + }; - if (cleanedInput.length) { - if (searchTagNameInInput(inputValue, keyword)) { - return setInputValue( - items.filter((item) => item.trim() !== keyword).join(", "), - ); - } + const handleSearchTag = (tagName) => { + const params = new URLSearchParams({ query: searchTerm }); + if (!userSearchParam) { + params.set("query", tagName); + } - return setInputValue([...items, keyword].join(", ")); + if (userSearchParam) { + if (searchTagNameInInput(userSearchParam, tagName)) { + const terms = userSearchParam.split(","); + const filteredTerms = terms.filter((item) => item.trim() !== tagName); + params.set("query", filteredTerms); + } else { + params.append("query", tagName); + } } - setInputValue(keyword); + replace( + { + pathname, + query: { + userSearchParam: params.getAll("query").join(", "), + }, + }, + undefined, + { shallow: true }, + ); }; const usersPerPage = 21; @@ -218,8 +231,10 @@ export default function Search({ key={tag.name} name={tag.name} total={tag.total} - selected={searchTagNameInInput(inputValue, tag.name)} - onClick={() => search(tag.name)} + selected={ + searchTerm && searchTagNameInInput(searchTerm, tag.name) + } + onClick={() => handleSearchTag(tag.name)} /> ))} @@ -230,16 +245,24 @@ export default function Search({ className="w-full" badgeClassName={"translate-x-2/4 -translate-y-1/2"} > - setInputValue(e.target.value)} - /> +
+ + +
- {!inputValue &&

Recently updated profiles

} + {!searchTerm && ( +

+ Recently updated profiles +

+ )} {notFound && } diff --git a/tests/search.spec.js b/tests/search.spec.js index f579ba7c0f9..fb066d7722d 100644 --- a/tests/search.spec.js +++ b/tests/search.spec.js @@ -29,6 +29,7 @@ test("Search works correctly", async ({ page }) => { // 3. type in search and check that user with the name exist and check a name doesn't exist const input = page.locator("[name='keyword']"); await input.type("_test-profile-user-1"); + await page.locator("[type='submit']").click(); await expect(page.locator("main li")).toHaveCount(1); }); @@ -40,6 +41,7 @@ test("Search page has random results when no search term used", async ({ const input = page.locator("[name='keyword']"); await input.fill(""); + await page.locator("[type='submit']").click(); await expect(page.locator("main li")).toHaveCount(defaultUsers); }); @@ -51,6 +53,7 @@ test("Search page shows random results after typing 1 characters", async ({ const input = page.locator("[name='keyword']"); await input.type("e"); + await page.locator("[type='submit']").click(); await expect(page.locator("main li")).toHaveCount(defaultUsers); }); @@ -62,6 +65,7 @@ test("Search page shows results after typing 3 characters", async ({ const input = page.locator("[name='keyword']"); await input.type("aka"); + await page.locator("[type='submit']").click(); await expect(page.locator("main li")).toContainText(["aka"]); }); @@ -73,6 +77,7 @@ test("Search term persistence after navigating back", async ({ page }) => { const searchTerm = "_test-profile-user-1"; const searchName = "Test User Name 1"; await input.fill(searchTerm); + await page.locator("[type='submit']").click(); // 2. Navigate to profile await expect(page).toHaveURL(`/search?userSearchParam=${searchTerm}`); @@ -107,6 +112,7 @@ test("find the profile after providing concise name", async ({ page }) => { // 3. find the input field and type the whole name const input = page.locator("[name='keyword']"); await input.fill(searchTerm); + await page.locator("[type='submit']").click(); // 4. select and click on the profile by matching name string const profileHeader = page.locator(`h2:has-text('${searchTerm}')`); From 8a09e1bfd48d7cfb354dd9055be0aa42bbf2f4ab Mon Sep 17 00:00:00 2001 From: Conventional Changelog Action Date: Sun, 19 Nov 2023 11:01:54 +0000 Subject: [PATCH 2/4] chore(release): v2.89.3 [skip ci] --- CHANGELOG.md | 18 +++++++++--------- config/app.json | 2 +- package-lock.json | 2 +- package.json | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 531440dffde..2b882e7f6b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [2.89.3](https://github.com/EddieHubCommunity/BioDrop/compare/v2.89.2...v2.89.3) (2023-11-19) + + +### Bug Fixes + +* resolve mobile keyboard fluctuation during search ([#9248](https://github.com/EddieHubCommunity/BioDrop/issues/9248)) ([999602b](https://github.com/EddieHubCommunity/BioDrop/commit/999602bae3a2b267a68fd2d8e55282bbfe979501)) + + + ## [2.89.2](https://github.com/EddieHubCommunity/BioDrop/compare/v2.89.1...v2.89.2) (2023-11-18) @@ -34,12 +43,3 @@ -## [2.87.5](https://github.com/EddieHubCommunity/BioDrop/compare/v2.87.4...v2.87.5) (2023-11-17) - - -### Bug Fixes - -* tags with enter [#9103](https://github.com/EddieHubCommunity/BioDrop/issues/9103) ([#9508](https://github.com/EddieHubCommunity/BioDrop/issues/9508)) ([978bc1a](https://github.com/EddieHubCommunity/BioDrop/commit/978bc1a29ad46862066141971615f246d59b06a1)), closes [#9459](https://github.com/EddieHubCommunity/BioDrop/issues/9459) [#9459](https://github.com/EddieHubCommunity/BioDrop/issues/9459) - - - diff --git a/config/app.json b/config/app.json index 5bd33e1ed8c..0b58ba16039 100644 --- a/config/app.json +++ b/config/app.json @@ -1,5 +1,5 @@ { - "version": "2.89.2", + "version": "2.89.3", "alerts": [], "layouts": [ "classic", diff --git a/package-lock.json b/package-lock.json index 82efac8ecc5..ae29a2f763a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "biodrop", - "version": "2.89.2", + "version": "2.89.3", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/package.json b/package.json index 9400f88214e..6f4dbb1fad4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "biodrop", - "version": "2.89.2", + "version": "2.89.3", "private": false, "homepage": "https://biodrop.io", "engines": { From bd90bc7e50e7795c2e7dfd3f3b06298b64f0aadb Mon Sep 17 00:00:00 2001 From: Eddie Jaoude Date: Sun, 19 Nov 2023 13:07:52 +0000 Subject: [PATCH 3/4] fix: pricing premium text (#9806) --- pages/pricing.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/pricing.js b/pages/pricing.js index b9eb7430572..f6ec9fc093c 100644 --- a/pages/pricing.js +++ b/pages/pricing.js @@ -84,7 +84,7 @@ export default function Premium({ user }) { return "Upgrade"; } if (!user.isLoggedIn) { - return "Sign up"; + return "Join Premium plan"; } }, action: () => { From ed72d5331392813e800c74703c2fb96a2b622fda Mon Sep 17 00:00:00 2001 From: Conventional Changelog Action Date: Sun, 19 Nov 2023 13:08:11 +0000 Subject: [PATCH 4/4] chore(release): v2.89.4 [skip ci] --- CHANGELOG.md | 18 +++++++++--------- config/app.json | 2 +- package-lock.json | 2 +- package.json | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b882e7f6b1..7ba29276053 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [2.89.4](https://github.com/EddieHubCommunity/BioDrop/compare/v2.89.3...v2.89.4) (2023-11-19) + + +### Bug Fixes + +* pricing premium text ([#9806](https://github.com/EddieHubCommunity/BioDrop/issues/9806)) ([bd90bc7](https://github.com/EddieHubCommunity/BioDrop/commit/bd90bc7e50e7795c2e7dfd3f3b06298b64f0aadb)) + + + ## [2.89.3](https://github.com/EddieHubCommunity/BioDrop/compare/v2.89.2...v2.89.3) (2023-11-19) @@ -34,12 +43,3 @@ -# [2.88.0](https://github.com/EddieHubCommunity/BioDrop/compare/v2.87.5...v2.88.0) (2023-11-17) - - -### Features - -* issue bug template steps to reproduce ([#9789](https://github.com/EddieHubCommunity/BioDrop/issues/9789)) ([5ac57ba](https://github.com/EddieHubCommunity/BioDrop/commit/5ac57bad5a685a5e688d972c95caa8c9e1a173dd)) - - - diff --git a/config/app.json b/config/app.json index 0b58ba16039..8fa431d17bc 100644 --- a/config/app.json +++ b/config/app.json @@ -1,5 +1,5 @@ { - "version": "2.89.3", + "version": "2.89.4", "alerts": [], "layouts": [ "classic", diff --git a/package-lock.json b/package-lock.json index ae29a2f763a..2e376e146f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "biodrop", - "version": "2.89.3", + "version": "2.89.4", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/package.json b/package.json index 6f4dbb1fad4..b7d297ecfeb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "biodrop", - "version": "2.89.3", + "version": "2.89.4", "private": false, "homepage": "https://biodrop.io", "engines": {