Show error when searching public rooms fails (#11378)
* Show error when searching public rooms fails * Fix types * Improve test coverage * Improve coveragepull/28788/head^2
parent
b5bfc5be21
commit
2b17fc3221
|
@ -311,6 +311,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
||||||
config,
|
config,
|
||||||
setConfig,
|
setConfig,
|
||||||
search: searchPublicRooms,
|
search: searchPublicRooms,
|
||||||
|
error: publicRoomsError,
|
||||||
} = usePublicRoomDirectory();
|
} = usePublicRoomDirectory();
|
||||||
const [showRooms, setShowRooms] = useState(true);
|
const [showRooms, setShowRooms] = useState(true);
|
||||||
const [showSpaces, setShowSpaces] = useState(false);
|
const [showSpaces, setShowSpaces] = useState(false);
|
||||||
|
@ -757,6 +758,23 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
||||||
|
|
||||||
let publicRoomsSection: JSX.Element | undefined;
|
let publicRoomsSection: JSX.Element | undefined;
|
||||||
if (filter === Filter.PublicRooms) {
|
if (filter === Filter.PublicRooms) {
|
||||||
|
let content: JSX.Element | JSX.Element[];
|
||||||
|
if (!showRooms && !showSpaces) {
|
||||||
|
content = (
|
||||||
|
<div className="mx_SpotlightDialog_otherSearches_messageSearchText">
|
||||||
|
{_t("You cannot search for rooms that are neither a room nor a space")}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else if (publicRoomsError) {
|
||||||
|
content = (
|
||||||
|
<div className="mx_SpotlightDialog_otherSearches_messageSearchText">
|
||||||
|
{_t("Failed to query public rooms")}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
content = results[Section.PublicRooms].slice(0, SECTION_LIMIT).map(resultMapper);
|
||||||
|
}
|
||||||
|
|
||||||
publicRoomsSection = (
|
publicRoomsSection = (
|
||||||
<div
|
<div
|
||||||
className="mx_SpotlightDialog_section mx_SpotlightDialog_results"
|
className="mx_SpotlightDialog_section mx_SpotlightDialog_results"
|
||||||
|
@ -783,16 +801,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
||||||
<NetworkDropdown protocols={protocols} config={config ?? null} setConfig={setConfig} />
|
<NetworkDropdown protocols={protocols} config={config ?? null} setConfig={setConfig} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>{content}</div>
|
||||||
{" "}
|
|
||||||
{showRooms || showSpaces ? (
|
|
||||||
results[Section.PublicRooms].slice(0, SECTION_LIMIT).map(resultMapper)
|
|
||||||
) : (
|
|
||||||
<div className="mx_SpotlightDialog_otherSearches_messageSearchText">
|
|
||||||
{_t("You cannot search for rooms that are neither a room nor a space")}
|
|
||||||
</div>
|
|
||||||
)}{" "}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ export const usePublicRoomDirectory = (): {
|
||||||
config?: IPublicRoomDirectoryConfig | null;
|
config?: IPublicRoomDirectoryConfig | null;
|
||||||
setConfig(config: IPublicRoomDirectoryConfig | null): void;
|
setConfig(config: IPublicRoomDirectoryConfig | null): void;
|
||||||
search(opts: IPublicRoomsOpts): Promise<boolean>;
|
search(opts: IPublicRoomsOpts): Promise<boolean>;
|
||||||
|
error?: Error | true; // true if an unknown error is encountered
|
||||||
} => {
|
} => {
|
||||||
const [publicRooms, setPublicRooms] = useState<IPublicRoomsChunkRoom[]>([]);
|
const [publicRooms, setPublicRooms] = useState<IPublicRoomsChunkRoom[]>([]);
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ export const usePublicRoomDirectory = (): {
|
||||||
|
|
||||||
const [ready, setReady] = useState(false);
|
const [ready, setReady] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [error, setError] = useState<Error | true | undefined>();
|
||||||
|
|
||||||
const [updateQuery, updateResult] = useLatestResult<IRoomDirectoryOptions, IPublicRoomsChunkRoom[]>(setPublicRooms);
|
const [updateQuery, updateResult] = useLatestResult<IRoomDirectoryOptions, IPublicRoomsChunkRoom[]>(setPublicRooms);
|
||||||
|
|
||||||
|
@ -112,12 +114,14 @@ export const usePublicRoomDirectory = (): {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateQuery(opts);
|
updateQuery(opts);
|
||||||
|
setLoading(true);
|
||||||
|
setError(undefined);
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
|
||||||
const { chunk } = await MatrixClientPeg.safeGet().publicRooms(opts);
|
const { chunk } = await MatrixClientPeg.safeGet().publicRooms(opts);
|
||||||
updateResult(opts, showNsfwPublicRooms ? chunk : chunk.filter(cheapNsfwFilter));
|
updateResult(opts, showNsfwPublicRooms ? chunk : chunk.filter(cheapNsfwFilter));
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
setError(e instanceof Error ? e : true);
|
||||||
console.error("Could not fetch public rooms for params", opts, e);
|
console.error("Could not fetch public rooms for params", opts, e);
|
||||||
updateResult(opts, []);
|
updateResult(opts, []);
|
||||||
return false;
|
return false;
|
||||||
|
@ -183,5 +187,6 @@ export const usePublicRoomDirectory = (): {
|
||||||
config,
|
config,
|
||||||
search,
|
search,
|
||||||
setConfig,
|
setConfig,
|
||||||
|
error,
|
||||||
} as const;
|
} as const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -3138,9 +3138,10 @@
|
||||||
"Search for": "Search for",
|
"Search for": "Search for",
|
||||||
"View": "View",
|
"View": "View",
|
||||||
"Spaces you're in": "Spaces you're in",
|
"Spaces you're in": "Spaces you're in",
|
||||||
|
"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",
|
||||||
|
"Failed to query public rooms": "Failed to query public rooms",
|
||||||
"Show rooms": "Show rooms",
|
"Show rooms": "Show rooms",
|
||||||
"Show spaces": "Show spaces",
|
"Show spaces": "Show spaces",
|
||||||
"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",
|
|
||||||
"Other rooms in %(spaceName)s": "Other rooms in %(spaceName)s",
|
"Other rooms in %(spaceName)s": "Other rooms in %(spaceName)s",
|
||||||
"Join %(roomAddress)s": "Join %(roomAddress)s",
|
"Join %(roomAddress)s": "Join %(roomAddress)s",
|
||||||
"Some results may be hidden for privacy": "Some results may be hidden for privacy",
|
"Some results may be hidden for privacy": "Some results may be hidden for privacy",
|
||||||
|
|
|
@ -16,7 +16,14 @@ limitations under the License.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { mocked } from "jest-mock";
|
import { mocked } from "jest-mock";
|
||||||
import { IProtocol, IPublicRoomsChunkRoom, MatrixClient, Room, RoomMember } from "matrix-js-sdk/src/matrix";
|
import {
|
||||||
|
ConnectionError,
|
||||||
|
IProtocol,
|
||||||
|
IPublicRoomsChunkRoom,
|
||||||
|
MatrixClient,
|
||||||
|
Room,
|
||||||
|
RoomMember,
|
||||||
|
} from "matrix-js-sdk/src/matrix";
|
||||||
import sanitizeHtml from "sanitize-html";
|
import sanitizeHtml from "sanitize-html";
|
||||||
import { fireEvent, render, screen } from "@testing-library/react";
|
import { fireEvent, render, screen } from "@testing-library/react";
|
||||||
|
|
||||||
|
@ -495,4 +502,32 @@ describe("Spotlight Dialog", () => {
|
||||||
expect(screen.getByText(potatoRoom.name!)).toBeInTheDocument();
|
expect(screen.getByText(potatoRoom.name!)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should show error if /publicRooms API failed", async () => {
|
||||||
|
mocked(mockedClient.publicRooms).mockRejectedValue(new ConnectionError("Failed to fetch"));
|
||||||
|
render(<SpotlightDialog initialFilter={Filter.PublicRooms} onFinished={() => null} />);
|
||||||
|
|
||||||
|
jest.advanceTimersByTime(200);
|
||||||
|
await flushPromisesWithFakeTimers();
|
||||||
|
|
||||||
|
expect(screen.getByText("Failed to query public rooms")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should show error both 'Show rooms' and 'Show spaces' are unchecked", async () => {
|
||||||
|
jest.spyOn(SettingsStore, "getValue").mockImplementation((settingName, roomId, excludeDefault) => {
|
||||||
|
if (settingName === "feature_exploring_public_spaces") {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return []; // SpotlightSearch.recentSearches
|
||||||
|
}
|
||||||
|
});
|
||||||
|
render(<SpotlightDialog initialFilter={Filter.PublicRooms} onFinished={() => null} />);
|
||||||
|
|
||||||
|
jest.advanceTimersByTime(200);
|
||||||
|
await flushPromisesWithFakeTimers();
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByText("Show rooms"));
|
||||||
|
|
||||||
|
expect(screen.getByText("You cannot search for rooms that are neither a room nor a space")).toBeInTheDocument();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue