Implement MSC3869: Read event relations with the Widget API (#9210)
* Add an action to read relations according to MSC3869 Signed-off-by: Dominik Henneke <dominik.henneke@nordeck.net> * Apply review comments Signed-off-by: Dominik Henneke <dominik.henneke@nordeck.net> * Fix test Signed-off-by: Dominik Henneke <dominik.henneke@nordeck.net> * Update matrix-widget-api to 1.1.1 Signed-off-by: Dominik Henneke <dominik.henneke@nordeck.net> Signed-off-by: Dominik Henneke <dominik.henneke@nordeck.net>
This commit is contained in:
parent
f20d86b7b8
commit
0c22b15bba
4 changed files with 148 additions and 7 deletions
|
@ -94,7 +94,7 @@
|
|||
"matrix-encrypt-attachment": "^1.0.3",
|
||||
"matrix-events-sdk": "^0.0.1-beta.7",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
||||
"matrix-widget-api": "^1.0.0",
|
||||
"matrix-widget-api": "^1.1.1",
|
||||
"minimist": "^1.2.5",
|
||||
"opus-recorder": "^8.0.3",
|
||||
"pako": "^2.0.3",
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
IOpenIDUpdate,
|
||||
ISendEventDetails,
|
||||
ITurnServer,
|
||||
IReadEventRelationsResult,
|
||||
IRoomEvent,
|
||||
MatrixCapabilities,
|
||||
OpenIDRequestState,
|
||||
|
@ -37,6 +38,7 @@ import { IContent, IEvent, MatrixEvent } from "matrix-js-sdk/src/models/event";
|
|||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { THREAD_RELATION_TYPE } from "matrix-js-sdk/src/models/thread";
|
||||
import { Direction } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { iterableDiff, iterableIntersection } from "../../utils/iterables";
|
||||
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
||||
|
@ -366,4 +368,47 @@ export class StopGapWidgetDriver extends WidgetDriver {
|
|||
client.off(ClientEvent.TurnServersError, onTurnServersError);
|
||||
}
|
||||
}
|
||||
|
||||
public async readEventRelations(
|
||||
eventId: string,
|
||||
roomId?: string,
|
||||
relationType?: string,
|
||||
eventType?: string,
|
||||
from?: string,
|
||||
to?: string,
|
||||
limit?: number,
|
||||
direction?: 'f' | 'b',
|
||||
): Promise<IReadEventRelationsResult> {
|
||||
const client = MatrixClientPeg.get();
|
||||
const dir = direction as Direction;
|
||||
roomId = roomId ?? RoomViewStore.instance.getRoomId() ?? undefined;
|
||||
|
||||
if (typeof roomId !== "string") {
|
||||
throw new Error('Error while reading the current room');
|
||||
}
|
||||
|
||||
const {
|
||||
originalEvent,
|
||||
events,
|
||||
nextBatch,
|
||||
prevBatch,
|
||||
} = await client.relations(
|
||||
roomId,
|
||||
eventId,
|
||||
relationType ?? null,
|
||||
eventType ?? null,
|
||||
{
|
||||
from,
|
||||
to,
|
||||
limit,
|
||||
direction: dir,
|
||||
});
|
||||
|
||||
return {
|
||||
originalEvent: originalEvent?.getEffectiveEvent(),
|
||||
chunk: events.map(e => e.getEffectiveEvent()),
|
||||
nextBatch,
|
||||
prevBatch,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,11 +15,13 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import { mocked, MockedObject } from "jest-mock";
|
||||
import { Widget, WidgetKind, WidgetDriver, ITurnServer } from "matrix-widget-api";
|
||||
import { MatrixClient, ClientEvent, ITurnServer as IClientTurnServer } from "matrix-js-sdk/src/client";
|
||||
import { ClientEvent, ITurnServer as IClientTurnServer, MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { DeviceInfo } from "matrix-js-sdk/src/crypto/deviceinfo";
|
||||
import { Direction, MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { ITurnServer, Widget, WidgetDriver, WidgetKind } from "matrix-widget-api";
|
||||
|
||||
import { MatrixClientPeg } from "../../../src/MatrixClientPeg";
|
||||
import { RoomViewStore } from "../../../src/stores/RoomViewStore";
|
||||
import { StopGapWidgetDriver } from "../../../src/stores/widgets/StopGapWidgetDriver";
|
||||
import { stubClient } from "../../test-utils";
|
||||
|
||||
|
@ -131,4 +133,98 @@ describe("StopGapWidgetDriver", () => {
|
|||
await servers.return(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe("readEventRelations", () => {
|
||||
it('reads related events from the current room', async () => {
|
||||
jest.spyOn(RoomViewStore.instance, 'getRoomId').mockReturnValue('!this-room-id');
|
||||
|
||||
client.relations.mockResolvedValue({
|
||||
originalEvent: new MatrixEvent(),
|
||||
events: [],
|
||||
});
|
||||
|
||||
await expect(driver.readEventRelations('$event')).resolves.toEqual({
|
||||
originalEvent: expect.objectContaining({ content: {} }),
|
||||
chunk: [],
|
||||
nextBatch: undefined,
|
||||
prevBatch: undefined,
|
||||
});
|
||||
|
||||
expect(client.relations).toBeCalledWith('!this-room-id', '$event', null, null, {});
|
||||
});
|
||||
|
||||
it('reads related events if the original event is missing', async () => {
|
||||
client.relations.mockResolvedValue({
|
||||
// the relations function can return an undefined event, even
|
||||
// though the typings don't permit an undefined value.
|
||||
originalEvent: undefined as any,
|
||||
events: [],
|
||||
});
|
||||
|
||||
await expect(driver.readEventRelations('$event', '!room-id')).resolves.toEqual({
|
||||
originalEvent: undefined,
|
||||
chunk: [],
|
||||
nextBatch: undefined,
|
||||
prevBatch: undefined,
|
||||
});
|
||||
|
||||
expect(client.relations).toBeCalledWith('!room-id', '$event', null, null, {});
|
||||
});
|
||||
|
||||
it('reads related events from a selected room', async () => {
|
||||
client.relations.mockResolvedValue({
|
||||
originalEvent: new MatrixEvent(),
|
||||
events: [new MatrixEvent(), new MatrixEvent()],
|
||||
nextBatch: 'next-batch-token',
|
||||
});
|
||||
|
||||
await expect(driver.readEventRelations('$event', '!room-id')).resolves.toEqual({
|
||||
originalEvent: expect.objectContaining({ content: {} }),
|
||||
chunk: [
|
||||
expect.objectContaining({ content: {} }),
|
||||
expect.objectContaining({ content: {} }),
|
||||
],
|
||||
nextBatch: 'next-batch-token',
|
||||
prevBatch: undefined,
|
||||
});
|
||||
|
||||
expect(client.relations).toBeCalledWith('!room-id', '$event', null, null, {});
|
||||
});
|
||||
|
||||
it('reads related events with custom parameters', async () => {
|
||||
client.relations.mockResolvedValue({
|
||||
originalEvent: new MatrixEvent(),
|
||||
events: [],
|
||||
});
|
||||
|
||||
await expect(driver.readEventRelations(
|
||||
'$event',
|
||||
'!room-id',
|
||||
'm.reference',
|
||||
'm.room.message',
|
||||
'from-token',
|
||||
'to-token',
|
||||
25,
|
||||
'f',
|
||||
)).resolves.toEqual({
|
||||
originalEvent: expect.objectContaining({ content: {} }),
|
||||
chunk: [],
|
||||
nextBatch: undefined,
|
||||
prevBatch: undefined,
|
||||
});
|
||||
|
||||
expect(client.relations).toBeCalledWith(
|
||||
'!room-id',
|
||||
'$event',
|
||||
'm.reference',
|
||||
'm.room.message',
|
||||
{
|
||||
limit: 25,
|
||||
from: 'from-token',
|
||||
to: 'to-token',
|
||||
direction: Direction.Forward,
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6815,10 +6815,10 @@ matrix-web-i18n@^1.3.0:
|
|||
"@babel/traverse" "^7.18.5"
|
||||
walk "^2.3.15"
|
||||
|
||||
matrix-widget-api@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-1.0.0.tgz#0cde6839cca66ad817ab12aca3490ccc8bac97d1"
|
||||
integrity sha512-cy8p/8EteRPTFIAw7Q9EgPUJc2jD19ZahMR8bMKf2NkILDcjuPMC0UWnsJyB3fSnlGw+VbGepttRpULM31zX8Q==
|
||||
matrix-widget-api@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-1.1.1.tgz#d3fec45033d0cbc14387a38ba92dac4dbb1be962"
|
||||
integrity sha512-gNSgmgSwvOsOcWK9k2+tOhEMYBiIMwX95vMZu0JqY7apkM02xrOzUBuPRProzN8CnbIALH7e3GAhatF6QCNvtA==
|
||||
dependencies:
|
||||
"@types/events" "^3.0.0"
|
||||
events "^3.2.0"
|
||||
|
|
Loading…
Reference in a new issue