Skip to content

Commit 3ce45ef

Browse files
authored
Merge pull request matrix-org#5424 from matrix-org/travis/fix-dms
Fix DM logic to always pick a more reliable DM room
2 parents e05fcc8 + 91b1c8b commit 3ce45ef

File tree

4 files changed

+29
-20
lines changed

4 files changed

+29
-20
lines changed

src/components/views/dialogs/InviteDialog.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import dis from "../../../dispatcher/dispatcher";
3131
import IdentityAuthClient from "../../../IdentityAuthClient";
3232
import Modal from "../../../Modal";
3333
import {humanizeTime} from "../../../utils/humanize";
34-
import createRoom, {canEncryptToAllUsers, privateShouldBeEncrypted} from "../../../createRoom";
34+
import createRoom, {canEncryptToAllUsers, findDMForUser, privateShouldBeEncrypted} from "../../../createRoom";
3535
import {inviteMultipleToRoom, showCommunityInviteDialog} from "../../../RoomInvite";
3636
import {Key} from "../../../Keyboard";
3737
import {Action} from "../../../dispatcher/actions";
@@ -41,6 +41,7 @@ import {CommunityPrototypeStore} from "../../../stores/CommunityPrototypeStore";
4141
import SettingsStore from "../../../settings/SettingsStore";
4242
import {UIFeature} from "../../../settings/UIFeature";
4343
import CountlyAnalytics from "../../../CountlyAnalytics";
44+
import {Room} from "matrix-js-sdk/src/models/room";
4445

4546
// we have a number of types defined from the Matrix spec which can't reasonably be altered here.
4647
/* eslint-disable camelcase */
@@ -575,7 +576,12 @@ export default class InviteDialog extends React.PureComponent {
575576
const targetIds = targets.map(t => t.userId);
576577

577578
// Check if there is already a DM with these people and reuse it if possible.
578-
const existingRoom = DMRoomMap.shared().getDMRoomForIdentifiers(targetIds);
579+
let existingRoom: Room;
580+
if (targetIds.length === 1) {
581+
existingRoom = findDMForUser(MatrixClientPeg.get(), targetIds[0]);
582+
} else {
583+
existingRoom = DMRoomMap.shared().getDMRoomForIdentifiers(targetIds);
584+
}
579585
if (existingRoom) {
580586
dis.dispatch({
581587
action: 'view_room',

src/components/views/right_panel/UserInfo.tsx

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {EventTimeline} from 'matrix-js-sdk/src/models/event-timeline';
2828
import dis from '../../../dispatcher/dispatcher';
2929
import Modal from '../../../Modal';
3030
import {_t} from '../../../languageHandler';
31-
import createRoom, {privateShouldBeEncrypted} from '../../../createRoom';
31+
import createRoom, { findDMForUser, privateShouldBeEncrypted } from '../../../createRoom';
3232
import DMRoomMap from '../../../utils/DMRoomMap';
3333
import AccessibleButton from '../elements/AccessibleButton';
3434
import SdkConfig from '../../../SdkConfig';
@@ -105,17 +105,7 @@ export const getE2EStatus = (cli: MatrixClient, userId: string, devices: IDevice
105105
};
106106

107107
async function openDMForUser(matrixClient: MatrixClient, userId: string) {
108-
const dmRooms = DMRoomMap.shared().getDMRoomsForUserId(userId);
109-
const lastActiveRoom = dmRooms.reduce((lastActiveRoom, roomId) => {
110-
const room = matrixClient.getRoom(roomId);
111-
if (!room || room.getMyMembership() === "leave") {
112-
return lastActiveRoom;
113-
}
114-
if (!lastActiveRoom || lastActiveRoom.getLastActiveTimestamp() < room.getLastActiveTimestamp()) {
115-
return room;
116-
}
117-
return lastActiveRoom;
118-
}, null);
108+
const lastActiveRoom = findDMForUser(matrixClient, userId);
119109

120110
if (lastActiveRoom) {
121111
dis.dispatch({

src/createRoom.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,21 @@ See the License for the specific language governing permissions and
1515
limitations under the License.
1616
*/
1717

18-
import {MatrixClient} from "matrix-js-sdk/src/client";
19-
import {Room} from "matrix-js-sdk/src/models/room";
18+
import { MatrixClient } from "matrix-js-sdk/src/client";
19+
import { Room } from "matrix-js-sdk/src/models/room";
2020

21-
import {MatrixClientPeg} from './MatrixClientPeg';
21+
import { MatrixClientPeg } from './MatrixClientPeg';
2222
import Modal from './Modal';
2323
import * as sdk from './index';
2424
import { _t } from './languageHandler';
2525
import dis from "./dispatcher/dispatcher";
2626
import * as Rooms from "./Rooms";
2727
import DMRoomMap from "./utils/DMRoomMap";
28-
import {getAddressType} from "./UserAddress";
28+
import { getAddressType } from "./UserAddress";
2929
import { getE2EEWellKnown } from "./utils/WellKnownUtils";
3030
import GroupStore from "./stores/GroupStore";
3131
import CountlyAnalytics from "./CountlyAnalytics";
32+
import { isJoinedOrNearlyJoined } from "./utils/membership";
3233

3334
// we define a number of interfaces which take their names from the js-sdk
3435
/* eslint-disable camelcase */
@@ -236,9 +237,16 @@ export function findDMForUser(client: MatrixClient, userId: string): Room {
236237
const roomIds = DMRoomMap.shared().getDMRoomsForUserId(userId);
237238
const rooms = roomIds.map(id => client.getRoom(id));
238239
const suitableDMRooms = rooms.filter(r => {
240+
// Validate that we are joined and the other person is also joined. We'll also make sure
241+
// that the room also looks like a DM (until we have canonical DMs to tell us). For now,
242+
// a DM is a room of two people that contains those two people exactly. This does mean
243+
// that bots, assistants, etc will ruin a room's DM-ness, though this is a problem for
244+
// canonical DMs to solve.
239245
if (r && r.getMyMembership() === "join") {
240-
const member = r.getMember(userId);
241-
return member && (member.membership === "invite" || member.membership === "join");
246+
const members = r.currentState.getMembers();
247+
const joinedMembers = members.filter(m => isJoinedOrNearlyJoined(m.membership));
248+
const otherMember = joinedMembers.find(m => m.userId === userId);
249+
return otherMember && joinedMembers.length === 2;
242250
}
243251
return false;
244252
}).sort((r1, r2) => {

src/utils/membership.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ export function getEffectiveMembership(membership: string): EffectiveMembership
7878
}
7979
}
8080

81+
export function isJoinedOrNearlyJoined(membership: string): boolean {
82+
const effective = getEffectiveMembership(membership);
83+
return effective === EffectiveMembership.Join || effective === EffectiveMembership.Invite;
84+
}
85+
8186
export async function leaveRoomBehaviour(roomId: string) {
8287
let leavingAllVersions = true;
8388
const history = await MatrixClientPeg.get().getRoomUpgradeHistory(roomId);

0 commit comments

Comments
 (0)