UNPKG

matrix-react-sdk

Version:
88 lines (82 loc) 13.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.findDMForUser = findDMForUser; var _types = require("matrix-js-sdk/src/types"); var _DMRoomMap = _interopRequireDefault(require("../DMRoomMap")); var _isLocalRoom = require("../localRoom/isLocalRoom"); var _membership = require("../membership"); var _getFunctionalMembers = require("../room/getFunctionalMembers"); /* Copyright 2024 New Vector Ltd. Copyright 2022 The Matrix.org Foundation C.I.C. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ /** * Iterates the rooms and tries to find a DM room with the user identified by UserId. * A DM room is assumed if one of the following matches: * - Has two members and contains a membership for the user identified by userId * - findRoomWithThirdpartyInvites is true and has one member and a third pending third party invite * * If multiple rooms match it will return the one with the most recent event. * * @param rooms - Rooms to iterate * @param userId - User Id of the other user * @param [findRoomWithThirdpartyInvites] - Whether to find a DM for a pending thirdparty invite * @returns DM room if found or undefined if not */ function extractSuitableRoom(rooms, userId, findRoomWithThirdpartyInvites) { const suitableRooms = rooms.filter(r => { // Validate that we are joined and the other person is also joined. We'll also make sure // that the room also looks like a DM (until we have canonical DMs to tell us). For now, // a DM is a room of two people that contains those two people exactly. This does mean // that bots, assistants, etc will ruin a room's DM-ness, though this is a problem for // canonical DMs to solve. if (r && r.getMyMembership() === _types.KnownMembership.Join) { if ((0, _isLocalRoom.isLocalRoom)(r)) return false; const functionalUsers = (0, _getFunctionalMembers.getFunctionalMembers)(r); const members = r.currentState.getMembers(); const joinedMembers = members.filter(m => !functionalUsers.includes(m.userId) && m.membership && (0, _membership.isJoinedOrNearlyJoined)(m.membership)); const otherMember = joinedMembers.find(m => m.userId === userId); if (otherMember && joinedMembers.length === 2) { return true; } const thirdPartyInvites = r.currentState.getStateEvents("m.room.third_party_invite") || []; // match room with pending third-party invite return findRoomWithThirdpartyInvites && joinedMembers.length === 1 && thirdPartyInvites.length === 1; } return false; }).sort((r1, r2) => { return r2.getLastActiveTimestamp() - r1.getLastActiveTimestamp(); }); if (suitableRooms.length) { return suitableRooms[0]; } return undefined; } /** * Tries to find a DM room with a specific user. * * @param {MatrixClient} client * @param {string} userId ID of the user to find the DM for * @returns {Room | undefined} Room if found */ function findDMForUser(client, userId) { const roomIdsForUserId = _DMRoomMap.default.shared().getDMRoomsForUserId(userId); const roomsForUserId = roomIdsForUserId.map(id => client.getRoom(id)).filter(r => r !== null); // Call with findRoomWithThirdpartyInvites = true to also include rooms with pending thirdparty invites. // roomsForUserId can only contain rooms with the other user here, // because they have been queried by getDMRoomsForUserId(). const suitableRoomForUserId = extractSuitableRoom(roomsForUserId, userId, true); if (suitableRoomForUserId) { return suitableRoomForUserId; } // Try to find in all rooms as a fallback const allRoomIds = _DMRoomMap.default.shared().getRoomIds(); const allRooms = Array.from(allRoomIds).map(id => client.getRoom(id)).filter(r => r !== null); return extractSuitableRoom(allRooms, userId, false); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdHlwZXMiLCJyZXF1aXJlIiwiX0RNUm9vbU1hcCIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfaXNMb2NhbFJvb20iLCJfbWVtYmVyc2hpcCIsIl9nZXRGdW5jdGlvbmFsTWVtYmVycyIsImV4dHJhY3RTdWl0YWJsZVJvb20iLCJyb29tcyIsInVzZXJJZCIsImZpbmRSb29tV2l0aFRoaXJkcGFydHlJbnZpdGVzIiwic3VpdGFibGVSb29tcyIsImZpbHRlciIsInIiLCJnZXRNeU1lbWJlcnNoaXAiLCJLbm93bk1lbWJlcnNoaXAiLCJKb2luIiwiaXNMb2NhbFJvb20iLCJmdW5jdGlvbmFsVXNlcnMiLCJnZXRGdW5jdGlvbmFsTWVtYmVycyIsIm1lbWJlcnMiLCJjdXJyZW50U3RhdGUiLCJnZXRNZW1iZXJzIiwiam9pbmVkTWVtYmVycyIsIm0iLCJpbmNsdWRlcyIsIm1lbWJlcnNoaXAiLCJpc0pvaW5lZE9yTmVhcmx5Sm9pbmVkIiwib3RoZXJNZW1iZXIiLCJmaW5kIiwibGVuZ3RoIiwidGhpcmRQYXJ0eUludml0ZXMiLCJnZXRTdGF0ZUV2ZW50cyIsInNvcnQiLCJyMSIsInIyIiwiZ2V0TGFzdEFjdGl2ZVRpbWVzdGFtcCIsInVuZGVmaW5lZCIsImZpbmRETUZvclVzZXIiLCJjbGllbnQiLCJyb29tSWRzRm9yVXNlcklkIiwiRE1Sb29tTWFwIiwic2hhcmVkIiwiZ2V0RE1Sb29tc0ZvclVzZXJJZCIsInJvb21zRm9yVXNlcklkIiwibWFwIiwiaWQiLCJnZXRSb29tIiwic3VpdGFibGVSb29tRm9yVXNlcklkIiwiYWxsUm9vbUlkcyIsImdldFJvb21JZHMiLCJhbGxSb29tcyIsIkFycmF5IiwiZnJvbSJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy91dGlscy9kbS9maW5kRE1Gb3JVc2VyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDIyIFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCB7IE1hdHJpeENsaWVudCwgUm9vbSB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9tYXRyaXhcIjtcbmltcG9ydCB7IEtub3duTWVtYmVyc2hpcCB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy90eXBlc1wiO1xuXG5pbXBvcnQgRE1Sb29tTWFwIGZyb20gXCIuLi9ETVJvb21NYXBcIjtcbmltcG9ydCB7IGlzTG9jYWxSb29tIH0gZnJvbSBcIi4uL2xvY2FsUm9vbS9pc0xvY2FsUm9vbVwiO1xuaW1wb3J0IHsgaXNKb2luZWRPck5lYXJseUpvaW5lZCB9IGZyb20gXCIuLi9tZW1iZXJzaGlwXCI7XG5pbXBvcnQgeyBnZXRGdW5jdGlvbmFsTWVtYmVycyB9IGZyb20gXCIuLi9yb29tL2dldEZ1bmN0aW9uYWxNZW1iZXJzXCI7XG5cbi8qKlxuICogSXRlcmF0ZXMgdGhlIHJvb21zIGFuZCB0cmllcyB0byBmaW5kIGEgRE0gcm9vbSB3aXRoIHRoZSB1c2VyIGlkZW50aWZpZWQgYnkgVXNlcklkLlxuICogQSBETSByb29tIGlzIGFzc3VtZWQgaWYgb25lIG9mIHRoZSBmb2xsb3dpbmcgbWF0Y2hlczpcbiAqIC0gSGFzIHR3byBtZW1iZXJzIGFuZCBjb250YWlucyBhIG1lbWJlcnNoaXAgZm9yIHRoZSB1c2VyIGlkZW50aWZpZWQgYnkgdXNlcklkXG4gKiAtIGZpbmRSb29tV2l0aFRoaXJkcGFydHlJbnZpdGVzIGlzIHRydWUgYW5kIGhhcyBvbmUgbWVtYmVyIGFuZCBhIHRoaXJkIHBlbmRpbmcgdGhpcmQgcGFydHkgaW52aXRlXG4gKlxuICogSWYgbXVsdGlwbGUgcm9vbXMgbWF0Y2ggaXQgd2lsbCByZXR1cm4gdGhlIG9uZSB3aXRoIHRoZSBtb3N0IHJlY2VudCBldmVudC5cbiAqXG4gKiBAcGFyYW0gcm9vbXMgLSBSb29tcyB0byBpdGVyYXRlXG4gKiBAcGFyYW0gdXNlcklkIC0gVXNlciBJZCBvZiB0aGUgb3RoZXIgdXNlclxuICogQHBhcmFtIFtmaW5kUm9vbVdpdGhUaGlyZHBhcnR5SW52aXRlc10gLSBXaGV0aGVyIHRvIGZpbmQgYSBETSBmb3IgYSBwZW5kaW5nIHRoaXJkcGFydHkgaW52aXRlXG4gKiBAcmV0dXJucyBETSByb29tIGlmIGZvdW5kIG9yIHVuZGVmaW5lZCBpZiBub3RcbiAqL1xuZnVuY3Rpb24gZXh0cmFjdFN1aXRhYmxlUm9vbShyb29tczogUm9vbVtdLCB1c2VySWQ6IHN0cmluZywgZmluZFJvb21XaXRoVGhpcmRwYXJ0eUludml0ZXM6IGJvb2xlYW4pOiBSb29tIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBzdWl0YWJsZVJvb21zID0gcm9vbXNcbiAgICAgICAgLmZpbHRlcigocikgPT4ge1xuICAgICAgICAgICAgLy8gVmFsaWRhdGUgdGhhdCB3ZSBhcmUgam9pbmVkIGFuZCB0aGUgb3RoZXIgcGVyc29uIGlzIGFsc28gam9pbmVkLiBXZSdsbCBhbHNvIG1ha2Ugc3VyZVxuICAgICAgICAgICAgLy8gdGhhdCB0aGUgcm9vbSBhbHNvIGxvb2tzIGxpa2UgYSBETSAodW50aWwgd2UgaGF2ZSBjYW5vbmljYWwgRE1zIHRvIHRlbGwgdXMpLiBGb3Igbm93LFxuICAgICAgICAgICAgLy8gYSBETSBpcyBhIHJvb20gb2YgdHdvIHBlb3BsZSB0aGF0IGNvbnRhaW5zIHRob3NlIHR3byBwZW9wbGUgZXhhY3RseS4gVGhpcyBkb2VzIG1lYW5cbiAgICAgICAgICAgIC8vIHRoYXQgYm90cywgYXNzaXN0YW50cywgZXRjIHdpbGwgcnVpbiBhIHJvb20ncyBETS1uZXNzLCB0aG91Z2ggdGhpcyBpcyBhIHByb2JsZW0gZm9yXG4gICAgICAgICAgICAvLyBjYW5vbmljYWwgRE1zIHRvIHNvbHZlLlxuICAgICAgICAgICAgaWYgKHIgJiYgci5nZXRNeU1lbWJlcnNoaXAoKSA9PT0gS25vd25NZW1iZXJzaGlwLkpvaW4pIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNMb2NhbFJvb20ocikpIHJldHVybiBmYWxzZTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGZ1bmN0aW9uYWxVc2VycyA9IGdldEZ1bmN0aW9uYWxNZW1iZXJzKHIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lbWJlcnMgPSByLmN1cnJlbnRTdGF0ZS5nZXRNZW1iZXJzKCk7XG4gICAgICAgICAgICAgICAgY29uc3Qgam9pbmVkTWVtYmVycyA9IG1lbWJlcnMuZmlsdGVyKFxuICAgICAgICAgICAgICAgICAgICAobSkgPT4gIWZ1bmN0aW9uYWxVc2Vycy5pbmNsdWRlcyhtLnVzZXJJZCkgJiYgbS5tZW1iZXJzaGlwICYmIGlzSm9pbmVkT3JOZWFybHlKb2luZWQobS5tZW1iZXJzaGlwKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnN0IG90aGVyTWVtYmVyID0gam9pbmVkTWVtYmVycy5maW5kKChtKSA9PiBtLnVzZXJJZCA9PT0gdXNlcklkKTtcblxuICAgICAgICAgICAgICAgIGlmIChvdGhlck1lbWJlciAmJiBqb2luZWRNZW1iZXJzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCB0aGlyZFBhcnR5SW52aXRlcyA9IHIuY3VycmVudFN0YXRlLmdldFN0YXRlRXZlbnRzKFwibS5yb29tLnRoaXJkX3BhcnR5X2ludml0ZVwiKSB8fCBbXTtcblxuICAgICAgICAgICAgICAgIC8vIG1hdGNoIHJvb20gd2l0aCBwZW5kaW5nIHRoaXJkLXBhcnR5IGludml0ZVxuICAgICAgICAgICAgICAgIHJldHVybiBmaW5kUm9vbVdpdGhUaGlyZHBhcnR5SW52aXRlcyAmJiBqb2luZWRNZW1iZXJzLmxlbmd0aCA9PT0gMSAmJiB0aGlyZFBhcnR5SW52aXRlcy5sZW5ndGggPT09IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0pXG4gICAgICAgIC5zb3J0KChyMSwgcjIpID0+IHtcbiAgICAgICAgICAgIHJldHVybiByMi5nZXRMYXN0QWN0aXZlVGltZXN0YW1wKCkgLSByMS5nZXRMYXN0QWN0aXZlVGltZXN0YW1wKCk7XG4gICAgICAgIH0pO1xuXG4gICAgaWYgKHN1aXRhYmxlUm9vbXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBzdWl0YWJsZVJvb21zWzBdO1xuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogVHJpZXMgdG8gZmluZCBhIERNIHJvb20gd2l0aCBhIHNwZWNpZmljIHVzZXIuXG4gKlxuICogQHBhcmFtIHtNYXRyaXhDbGllbnR9IGNsaWVudFxuICogQHBhcmFtIHtzdHJpbmd9IHVzZXJJZCBJRCBvZiB0aGUgdXNlciB0byBmaW5kIHRoZSBETSBmb3JcbiAqIEByZXR1cm5zIHtSb29tIHwgdW5kZWZpbmVkfSBSb29tIGlmIGZvdW5kXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kRE1Gb3JVc2VyKGNsaWVudDogTWF0cml4Q2xpZW50LCB1c2VySWQ6IHN0cmluZyk6IFJvb20gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHJvb21JZHNGb3JVc2VySWQgPSBETVJvb21NYXAuc2hhcmVkKCkuZ2V0RE1Sb29tc0ZvclVzZXJJZCh1c2VySWQpO1xuICAgIGNvbnN0IHJvb21zRm9yVXNlcklkID0gcm9vbUlkc0ZvclVzZXJJZC5tYXAoKGlkKSA9PiBjbGllbnQuZ2V0Um9vbShpZCkpLmZpbHRlcigocik6IHIgaXMgUm9vbSA9PiByICE9PSBudWxsKTtcbiAgICAvLyBDYWxsIHdpdGggZmluZFJvb21XaXRoVGhpcmRwYXJ0eUludml0ZXMgPSB0cnVlIHRvIGFsc28gaW5jbHVkZSByb29tcyB3aXRoIHBlbmRpbmcgdGhpcmRwYXJ0eSBpbnZpdGVzLlxuICAgIC8vIHJvb21zRm9yVXNlcklkIGNhbiBvbmx5IGNvbnRhaW4gcm9vbXMgd2l0aCB0aGUgb3RoZXIgdXNlciBoZXJlLFxuICAgIC8vIGJlY2F1c2UgdGhleSBoYXZlIGJlZW4gcXVlcmllZCBieSBnZXRETVJvb21zRm9yVXNlcklkKCkuXG4gICAgY29uc3Qgc3VpdGFibGVSb29tRm9yVXNlcklkID0gZXh0cmFjdFN1aXRhYmxlUm9vbShyb29tc0ZvclVzZXJJZCwgdXNlcklkLCB0cnVlKTtcblxuICAgIGlmIChzdWl0YWJsZVJvb21Gb3JVc2VySWQpIHtcbiAgICAgICAgcmV0dXJuIHN1aXRhYmxlUm9vbUZvclVzZXJJZDtcbiAgICB9XG5cbiAgICAvLyBUcnkgdG8gZmluZCBpbiBhbGwgcm9vbXMgYXMgYSBmYWxsYmFja1xuICAgIGNvbnN0IGFsbFJvb21JZHMgPSBETVJvb21NYXAuc2hhcmVkKCkuZ2V0Um9vbUlkcygpO1xuICAgIGNvbnN0IGFsbFJvb21zID0gQXJyYXkuZnJvbShhbGxSb29tSWRzKVxuICAgICAgICAubWFwKChpZCkgPT4gY2xpZW50LmdldFJvb20oaWQpKVxuICAgICAgICAuZmlsdGVyKChyKTogciBpcyBSb29tID0+IHIgIT09IG51bGwpO1xuICAgIHJldHVybiBleHRyYWN0U3VpdGFibGVSb29tKGFsbFJvb21zLCB1c2VySWQsIGZhbHNlKTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQVNBLElBQUFBLE1BQUEsR0FBQUMsT0FBQTtBQUVBLElBQUFDLFVBQUEsR0FBQUMsc0JBQUEsQ0FBQUYsT0FBQTtBQUNBLElBQUFHLFlBQUEsR0FBQUgsT0FBQTtBQUNBLElBQUFJLFdBQUEsR0FBQUosT0FBQTtBQUNBLElBQUFLLHFCQUFBLEdBQUFMLE9BQUE7QUFkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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