Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 2b17fc3

Browse files
authored
Show error when searching public rooms fails (#11378)
* Show error when searching public rooms fails * Fix types * Improve test coverage * Improve coverage
1 parent b5bfc5b commit 2b17fc3

File tree

4 files changed

+63
-13
lines changed

4 files changed

+63
-13
lines changed

src/components/views/dialogs/spotlight/SpotlightDialog.tsx

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
311311
config,
312312
setConfig,
313313
search: searchPublicRooms,
314+
error: publicRoomsError,
314315
} = usePublicRoomDirectory();
315316
const [showRooms, setShowRooms] = useState(true);
316317
const [showSpaces, setShowSpaces] = useState(false);
@@ -757,6 +758,23 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
757758

758759
let publicRoomsSection: JSX.Element | undefined;
759760
if (filter === Filter.PublicRooms) {
761+
let content: JSX.Element | JSX.Element[];
762+
if (!showRooms && !showSpaces) {
763+
content = (
764+
<div className="mx_SpotlightDialog_otherSearches_messageSearchText">
765+
{_t("You cannot search for rooms that are neither a room nor a space")}
766+
</div>
767+
);
768+
} else if (publicRoomsError) {
769+
content = (
770+
<div className="mx_SpotlightDialog_otherSearches_messageSearchText">
771+
{_t("Failed to query public rooms")}
772+
</div>
773+
);
774+
} else {
775+
content = results[Section.PublicRooms].slice(0, SECTION_LIMIT).map(resultMapper);
776+
}
777+
760778
publicRoomsSection = (
761779
<div
762780
className="mx_SpotlightDialog_section mx_SpotlightDialog_results"
@@ -783,16 +801,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
783801
<NetworkDropdown protocols={protocols} config={config ?? null} setConfig={setConfig} />
784802
</div>
785803
</div>
786-
<div>
787-
{" "}
788-
{showRooms || showSpaces ? (
789-
results[Section.PublicRooms].slice(0, SECTION_LIMIT).map(resultMapper)
790-
) : (
791-
<div className="mx_SpotlightDialog_otherSearches_messageSearchText">
792-
{_t("You cannot search for rooms that are neither a room nor a space")}
793-
</div>
794-
)}{" "}
795-
</div>
804+
<div>{content}</div>
796805
</div>
797806
);
798807
}

src/hooks/usePublicRoomDirectory.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export const usePublicRoomDirectory = (): {
5151
config?: IPublicRoomDirectoryConfig | null;
5252
setConfig(config: IPublicRoomDirectoryConfig | null): void;
5353
search(opts: IPublicRoomsOpts): Promise<boolean>;
54+
error?: Error | true; // true if an unknown error is encountered
5455
} => {
5556
const [publicRooms, setPublicRooms] = useState<IPublicRoomsChunkRoom[]>([]);
5657

@@ -60,6 +61,7 @@ export const usePublicRoomDirectory = (): {
6061

6162
const [ready, setReady] = useState(false);
6263
const [loading, setLoading] = useState(false);
64+
const [error, setError] = useState<Error | true | undefined>();
6365

6466
const [updateQuery, updateResult] = useLatestResult<IRoomDirectoryOptions, IPublicRoomsChunkRoom[]>(setPublicRooms);
6567

@@ -112,12 +114,14 @@ export const usePublicRoomDirectory = (): {
112114
}
113115

114116
updateQuery(opts);
117+
setLoading(true);
118+
setError(undefined);
115119
try {
116-
setLoading(true);
117120
const { chunk } = await MatrixClientPeg.safeGet().publicRooms(opts);
118121
updateResult(opts, showNsfwPublicRooms ? chunk : chunk.filter(cheapNsfwFilter));
119122
return true;
120123
} catch (e) {
124+
setError(e instanceof Error ? e : true);
121125
console.error("Could not fetch public rooms for params", opts, e);
122126
updateResult(opts, []);
123127
return false;
@@ -183,5 +187,6 @@ export const usePublicRoomDirectory = (): {
183187
config,
184188
search,
185189
setConfig,
190+
error,
186191
} as const;
187192
};

src/i18n/strings/en_EN.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3138,9 +3138,10 @@
31383138
"Search for": "Search for",
31393139
"View": "View",
31403140
"Spaces you're in": "Spaces you're in",
3141+
"You cannot search for rooms that are neither a room nor a space": "You cannot search for rooms that are neither a room nor a space",
3142+
"Failed to query public rooms": "Failed to query public rooms",
31413143
"Show rooms": "Show rooms",
31423144
"Show spaces": "Show spaces",
3143-
"You cannot search for rooms that are neither a room nor a space": "You cannot search for rooms that are neither a room nor a space",
31443145
"Other rooms in %(spaceName)s": "Other rooms in %(spaceName)s",
31453146
"Join %(roomAddress)s": "Join %(roomAddress)s",
31463147
"Some results may be hidden for privacy": "Some results may be hidden for privacy",

test/components/views/dialogs/SpotlightDialog-test.tsx

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,14 @@ limitations under the License.
1616

1717
import React from "react";
1818
import { mocked } from "jest-mock";
19-
import { IProtocol, IPublicRoomsChunkRoom, MatrixClient, Room, RoomMember } from "matrix-js-sdk/src/matrix";
19+
import {
20+
ConnectionError,
21+
IProtocol,
22+
IPublicRoomsChunkRoom,
23+
MatrixClient,
24+
Room,
25+
RoomMember,
26+
} from "matrix-js-sdk/src/matrix";
2027
import sanitizeHtml from "sanitize-html";
2128
import { fireEvent, render, screen } from "@testing-library/react";
2229

@@ -495,4 +502,32 @@ describe("Spotlight Dialog", () => {
495502
expect(screen.getByText(potatoRoom.name!)).toBeInTheDocument();
496503
});
497504
});
505+
506+
it("should show error if /publicRooms API failed", async () => {
507+
mocked(mockedClient.publicRooms).mockRejectedValue(new ConnectionError("Failed to fetch"));
508+
render(<SpotlightDialog initialFilter={Filter.PublicRooms} onFinished={() => null} />);
509+
510+
jest.advanceTimersByTime(200);
511+
await flushPromisesWithFakeTimers();
512+
513+
expect(screen.getByText("Failed to query public rooms")).toBeInTheDocument();
514+
});
515+
516+
it("should show error both 'Show rooms' and 'Show spaces' are unchecked", async () => {
517+
jest.spyOn(SettingsStore, "getValue").mockImplementation((settingName, roomId, excludeDefault) => {
518+
if (settingName === "feature_exploring_public_spaces") {
519+
return true;
520+
} else {
521+
return []; // SpotlightSearch.recentSearches
522+
}
523+
});
524+
render(<SpotlightDialog initialFilter={Filter.PublicRooms} onFinished={() => null} />);
525+
526+
jest.advanceTimersByTime(200);
527+
await flushPromisesWithFakeTimers();
528+
529+
fireEvent.click(screen.getByText("Show rooms"));
530+
531+
expect(screen.getByText("You cannot search for rooms that are neither a room nor a space")).toBeInTheDocument();
532+
});
498533
});

0 commit comments

Comments
 (0)