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-encrypt-attachment": "^1.0.3",
|
||||||
"matrix-events-sdk": "^0.0.1-beta.7",
|
"matrix-events-sdk": "^0.0.1-beta.7",
|
||||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
"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",
|
"minimist": "^1.2.5",
|
||||||
"opus-recorder": "^8.0.3",
|
"opus-recorder": "^8.0.3",
|
||||||
"pako": "^2.0.3",
|
"pako": "^2.0.3",
|
||||||
|
|
|
@ -21,6 +21,7 @@ import {
|
||||||
IOpenIDUpdate,
|
IOpenIDUpdate,
|
||||||
ISendEventDetails,
|
ISendEventDetails,
|
||||||
ITurnServer,
|
ITurnServer,
|
||||||
|
IReadEventRelationsResult,
|
||||||
IRoomEvent,
|
IRoomEvent,
|
||||||
MatrixCapabilities,
|
MatrixCapabilities,
|
||||||
OpenIDRequestState,
|
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 { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
import { THREAD_RELATION_TYPE } from "matrix-js-sdk/src/models/thread";
|
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 { iterableDiff, iterableIntersection } from "../../utils/iterables";
|
||||||
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
||||||
|
@ -366,4 +368,47 @@ export class StopGapWidgetDriver extends WidgetDriver {
|
||||||
client.off(ClientEvent.TurnServersError, onTurnServersError);
|
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 { mocked, MockedObject } from "jest-mock";
|
||||||
import { Widget, WidgetKind, WidgetDriver, ITurnServer } from "matrix-widget-api";
|
import { ClientEvent, ITurnServer as IClientTurnServer, MatrixClient } from "matrix-js-sdk/src/client";
|
||||||
import { MatrixClient, ClientEvent, ITurnServer as IClientTurnServer } from "matrix-js-sdk/src/client";
|
|
||||||
import { DeviceInfo } from "matrix-js-sdk/src/crypto/deviceinfo";
|
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 { MatrixClientPeg } from "../../../src/MatrixClientPeg";
|
||||||
|
import { RoomViewStore } from "../../../src/stores/RoomViewStore";
|
||||||
import { StopGapWidgetDriver } from "../../../src/stores/widgets/StopGapWidgetDriver";
|
import { StopGapWidgetDriver } from "../../../src/stores/widgets/StopGapWidgetDriver";
|
||||||
import { stubClient } from "../../test-utils";
|
import { stubClient } from "../../test-utils";
|
||||||
|
|
||||||
|
@ -131,4 +133,98 @@ describe("StopGapWidgetDriver", () => {
|
||||||
await servers.return(undefined);
|
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"
|
"@babel/traverse" "^7.18.5"
|
||||||
walk "^2.3.15"
|
walk "^2.3.15"
|
||||||
|
|
||||||
matrix-widget-api@^1.0.0:
|
matrix-widget-api@^1.1.1:
|
||||||
version "1.0.0"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-1.0.0.tgz#0cde6839cca66ad817ab12aca3490ccc8bac97d1"
|
resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-1.1.1.tgz#d3fec45033d0cbc14387a38ba92dac4dbb1be962"
|
||||||
integrity sha512-cy8p/8EteRPTFIAw7Q9EgPUJc2jD19ZahMR8bMKf2NkILDcjuPMC0UWnsJyB3fSnlGw+VbGepttRpULM31zX8Q==
|
integrity sha512-gNSgmgSwvOsOcWK9k2+tOhEMYBiIMwX95vMZu0JqY7apkM02xrOzUBuPRProzN8CnbIALH7e3GAhatF6QCNvtA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/events" "^3.0.0"
|
"@types/events" "^3.0.0"
|
||||||
events "^3.2.0"
|
events "^3.2.0"
|
||||||
|
|
Loading…
Reference in a new issue