From 739eec85557ebd4497620917e7cb36fcc114b41a Mon Sep 17 00:00:00 2001 From: Boluwatife Omosowon <59070723+bolu-tife@users.noreply.github.com> Date: Tue, 9 May 2023 08:55:50 +0100 Subject: [PATCH] Allows search to recognize full room links (#8275) * fix matrix search link * fix matrix search link Signed-off-by: Boluwatife Omosowon * fix: allow full link search Signed-off-by: Boluwatife Omosowon * fix: allow full link search on new search feature Signed-off-by: Boluwatife Omosowon * improve transformSearchTerm function Signed-off-by: Boluwatife Omosowon * improve transformSearchTerm function Signed-off-by: Boluwatife Omosowon * add review changes * Signed-off-by: Boluwatife Omosowon added review correction changed the transformSearchTerm function to use parsePermaLink removed extra spaces * add angle brackets to copyright email title * removed extra space Signed-off-by: Boluwatife Omosowon * Update src/utils/SearchInput.ts Co-authored-by: Travis Ralston * fixed spolight dialog search for room and user links * added tests for transformSearchTerm * removed transformSearchTerm from room search bar * replaces two test cases to one that should return the primaryEntityId if the search term was a permalink * corrected ts issues * changed type of transformSearchTerm to string * changed return value from empty string to the original search term if the primaryEntityId of the parsedLink is null * changed return value from empty string to the original search term if the primaryEntityId of the parsedLink is null * refactored transformSearchTerm and added a new test case * rewrote transformSearchTerm doc * changed mocked return values of test case - should return the original search term if the search term is a permalink and the primaryEntityId is null * lint corrections --------- Signed-off-by: Boluwatife Omosowon Co-authored-by: Boluwatife Omosowon Co-authored-by: Travis Ralston --- .../dialogs/spotlight/SpotlightDialog.tsx | 3 +- src/utils/SearchInput.ts | 30 ++++++++++ test/utils/SearchInput-test.ts | 60 +++++++++++++++++++ 3 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 src/utils/SearchInput.ts create mode 100644 test/utils/SearchInput-test.ts diff --git a/src/components/views/dialogs/spotlight/SpotlightDialog.tsx b/src/components/views/dialogs/spotlight/SpotlightDialog.tsx index 2939d7f46d1..94db40847bd 100644 --- a/src/components/views/dialogs/spotlight/SpotlightDialog.tsx +++ b/src/components/views/dialogs/spotlight/SpotlightDialog.tsx @@ -89,6 +89,7 @@ import { isLocalRoom } from "../../../../utils/localRoom/isLocalRoom"; import RoomAvatar from "../../avatars/RoomAvatar"; import { useFeatureEnabled } from "../../../../hooks/useSettings"; import { filterBoolean } from "../../../../utils/arrays"; +import { transformSearchTerm } from "../../../../utils/SearchInput"; const MAX_RECENT_SEARCHES = 10; const SECTION_LIMIT = 50; // only show 50 results per section for performance reasons @@ -466,7 +467,7 @@ const SpotlightDialog: React.FC = ({ initialText = "", initialFilter = n const [spaceResults, spaceResultsLoading] = useSpaceResults(activeSpace ?? undefined, query); const setQuery = (e: ChangeEvent): void => { - const newQuery = e.currentTarget.value; + const newQuery = transformSearchTerm(e.currentTarget.value); _setQuery(newQuery); }; useEffect(() => { diff --git a/src/utils/SearchInput.ts b/src/utils/SearchInput.ts new file mode 100644 index 00000000000..04b6d1bc43d --- /dev/null +++ b/src/utils/SearchInput.ts @@ -0,0 +1,30 @@ +/* +Copyright 2023 Boluwatife Omosowon + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { parsePermalink } from "./permalinks/Permalinks"; + +/** + * Returns the primaryEntityId(roomIdOrAlias or userId) if the search term + * is a permalink and the primaryEntityId is not null. Otherwise, it returns + * the original search term. + * E.g https://matrix.to/#/#element-dev:matrix.org returns #element-dev:matrix.org + * @param {string} searchTerm The search term. + * @returns {string} The roomId, alias, userId, or the original search term + */ +export function transformSearchTerm(searchTerm: string): string { + const parseLink = parsePermalink(searchTerm); + return parseLink?.primaryEntityId ?? searchTerm; +} diff --git a/test/utils/SearchInput-test.ts b/test/utils/SearchInput-test.ts new file mode 100644 index 00000000000..0f863973629 --- /dev/null +++ b/test/utils/SearchInput-test.ts @@ -0,0 +1,60 @@ +/* +Copyright 2023 Boluwatife Omosowon + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import { mocked } from "jest-mock"; + +import { parsePermalink } from "../../src/utils/permalinks/Permalinks"; +import { transformSearchTerm } from "../../src/utils/SearchInput"; + +jest.mock("../../src/utils/permalinks/Permalinks"); + +describe("transforming search term", () => { + it("should return the primaryEntityId if the search term was a permalink", () => { + const roomLink = "https://matrix.to/#/#element-dev:matrix.org"; + const parsedPermalink = "#element-dev:matrix.org"; + + mocked(parsePermalink).mockReturnValue({ + primaryEntityId: parsedPermalink, + roomIdOrAlias: parsedPermalink, + eventId: "", + userId: "", + viaServers: [], + sigil: "", + }); + + expect(transformSearchTerm(roomLink)).toBe(parsedPermalink); + }); + + it("should return the original search term if the search term is a permalink and the primaryEntityId is null", () => { + const searchTerm = "https://matrix.to/#/#random-link:matrix.org"; + + mocked(parsePermalink).mockReturnValue({ + primaryEntityId: null, + roomIdOrAlias: null, + eventId: null, + userId: null, + viaServers: null, + sigil: "?", + }); + + expect(transformSearchTerm(searchTerm)).toBe(searchTerm); + }); + + it("should return the original search term if the search term was not a permalink", () => { + const searchTerm = "search term"; + mocked(parsePermalink).mockReturnValue(null); + expect(transformSearchTerm(searchTerm)).toBe(searchTerm); + }); +});