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

Commit

Permalink
Fix editing event from search room view (#11992)
Browse files Browse the repository at this point in the history
* Fix editing event from search room view

Signed-off-by: Michael Telatynski <[email protected]>

* Iterate

Signed-off-by: Michael Telatynski <[email protected]>

* Handle different room for all rooms search case

Signed-off-by: Michael Telatynski <[email protected]>

* Iterate

Signed-off-by: Michael Telatynski <[email protected]>

* Iterate

Signed-off-by: Michael Telatynski <[email protected]>

* Add tests

Signed-off-by: Michael Telatynski <[email protected]>

* Increase coverage

Signed-off-by: Michael Telatynski <[email protected]>

---------

Signed-off-by: Michael Telatynski <[email protected]>
  • Loading branch information
t3chguy authored Dec 19, 2023
1 parent d2f7b4a commit 5f92dad
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 7 deletions.
34 changes: 29 additions & 5 deletions src/components/structures/RoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ export interface IRoomState {
initialEventScrollIntoView?: boolean;
replyToEvent?: MatrixEvent;
numUnreadMessages: number;
/**
* The state of an ongoing search if there is one.
*/
search?: ISearchInfo;
callState?: CallState;
activeCall: Call | null;
Expand Down Expand Up @@ -1208,12 +1211,33 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
case Action.EditEvent: {
// Quit early if we're trying to edit events in wrong rendering context
if (payload.timelineRenderingType !== this.state.timelineRenderingType) return;
if (payload.event && payload.event.getRoomId() !== this.state.roomId) {
// If the event is in a different room (e.g. because the event to be edited is being displayed
// in the results of an all-rooms search), we need to view that room first.
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: payload.event.getRoomId(),
metricsTrigger: undefined,
deferred_action: payload,
});
return;
}

const editState = payload.event ? new EditorStateTransfer(payload.event) : undefined;
this.setState({ editState }, () => {
if (payload.event) {
this.messagePanel?.scrollToEventIfNeeded(payload.event.getId());
}
});
this.setState(
{
editState,
// If a search is active (implying that the "edit" button has been pressed on one of the
// events in the search result), we need to close that search, because RoomSearchView
// doesn't handle editing and won't render the composer.
search: undefined,
},
() => {
if (payload.event) {
this.messagePanel?.scrollToEventIfNeeded(payload.event.getId());
}
},
);
break;
}

Expand Down
127 changes: 125 additions & 2 deletions test/components/structures/RoomView-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ import {
MatrixError,
RoomStateEvent,
MatrixEvent,
SearchResult,
IEvent,
} from "matrix-js-sdk/src/matrix";
import { MEGOLM_ALGORITHM } from "matrix-js-sdk/src/crypto/olmlib";
import { fireEvent, render, screen, RenderResult } from "@testing-library/react";
import { fireEvent, render, screen, RenderResult, waitForElementToBeRemoved, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

import {
stubClient,
Expand Down Expand Up @@ -60,12 +63,13 @@ import { LocalRoom, LocalRoomState } from "../../../src/models/LocalRoom";
import { DirectoryMember } from "../../../src/utils/direct-messages";
import { createDmLocalRoom } from "../../../src/utils/dm/createDmLocalRoom";
import { UPDATE_EVENT } from "../../../src/stores/AsyncStore";
import { SdkContextClass, SDKContext } from "../../../src/contexts/SDKContext";
import { SDKContext, SdkContextClass } from "../../../src/contexts/SDKContext";
import VoipUserMapper from "../../../src/VoipUserMapper";
import WidgetUtils from "../../../src/utils/WidgetUtils";
import { WidgetType } from "../../../src/widgets/WidgetType";
import WidgetStore from "../../../src/stores/WidgetStore";
import { ViewRoomErrorPayload } from "../../../src/dispatcher/payloads/ViewRoomErrorPayload";
import { SearchScope } from "../../../src/components/views/rooms/SearchBar";

const RoomView = wrapInMatrixClientContext(_RoomView);

Expand Down Expand Up @@ -585,4 +589,123 @@ describe("RoomView", () => {
expect(dis.dispatch).toHaveBeenCalledWith({ action: "cancel_ask_to_join", roomId: room.roomId });
});
});

it("should close search results when edit is clicked", async () => {
room.getMyMembership = jest.fn().mockReturnValue("join");

const eventMapper = (obj: Partial<IEvent>) => new MatrixEvent(obj);

const roomViewRef = createRef<_RoomView>();
const { container, getByText, findByLabelText } = await mountRoomView(roomViewRef);
// @ts-ignore - triggering a search organically is a lot of work
roomViewRef.current!.setState({
search: {
searchId: 1,
roomId: room.roomId,
term: "search term",
scope: SearchScope.Room,
promise: Promise.resolve({
results: [
SearchResult.fromJson(
{
rank: 1,
result: {
content: {
body: "search term",
msgtype: "m.text",
},
type: "m.room.message",
event_id: "$eventId",
sender: cli.getSafeUserId(),
origin_server_ts: 123456789,
room_id: room.roomId,
},
context: {
events_before: [],
events_after: [],
profile_info: {},
},
},
eventMapper,
),
],
highlights: [],
count: 1,
}),
inProgress: false,
count: 1,
},
});

await waitFor(() => {
expect(container.querySelector(".mx_RoomView_searchResultsPanel")).toBeVisible();
});
const prom = waitForElementToBeRemoved(() => container.querySelector(".mx_RoomView_searchResultsPanel"));

await userEvent.hover(getByText("search term"));
await userEvent.click(await findByLabelText("Edit"));

await prom;
});

it("should switch rooms when edit is clicked on a search result for a different room", async () => {
const room2 = new Room(`!${roomCount++}:example.org`, cli, "@alice:example.org");
rooms.set(room2.roomId, room2);

room.getMyMembership = jest.fn().mockReturnValue("join");

const eventMapper = (obj: Partial<IEvent>) => new MatrixEvent(obj);

const roomViewRef = createRef<_RoomView>();
const { container, getByText, findByLabelText } = await mountRoomView(roomViewRef);
// @ts-ignore - triggering a search organically is a lot of work
roomViewRef.current!.setState({
search: {
searchId: 1,
roomId: room.roomId,
term: "search term",
scope: SearchScope.All,
promise: Promise.resolve({
results: [
SearchResult.fromJson(
{
rank: 1,
result: {
content: {
body: "search term",
msgtype: "m.text",
},
type: "m.room.message",
event_id: "$eventId",
sender: cli.getSafeUserId(),
origin_server_ts: 123456789,
room_id: room2.roomId,
},
context: {
events_before: [],
events_after: [],
profile_info: {},
},
},
eventMapper,
),
],
highlights: [],
count: 1,
}),
inProgress: false,
count: 1,
},
});

await waitFor(() => {
expect(container.querySelector(".mx_RoomView_searchResultsPanel")).toBeVisible();
});
const prom = untilDispatch(Action.ViewRoom, dis);

await userEvent.hover(getByText("search term"));
await userEvent.click(await findByLabelText("Edit"));

await expect(prom).resolves.toEqual(expect.objectContaining({ room_id: room2.roomId }));
});
});

0 comments on commit 5f92dad

Please sign in to comment.