Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
65762c4
Switch sliding sync support to simplified sliding sync
dbkr Sep 12, 2024
2593998
Remove txn_id handling, ensure we always resend when req params change
kegsay Sep 13, 2024
6fba79c
Fix some tests
kegsay Sep 13, 2024
e26e926
Fix remaining tests
kegsay Sep 13, 2024
c75c06a
Mark TODOs on tests which need to die
kegsay Sep 13, 2024
7444094
Linting
kegsay Sep 13, 2024
bf7be48
Make comments lie less
kegsay Sep 13, 2024
ade2c86
void
kegsay Sep 13, 2024
b8c3419
Always sent full extension request
kegsay Sep 13, 2024
85400e9
Fix test
kegsay Sep 13, 2024
c44818f
Remove usage of deprecated field
kegsay Sep 13, 2024
aeeb25f
Hopefully fix DM names
kegsay Sep 13, 2024
244ca62
Refactor how heroes are handled in Room
kegsay Sep 16, 2024
bd3f9f7
Fix how heroes work
kegsay Sep 16, 2024
581b419
Linting
kegsay Sep 16, 2024
39b4e9d
Ensure that when SSS omits heroes we don't forget we had heroes
kegsay Sep 16, 2024
11e7a3d
Check the right flag when doing timeline trickling
kegsay Sep 16, 2024
511a873
Also change when the backpagination token is set
kegsay Sep 16, 2024
181d786
Remove list ops and server-provided sort positions
kegsay Sep 17, 2024
679a984
Linting
kegsay Sep 17, 2024
cf37e43
Add Room.bumpStamp
kegsay Sep 17, 2024
426aa93
Update crypto wasm lib
kegsay Sep 18, 2024
63a636f
Add performance logging
kegsay Sep 18, 2024
f8d4161
Fix breaking change in crypto wasm v8
kegsay Sep 18, 2024
1fd6675
Update crypto wasm for breaking changes
kegsay Sep 18, 2024
8616294
Mark all tracked users as dirty on expired SSS connections
kegsay Sep 18, 2024
3833273
Merge remote-tracking branch 'origin/develop' into dbkr/sss
dbkr Nov 21, 2024
8b7213b
add ts extension
dbkr Nov 21, 2024
c6f8440
Fix typedoc ref
dbkr Nov 21, 2024
336797e
Add method to interface
dbkr Nov 21, 2024
af846e7
Merge branch 'develop' into dbkr/sss
dbkr Dec 13, 2024
ec83c14
Don't force membership to invite
dbkr Dec 17, 2024
a75a263
Merge branch 'develop' into dbkr/sss
dbkr Feb 12, 2025
dec2cb0
Missed merge
dbkr Feb 12, 2025
1634b83
Type import
dbkr Feb 12, 2025
ebef4cd
Make coverage happier
dbkr Feb 12, 2025
ef87316
More test coverage
dbkr Feb 12, 2025
1dc3b4c
Merge branch 'develop' into dbkr/sss
dbkr Feb 17, 2025
f1d53cf
Grammar & formatting
dbkr Mar 6, 2025
4ece850
Remove markAllTrackedUsersAsDirty from crypto API
dbkr Mar 6, 2025
60f7bca
Remove I from interface
dbkr Mar 6, 2025
7954040
API doc
dbkr Mar 6, 2025
1d020df
Move Hero definition to room-summary
dbkr Mar 6, 2025
cc6ad7f
make comment more specific
dbkr Mar 6, 2025
e4527b5
Move internal details into room.ts
dbkr Mar 6, 2025
42099bb
Use terser arrow function syntax
dbkr Mar 7, 2025
38467e6
Move comment to where we do the lookup
dbkr Mar 6, 2025
ff25912
Clarify comment
dbkr Mar 7, 2025
26069c9
Add comment
dbkr Mar 7, 2025
de7c5ea
Add tsdoc
dbkr Mar 7, 2025
8a26967
more comment
dbkr Mar 7, 2025
a7d013f
Remove unrelated changes
dbkr Mar 7, 2025
7028a88
Add docs & make fields optional
dbkr Mar 7, 2025
ee0219e
Type import
dbkr Mar 7, 2025
eeffb20
Merge branch 'develop' into dbkr/sss
dbkr Mar 10, 2025
d55a9ea
Clarify sync versions
dbkr Mar 13, 2025
6ea801b
Make tsdoc comment & add info on when it's used.
dbkr Mar 13, 2025
5a30e34
Rephrase comment
dbkr Mar 13, 2025
8ca0c04
Prettier
dbkr Mar 13, 2025
7506df2
Only fetch member for hero in legacy sync mode
dbkr Mar 14, 2025
7d8aeee
Split out a separate method to set SSS room summary
dbkr Mar 14, 2025
54492a8
Type import
dbkr Mar 14, 2025
793ae01
Make link work
dbkr Mar 14, 2025
d793a10
Nope, linter treats it as an unused import
dbkr Mar 14, 2025
7cca95a
Add link the other way
dbkr Mar 14, 2025
085a2d4
Add more detail to doc
dbkr Mar 18, 2025
bd6ba39
Remove unnecessary cast
dbkr Mar 18, 2025
7e1eb16
Remove length > 0 check
dbkr Mar 18, 2025
5c44bbb
Doc params
dbkr Mar 18, 2025
5f0b2e3
Remove unnecessary undefined comparison
dbkr Mar 18, 2025
0030998
Put the comparison back
dbkr Mar 18, 2025
707a7f5
Fix comment
dbkr Mar 18, 2025
532d885
Fix comment
dbkr Mar 18, 2025
06b0fd4
Merge branch 'develop' into dbkr/sss
dbkr Mar 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions spec/unit/room.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1239,9 +1239,7 @@ describe("Room", function () {
const nameC = "Clarissa Harissa";
addMember(userB, KnownMembership.Join, { name: nameB });
addMember(userC, KnownMembership.Join, { name: nameC });
room.setSummary({
"m.heroes": [{ userId: userB }, { userId: userC }],
});
room.setMSC4186SummaryData([{ user_id: userB }, { user_id: userC }], undefined, undefined);
room.recalculate();
expect(room.name).toEqual(`${nameB} and ${nameC}`);
});
Expand Down
30 changes: 9 additions & 21 deletions src/models/room-summary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,23 @@ limitations under the License.

/**
* A stripped m.room.member event which contains the key renderable fields from the event,
* sent only in simplified sliding sync (not sync v2).
* sent only in simplified sliding sync (not `/v3/sync`).
* This is very similar to MSC4186Hero from sliding-sync.ts but an internal format with
* camelCase rather than underscores.
*/
export type Hero = {
userId: string;
displayName?: string;
avatarUrl?: string;
/**
* If true, the hero is from an MSC4186 summary, in which case `displayName` and `avatarUrl` will
* have been set by the server if available. If false, these fields will always be undefined.
*/
fromMSC4186: boolean;
};

/**
* High level summary information for a room
* High level summary information for a room, as returned by `/v3/sync`.
*/
export interface IRoomSummary {
/**
Expand All @@ -43,25 +50,6 @@ export interface IRoomSummary {
"m.invited_member_count"?: number;
}

/**
* High level summary information for a room (MSC4186 sliding sync)
*/
export interface RoomSummaryMSC4186 {
/**
* The room heroes: a selected set of members that can be used when summarising or
* generating a name for a room.
*/
"m.heroes": Hero[];
/**
* The number of joined members in the room.
*/
"m.joined_member_count"?: number;
/**
* The number of invited members in the room.
*/
"m.invited_member_count"?: number;
}

interface IInfo {
/** The title of the room (e.g. `m.room.name`) */
title: string;
Expand Down
74 changes: 55 additions & 19 deletions src/models/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
} from "./event.ts";
import { EventStatus } from "./event-status.ts";
import { RoomMember } from "./room-member.ts";
import { type IRoomSummary, type RoomSummaryMSC4186, type Hero, RoomSummary } from "./room-summary.ts";
import { type IRoomSummary, type Hero, RoomSummary } from "./room-summary.ts";
import { logger } from "../logger.ts";
import { TypedReEmitter } from "../ReEmitter.ts";
import {
Expand Down Expand Up @@ -77,6 +77,7 @@ import { compareEventOrdering } from "./compare-event-ordering.ts";
import * as utils from "../utils.ts";
import { KnownMembership, type Membership } from "../@types/membership.ts";
import { type Capabilities, type IRoomVersionsCapability, RoomVersionStability } from "../serverCapabilities.ts";
import { type MSC4186Hero } from "../sliding-sync.ts";

// These constants are used as sane defaults when the homeserver doesn't support
// the m.room_versions capability. In practice, KNOWN_SAFE_ROOM_VERSION should be
Expand Down Expand Up @@ -362,8 +363,15 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
// read by megolm via getter; boolean value - null indicates "use global value"
private blacklistUnverifiedDevices?: boolean;
private selfMembership?: Membership;
// A Hero is a stripped m.room.member event which contains the key renderable fields from the event.
// It is used in MSC4186 (Simplified Sliding Sync) as a replacement for the old 'summary' field.
/**
* A `Hero` is a stripped `m.room.member` event which contains the important renderable fields from the event.
*
* It is used in MSC4186 (Simplified Sliding Sync) as a replacement for the old `summary` field.
*
* When we are doing old-style (`/v3/sync`) sync, we simulate the SSS behaviour by constructing
* a `Hero` object based on the user id we get from the summary. Obviously, in that case,
* the `Hero` will lack a `displayName` or `avatarUrl`.
*/
private heroes: Hero[] | null = null;
// flags to stop logspam about missing m.room.create events
private getTypeWarning = false;
Expand Down Expand Up @@ -949,13 +957,9 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
// use first hero that has a display name or avatar url, or whose user ID
// can be looked up as a member of the room
for (const hero of nonFunctionalHeroes) {
// The old form of heroes simply contained the hero's user ID, which forced clients to then look up the
// m.room.member event in the current state. This is entirely decoupled in SSS. To ensure this
// works in a backwards compatible way, we will A) only set displayName/avatarUrl with server-provided
// values, B) always prefer the hero values if they are set, over calling `.getMember`. This means
// in SSS mode we will use the heroes if the display name or avatar URL fields are set, but in sync v2
// mode these fields will never be set and hence we will always do getMember lookups (at the right time as well).
if (!hero.displayName && !hero.avatarUrl) {
// If the hero was from a legacy sync (`/v3/sync`), we will need to look the user ID up in the room
// the display name and avatar URL will not be set.
if (!hero.fromMSC4186) {
// attempt to look up renderable fields from the m.room.member event if it exists
const member = this.getMember(hero.userId);
if (member) {
Expand Down Expand Up @@ -1675,15 +1679,12 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
}

/**
* Takes either a legacy or MSC4186 room summary and updates the room with it.
* The summary will be converted to a legacy style summary in order to be emitted
* in the `RoomEvent.Summary` event.
* Takes a legacy room summary (/v3/sync as opposed to MSC4186) and updates the room with it.
*
* @param summary - The room summary to update the room with
*/
public setSummary(summary: IRoomSummary | RoomSummaryMSC4186): void {
// map heroes onto the MSC4186 form as that has more data
const heroes = summary["m.heroes"]?.map((h) => (typeof h === "string" ? { userId: h } : h));
public setSummary(summary: IRoomSummary): void {
const heroes = summary["m.heroes"]?.map((h) => ({ userId: h, fromMSC4186: false }));
const joinedCount = summary["m.joined_member_count"];
const invitedCount = summary["m.invited_member_count"];
if (Number.isInteger(joinedCount)) {
Expand All @@ -1699,12 +1700,47 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
});
}

// Convert back to the legacy heroes format for the `RoomEvent.Summary` event.
summary["m.heroes"] = heroes?.map((h) => h.userId);

this.emit(RoomEvent.Summary, summary as IRoomSummary);
}

/**
* Takes information from the MSC4186 room summary and updates the room with it.
*
* @param heroes
* @param joinedCount
* @param invitedCount
*/
public setMSC4186SummaryData(
heroes: MSC4186Hero[] | undefined,
joinedCount: number | undefined,
invitedCount: number | undefined,
): void {
if (heroes) {
this.heroes = heroes
.filter((h) => h.user_id !== this.myUserId)
.map((h) => ({
userId: h.user_id,
displayName: h.displayname,
avatarUrl: h.avatar_url,
fromMSC4186: true,
}));
}
if (joinedCount !== undefined && Number.isInteger(joinedCount)) {
this.currentState.setJoinedMemberCount(joinedCount);
}
if (invitedCount !== undefined && Number.isInteger(invitedCount)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typescript complains without these checks as Number.isInteger doesn't accept undefined for whatever reason.

this.currentState.setInvitedMemberCount(invitedCount);
}

// Construct a summary object to emit as the event wants the info in a single object
// more like old-style (/v3/sync) summaries.
this.emit(RoomEvent.Summary, {
"m.heroes": this.heroes ? this.heroes.map((h) => h.userId) : [],
"m.joined_member_count": joinedCount,
"m.invited_member_count": invitedCount,
});
}

/**
* Whether to send encrypted messages to devices within this room.
* @param value - true to blacklist unverified devices, null
Expand Down
14 changes: 1 addition & 13 deletions src/sliding-sync-sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -726,19 +726,7 @@ export class SlidingSyncSdk {
// synchronous execution prior to emitting SlidingSyncState.Complete
room.updateMyMembership(KnownMembership.Join);

room.setSummary({
"m.heroes": roomData.heroes
? roomData.heroes.map((h) => {
return {
userId: h.user_id,
avatarUrl: h.avatar_url,
displayName: h.displayname,
};
})
: [],
"m.invited_member_count": roomData.invited_count,
"m.joined_member_count": roomData.joined_count,
});
room.setMSC4186SummaryData(roomData.heroes, roomData.joined_count, roomData.invited_count);

room.recalculate();
if (roomData.initial) {
Expand Down
4 changes: 3 additions & 1 deletion src/sliding-sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ export interface MSC3575SlidingSyncRequest {

/**
* New format of hero introduced in MSC4186 with display name and avatar URL
* in addition to just user_id
* in addition to just user_id (as it is on the wire, with underscores)
* as opposed to Hero in room-summary.ts which has fields in camelCase
* (and also a flag to note what format the hero came from).
*/
export interface MSC4186Hero {
user_id: string;
Expand Down