mirror of https://github.com/vector-im/riot-web
Wire up CallEventGroupers for Search Results (#7866)
parent
e644ede09e
commit
2a55d22916
|
@ -44,6 +44,30 @@ export enum CustomCallState {
|
||||||
Missed = "missed",
|
Missed = "missed",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildCallEventGroupers(
|
||||||
|
callEventGroupers: Map<string, CallEventGrouper>,
|
||||||
|
events?: MatrixEvent[],
|
||||||
|
): Map<string, CallEventGrouper> {
|
||||||
|
const newCallEventGroupers = new Map();
|
||||||
|
events?.forEach(ev => {
|
||||||
|
if (!ev.getType().startsWith("m.call.") && !ev.getType().startsWith("org.matrix.call.")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const callId = ev.getContent().call_id;
|
||||||
|
if (!newCallEventGroupers.has(callId)) {
|
||||||
|
if (callEventGroupers.has(callId)) {
|
||||||
|
// reuse the CallEventGrouper object where possible
|
||||||
|
newCallEventGroupers.set(callId, callEventGroupers.get(callId));
|
||||||
|
} else {
|
||||||
|
newCallEventGroupers.set(callId, new CallEventGrouper());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newCallEventGroupers.get(callId).add(ev);
|
||||||
|
});
|
||||||
|
return newCallEventGroupers;
|
||||||
|
}
|
||||||
|
|
||||||
export default class CallEventGrouper extends EventEmitter {
|
export default class CallEventGrouper extends EventEmitter {
|
||||||
private events: Set<MatrixEvent> = new Set<MatrixEvent>();
|
private events: Set<MatrixEvent> = new Set<MatrixEvent>();
|
||||||
private call: MatrixCall;
|
private call: MatrixCall;
|
||||||
|
|
|
@ -51,7 +51,7 @@ import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
|
||||||
import Spinner from "../views/elements/Spinner";
|
import Spinner from "../views/elements/Spinner";
|
||||||
import EditorStateTransfer from '../../utils/EditorStateTransfer';
|
import EditorStateTransfer from '../../utils/EditorStateTransfer';
|
||||||
import ErrorDialog from '../views/dialogs/ErrorDialog';
|
import ErrorDialog from '../views/dialogs/ErrorDialog';
|
||||||
import CallEventGrouper from "./CallEventGrouper";
|
import CallEventGrouper, { buildCallEventGroupers } from "./CallEventGrouper";
|
||||||
import { ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload";
|
import { ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload";
|
||||||
|
|
||||||
const PAGINATE_SIZE = 20;
|
const PAGINATE_SIZE = 20;
|
||||||
|
@ -1546,24 +1546,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
||||||
) => this.props.timelineSet.getRelationsForEvent(eventId, relationType, eventType);
|
) => this.props.timelineSet.getRelationsForEvent(eventId, relationType, eventType);
|
||||||
|
|
||||||
private buildCallEventGroupers(events?: MatrixEvent[]): void {
|
private buildCallEventGroupers(events?: MatrixEvent[]): void {
|
||||||
const oldCallEventGroupers = this.callEventGroupers;
|
this.callEventGroupers = buildCallEventGroupers(this.callEventGroupers, events);
|
||||||
this.callEventGroupers = new Map();
|
|
||||||
events?.forEach(ev => {
|
|
||||||
if (!ev.getType().startsWith("m.call.") && !ev.getType().startsWith("org.matrix.call.")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const callId = ev.getContent().call_id;
|
|
||||||
if (!this.callEventGroupers.has(callId)) {
|
|
||||||
if (oldCallEventGroupers.has(callId)) {
|
|
||||||
// reuse the CallEventGrouper object where possible
|
|
||||||
this.callEventGroupers.set(callId, oldCallEventGroupers.get(callId));
|
|
||||||
} else {
|
|
||||||
this.callEventGroupers.set(callId, new CallEventGrouper());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.callEventGroupers.get(callId).add(ev);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { SearchResult } from "matrix-js-sdk/src/models/search-result";
|
import { SearchResult } from "matrix-js-sdk/src/models/search-result";
|
||||||
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
|
|
||||||
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
|
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
|
@ -27,6 +28,7 @@ import DateSeparator from "../messages/DateSeparator";
|
||||||
import EventTile, { haveTileForEvent } from "./EventTile";
|
import EventTile, { haveTileForEvent } from "./EventTile";
|
||||||
import { shouldFormContinuation } from "../../structures/MessagePanel";
|
import { shouldFormContinuation } from "../../structures/MessagePanel";
|
||||||
import { wantsDateSeparator } from "../../../DateUtils";
|
import { wantsDateSeparator } from "../../../DateUtils";
|
||||||
|
import CallEventGrouper, { buildCallEventGroupers } from "../../structures/CallEventGrouper";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
// a matrix-js-sdk SearchResult containing the details of this result
|
// a matrix-js-sdk SearchResult containing the details of this result
|
||||||
|
@ -42,6 +44,20 @@ interface IProps {
|
||||||
@replaceableComponent("views.rooms.SearchResultTile")
|
@replaceableComponent("views.rooms.SearchResultTile")
|
||||||
export default class SearchResultTile extends React.Component<IProps> {
|
export default class SearchResultTile extends React.Component<IProps> {
|
||||||
static contextType = RoomContext;
|
static contextType = RoomContext;
|
||||||
|
public context!: React.ContextType<typeof RoomContext>;
|
||||||
|
|
||||||
|
// A map of <callId, CallEventGrouper>
|
||||||
|
private callEventGroupers = new Map<string, CallEventGrouper>();
|
||||||
|
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context);
|
||||||
|
|
||||||
|
this.buildCallEventGroupers(this.props.searchResult.context.getTimeline());
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildCallEventGroupers(events?: MatrixEvent[]): void {
|
||||||
|
this.callEventGroupers = buildCallEventGroupers(this.callEventGroupers, events);
|
||||||
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const result = this.props.searchResult;
|
const result = this.props.searchResult;
|
||||||
|
@ -109,6 +125,7 @@ export default class SearchResultTile extends React.Component<IProps> {
|
||||||
timelineRenderingType={TimelineRenderingType.Search}
|
timelineRenderingType={TimelineRenderingType.Search}
|
||||||
lastInSection={lastInSection}
|
lastInSection={lastInSection}
|
||||||
continuation={continuation}
|
continuation={continuation}
|
||||||
|
callEventGrouper={this.callEventGroupers.get(mxEv.getContent().call_id)}
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
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 * as React from "react";
|
||||||
|
import { mount } from "enzyme";
|
||||||
|
import { SearchResult } from "matrix-js-sdk/src/models/search-result";
|
||||||
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
|
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||||
|
|
||||||
|
import sdk from "../../../skinned-sdk";
|
||||||
|
import { createTestClient } from "../../../test-utils";
|
||||||
|
import EventTile from "../../../../src/components/views/rooms/EventTile";
|
||||||
|
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
||||||
|
|
||||||
|
const SearchResultTile = sdk.getComponent("views.rooms.SearchResultTile");
|
||||||
|
|
||||||
|
describe("SearchResultTile", () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
MatrixClientPeg.get = () => createTestClient();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Sets up appropriate callEventGrouper for m.call. events", () => {
|
||||||
|
const wrapper = mount(
|
||||||
|
<SearchResultTile
|
||||||
|
searchResult={SearchResult.fromJson({
|
||||||
|
rank: 0.00424866,
|
||||||
|
result: {
|
||||||
|
content: {
|
||||||
|
body: "This is an example text message",
|
||||||
|
format: "org.matrix.custom.html",
|
||||||
|
formatted_body: "<b>This is an example text message</b>",
|
||||||
|
msgtype: "m.text",
|
||||||
|
},
|
||||||
|
event_id: "$144429830826TWwbB:localhost",
|
||||||
|
origin_server_ts: 1432735824653,
|
||||||
|
room_id: "!qPewotXpIctQySfjSy:localhost",
|
||||||
|
sender: "@example:example.org",
|
||||||
|
type: "m.room.message",
|
||||||
|
unsigned: {
|
||||||
|
age: 1234,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
context: {
|
||||||
|
end: "",
|
||||||
|
start: "",
|
||||||
|
profile_info: {},
|
||||||
|
events_before: [{
|
||||||
|
type: EventType.CallInvite,
|
||||||
|
sender: "@user1:server",
|
||||||
|
room_id: "!qPewotXpIctQySfjSy:localhost",
|
||||||
|
origin_server_ts: 1432735824652,
|
||||||
|
content: { call_id: "call.1" },
|
||||||
|
event_id: "$1:server",
|
||||||
|
}],
|
||||||
|
events_after: [{
|
||||||
|
type: EventType.CallAnswer,
|
||||||
|
sender: "@user2:server",
|
||||||
|
room_id: "!qPewotXpIctQySfjSy:localhost",
|
||||||
|
origin_server_ts: 1432735824654,
|
||||||
|
content: { call_id: "call.1" },
|
||||||
|
event_id: "$2:server",
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
}, o => new MatrixEvent(o))}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
const tiles = wrapper.find(EventTile);
|
||||||
|
expect(tiles.length).toEqual(2);
|
||||||
|
expect(tiles.at(0).prop("mxEvent").getId()).toBe("$1:server");
|
||||||
|
expect(tiles.at(0).prop("callEventGrouper").events.size).toBe(2);
|
||||||
|
expect(tiles.at(1).prop("mxEvent").getId()).toBe("$144429830826TWwbB:localhost");
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue