Fix editing event from search room view (#11992)
* Fix editing event from search room view Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Handle different room for all rooms search case Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Add tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Increase coverage Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
d2f7b4a2bf
commit
5f92dad273
2 changed files with 154 additions and 7 deletions
|
@ -186,6 +186,9 @@ export interface IRoomState {
|
||||||
initialEventScrollIntoView?: boolean;
|
initialEventScrollIntoView?: boolean;
|
||||||
replyToEvent?: MatrixEvent;
|
replyToEvent?: MatrixEvent;
|
||||||
numUnreadMessages: number;
|
numUnreadMessages: number;
|
||||||
|
/**
|
||||||
|
* The state of an ongoing search if there is one.
|
||||||
|
*/
|
||||||
search?: ISearchInfo;
|
search?: ISearchInfo;
|
||||||
callState?: CallState;
|
callState?: CallState;
|
||||||
activeCall: Call | null;
|
activeCall: Call | null;
|
||||||
|
@ -1208,12 +1211,33 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||||
case Action.EditEvent: {
|
case Action.EditEvent: {
|
||||||
// Quit early if we're trying to edit events in wrong rendering context
|
// Quit early if we're trying to edit events in wrong rendering context
|
||||||
if (payload.timelineRenderingType !== this.state.timelineRenderingType) return;
|
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;
|
const editState = payload.event ? new EditorStateTransfer(payload.event) : undefined;
|
||||||
this.setState({ editState }, () => {
|
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) {
|
if (payload.event) {
|
||||||
this.messagePanel?.scrollToEventIfNeeded(payload.event.getId());
|
this.messagePanel?.scrollToEventIfNeeded(payload.event.getId());
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,12 @@ import {
|
||||||
MatrixError,
|
MatrixError,
|
||||||
RoomStateEvent,
|
RoomStateEvent,
|
||||||
MatrixEvent,
|
MatrixEvent,
|
||||||
|
SearchResult,
|
||||||
|
IEvent,
|
||||||
} from "matrix-js-sdk/src/matrix";
|
} from "matrix-js-sdk/src/matrix";
|
||||||
import { MEGOLM_ALGORITHM } from "matrix-js-sdk/src/crypto/olmlib";
|
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 {
|
import {
|
||||||
stubClient,
|
stubClient,
|
||||||
|
@ -60,12 +63,13 @@ import { LocalRoom, LocalRoomState } from "../../../src/models/LocalRoom";
|
||||||
import { DirectoryMember } from "../../../src/utils/direct-messages";
|
import { DirectoryMember } from "../../../src/utils/direct-messages";
|
||||||
import { createDmLocalRoom } from "../../../src/utils/dm/createDmLocalRoom";
|
import { createDmLocalRoom } from "../../../src/utils/dm/createDmLocalRoom";
|
||||||
import { UPDATE_EVENT } from "../../../src/stores/AsyncStore";
|
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 VoipUserMapper from "../../../src/VoipUserMapper";
|
||||||
import WidgetUtils from "../../../src/utils/WidgetUtils";
|
import WidgetUtils from "../../../src/utils/WidgetUtils";
|
||||||
import { WidgetType } from "../../../src/widgets/WidgetType";
|
import { WidgetType } from "../../../src/widgets/WidgetType";
|
||||||
import WidgetStore from "../../../src/stores/WidgetStore";
|
import WidgetStore from "../../../src/stores/WidgetStore";
|
||||||
import { ViewRoomErrorPayload } from "../../../src/dispatcher/payloads/ViewRoomErrorPayload";
|
import { ViewRoomErrorPayload } from "../../../src/dispatcher/payloads/ViewRoomErrorPayload";
|
||||||
|
import { SearchScope } from "../../../src/components/views/rooms/SearchBar";
|
||||||
|
|
||||||
const RoomView = wrapInMatrixClientContext(_RoomView);
|
const RoomView = wrapInMatrixClientContext(_RoomView);
|
||||||
|
|
||||||
|
@ -585,4 +589,123 @@ describe("RoomView", () => {
|
||||||
expect(dis.dispatch).toHaveBeenCalledWith({ action: "cancel_ask_to_join", roomId: room.roomId });
|
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 }));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue