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); + }); +});