summaryrefslogtreecommitdiff
path: root/includes/external/matrix/node_modules/matrix-js-sdk/src/models/room-member.ts
diff options
context:
space:
mode:
authorRaindropsSys <raindrops@equestria.dev>2023-11-17 23:25:29 +0100
committerRaindropsSys <raindrops@equestria.dev>2023-11-17 23:25:29 +0100
commit953ddd82e48dd206cef5ac94456549aed13b3ad5 (patch)
tree8f003106ee2e7f422e5a22d2ee04d0db302e66c0 /includes/external/matrix/node_modules/matrix-js-sdk/src/models/room-member.ts
parent62a9199846b0c07c03218703b33e8385764f42d9 (diff)
downloadpluralconnect-953ddd82e48dd206cef5ac94456549aed13b3ad5.tar.gz
pluralconnect-953ddd82e48dd206cef5ac94456549aed13b3ad5.tar.bz2
pluralconnect-953ddd82e48dd206cef5ac94456549aed13b3ad5.zip
Updated 30 files and deleted 2976 files (automated)
Diffstat (limited to 'includes/external/matrix/node_modules/matrix-js-sdk/src/models/room-member.ts')
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/src/models/room-member.ts453
1 files changed, 0 insertions, 453 deletions
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/models/room-member.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/models/room-member.ts
deleted file mode 100644
index 116a93b..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/src/models/room-member.ts
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
-Copyright 2015 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-import { getHttpUriForMxc } from "../content-repo";
-import * as utils from "../utils";
-import { User } from "./user";
-import { MatrixEvent } from "./event";
-import { RoomState } from "./room-state";
-import { logger } from "../logger";
-import { TypedEventEmitter } from "./typed-event-emitter";
-import { EventType } from "../@types/event";
-
-export enum RoomMemberEvent {
- Membership = "RoomMember.membership",
- Name = "RoomMember.name",
- PowerLevel = "RoomMember.powerLevel",
- Typing = "RoomMember.typing",
-}
-
-export type RoomMemberEventHandlerMap = {
- /**
- * Fires whenever any room member's membership state changes.
- * @param event - The matrix event which caused this event to fire.
- * @param member - The member whose RoomMember.membership changed.
- * @param oldMembership - The previous membership state. Null if it's a new member.
- * @example
- * ```
- * matrixClient.on("RoomMember.membership", function(event, member, oldMembership){
- * var newState = member.membership;
- * });
- * ```
- */
- [RoomMemberEvent.Membership]: (event: MatrixEvent, member: RoomMember, oldMembership?: string) => void;
- /**
- * Fires whenever any room member's name changes.
- * @param event - The matrix event which caused this event to fire.
- * @param member - The member whose RoomMember.name changed.
- * @param oldName - The previous name. Null if the member didn't have a name previously.
- * @example
- * ```
- * matrixClient.on("RoomMember.name", function(event, member){
- * var newName = member.name;
- * });
- * ```
- */
- [RoomMemberEvent.Name]: (event: MatrixEvent, member: RoomMember, oldName: string | null) => void;
- /**
- * Fires whenever any room member's power level changes.
- * @param event - The matrix event which caused this event to fire.
- * @param member - The member whose RoomMember.powerLevel changed.
- * @example
- * ```
- * matrixClient.on("RoomMember.powerLevel", function(event, member){
- * var newPowerLevel = member.powerLevel;
- * var newNormPowerLevel = member.powerLevelNorm;
- * });
- * ```
- */
- [RoomMemberEvent.PowerLevel]: (event: MatrixEvent, member: RoomMember) => void;
- /**
- * Fires whenever any room member's typing state changes.
- * @param event - The matrix event which caused this event to fire.
- * @param member - The member whose RoomMember.typing changed.
- * @example
- * ```
- * matrixClient.on("RoomMember.typing", function(event, member){
- * var isTyping = member.typing;
- * });
- * ```
- */
- [RoomMemberEvent.Typing]: (event: MatrixEvent, member: RoomMember) => void;
-};
-
-export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEventHandlerMap> {
- private _isOutOfBand = false;
- private modified = -1;
- public requestedProfileInfo = false; // used by sync.ts
-
- // XXX these should be read-only
- /**
- * True if the room member is currently typing.
- */
- public typing = false;
- /**
- * The human-readable name for this room member. This will be
- * disambiguated with a suffix of " (\@user_id:matrix.org)" if another member shares the
- * same displayname.
- */
- public name: string;
- /**
- * The ambiguous displayname of this room member.
- */
- public rawDisplayName: string;
- /**
- * The power level for this room member.
- */
- public powerLevel = 0;
- /**
- * The normalised power level (0-100) for this room member.
- */
- public powerLevelNorm = 0;
- /**
- * The User object for this room member, if one exists.
- */
- public user?: User;
- /**
- * The membership state for this room member e.g. 'join'.
- */
- public membership?: string;
- /**
- * True if the member's name is disambiguated.
- */
- public disambiguate = false;
- /**
- * The events describing this RoomMember.
- */
- public events: {
- /**
- * The m.room.member event for this RoomMember.
- */
- member?: MatrixEvent;
- } = {};
-
- /**
- * Construct a new room member.
- *
- * @param roomId - The room ID of the member.
- * @param userId - The user ID of the member.
- */
- public constructor(public readonly roomId: string, public readonly userId: string) {
- super();
-
- this.name = userId;
- this.rawDisplayName = userId;
- this.updateModifiedTime();
- }
-
- /**
- * Mark the member as coming from a channel that is not sync
- */
- public markOutOfBand(): void {
- this._isOutOfBand = true;
- }
-
- /**
- * @returns does the member come from a channel that is not sync?
- * This is used to store the member seperately
- * from the sync state so it available across browser sessions.
- */
- public isOutOfBand(): boolean {
- return this._isOutOfBand;
- }
-
- /**
- * Update this room member's membership event. May fire "RoomMember.name" if
- * this event updates this member's name.
- * @param event - The `m.room.member` event
- * @param roomState - Optional. The room state to take into account
- * when calculating (e.g. for disambiguating users with the same name).
- *
- * @remarks
- * Fires {@link RoomMemberEvent.Name}
- * Fires {@link RoomMemberEvent.Membership}
- */
- public setMembershipEvent(event: MatrixEvent, roomState?: RoomState): void {
- const displayName = event.getDirectionalContent().displayname ?? "";
-
- if (event.getType() !== EventType.RoomMember) {
- return;
- }
-
- this._isOutOfBand = false;
-
- this.events.member = event;
-
- const oldMembership = this.membership;
- this.membership = event.getDirectionalContent().membership;
- if (this.membership === undefined) {
- // logging to diagnose https://github.com/vector-im/element-web/issues/20962
- // (logs event content, although only of membership events)
- logger.trace(
- `membership event with membership undefined (forwardLooking: ${event.forwardLooking})!`,
- event.getContent(),
- `prevcontent is `,
- event.getPrevContent(),
- );
- }
-
- this.disambiguate = shouldDisambiguate(this.userId, displayName, roomState);
-
- const oldName = this.name;
- this.name = calculateDisplayName(this.userId, displayName, this.disambiguate);
-
- // not quite raw: we strip direction override chars so it can safely be inserted into
- // blocks of text without breaking the text direction
- this.rawDisplayName = utils.removeDirectionOverrideChars(event.getDirectionalContent().displayname ?? "");
- if (!this.rawDisplayName || !utils.removeHiddenChars(this.rawDisplayName)) {
- this.rawDisplayName = this.userId;
- }
-
- if (oldMembership !== this.membership) {
- this.updateModifiedTime();
- this.emit(RoomMemberEvent.Membership, event, this, oldMembership);
- }
- if (oldName !== this.name) {
- this.updateModifiedTime();
- this.emit(RoomMemberEvent.Name, event, this, oldName);
- }
- }
-
- /**
- * Update this room member's power level event. May fire
- * "RoomMember.powerLevel" if this event updates this member's power levels.
- * @param powerLevelEvent - The `m.room.power_levels` event
- *
- * @remarks
- * Fires {@link RoomMemberEvent.PowerLevel}
- */
- public setPowerLevelEvent(powerLevelEvent: MatrixEvent): void {
- if (powerLevelEvent.getType() !== EventType.RoomPowerLevels || powerLevelEvent.getStateKey() !== "") {
- return;
- }
-
- const evContent = powerLevelEvent.getDirectionalContent();
-
- let maxLevel = evContent.users_default || 0;
- const users: { [userId: string]: number } = evContent.users || {};
- Object.values(users).forEach((lvl: number) => {
- maxLevel = Math.max(maxLevel, lvl);
- });
- const oldPowerLevel = this.powerLevel;
- const oldPowerLevelNorm = this.powerLevelNorm;
-
- if (users[this.userId] !== undefined && Number.isInteger(users[this.userId])) {
- this.powerLevel = users[this.userId];
- } else if (evContent.users_default !== undefined) {
- this.powerLevel = evContent.users_default;
- } else {
- this.powerLevel = 0;
- }
- this.powerLevelNorm = 0;
- if (maxLevel > 0) {
- this.powerLevelNorm = (this.powerLevel * 100) / maxLevel;
- }
-
- // emit for changes in powerLevelNorm as well (since the app will need to
- // redraw everyone's level if the max has changed)
- if (oldPowerLevel !== this.powerLevel || oldPowerLevelNorm !== this.powerLevelNorm) {
- this.updateModifiedTime();
- this.emit(RoomMemberEvent.PowerLevel, powerLevelEvent, this);
- }
- }
-
- /**
- * Update this room member's typing event. May fire "RoomMember.typing" if
- * this event changes this member's typing state.
- * @param event - The typing event
- *
- * @remarks
- * Fires {@link RoomMemberEvent.Typing}
- */
- public setTypingEvent(event: MatrixEvent): void {
- if (event.getType() !== "m.typing") {
- return;
- }
- const oldTyping = this.typing;
- this.typing = false;
- const typingList = event.getContent().user_ids;
- if (!Array.isArray(typingList)) {
- // malformed event :/ bail early. TODO: whine?
- return;
- }
- if (typingList.indexOf(this.userId) !== -1) {
- this.typing = true;
- }
- if (oldTyping !== this.typing) {
- this.updateModifiedTime();
- this.emit(RoomMemberEvent.Typing, event, this);
- }
- }
-
- /**
- * Update the last modified time to the current time.
- */
- private updateModifiedTime(): void {
- this.modified = Date.now();
- }
-
- /**
- * Get the timestamp when this RoomMember was last updated. This timestamp is
- * updated when properties on this RoomMember are updated.
- * It is updated <i>before</i> firing events.
- * @returns The timestamp
- */
- public getLastModifiedTime(): number {
- return this.modified;
- }
-
- public isKicked(): boolean {
- return (
- this.membership === "leave" &&
- this.events.member !== undefined &&
- this.events.member.getSender() !== this.events.member.getStateKey()
- );
- }
-
- /**
- * If this member was invited with the is_direct flag set, return
- * the user that invited this member
- * @returns user id of the inviter
- */
- public getDMInviter(): string | undefined {
- // when not available because that room state hasn't been loaded in,
- // we don't really know, but more likely to not be a direct chat
- if (this.events.member) {
- // TODO: persist the is_direct flag on the member as more member events
- // come in caused by displayName changes.
-
- // the is_direct flag is set on the invite member event.
- // This is copied on the prev_content section of the join member event
- // when the invite is accepted.
-
- const memberEvent = this.events.member;
- let memberContent = memberEvent.getContent();
- let inviteSender: string | undefined = memberEvent.getSender();
-
- if (memberContent.membership === "join") {
- memberContent = memberEvent.getPrevContent();
- inviteSender = memberEvent.getUnsigned().prev_sender;
- }
-
- if (memberContent.membership === "invite" && memberContent.is_direct) {
- return inviteSender;
- }
- }
- }
-
- /**
- * Get the avatar URL for a room member.
- * @param baseUrl - The base homeserver URL See
- * {@link MatrixClient#getHomeserverUrl}.
- * @param width - The desired width of the thumbnail.
- * @param height - The desired height of the thumbnail.
- * @param resizeMethod - The thumbnail resize method to use, either
- * "crop" or "scale".
- * @param allowDefault - (optional) Passing false causes this method to
- * return null if the user has no avatar image. Otherwise, a default image URL
- * will be returned. Default: true. (Deprecated)
- * @param allowDirectLinks - (optional) If true, the avatar URL will be
- * returned even if it is a direct hyperlink rather than a matrix content URL.
- * If false, any non-matrix content URLs will be ignored. Setting this option to
- * true will expose URLs that, if fetched, will leak information about the user
- * to anyone who they share a room with.
- * @returns the avatar URL or null.
- */
- public getAvatarUrl(
- baseUrl: string,
- width: number,
- height: number,
- resizeMethod: string,
- allowDefault = true,
- allowDirectLinks: boolean,
- ): string | null {
- const rawUrl = this.getMxcAvatarUrl();
-
- if (!rawUrl && !allowDefault) {
- return null;
- }
- const httpUrl = getHttpUriForMxc(baseUrl, rawUrl, width, height, resizeMethod, allowDirectLinks);
- if (httpUrl) {
- return httpUrl;
- }
- return null;
- }
-
- /**
- * get the mxc avatar url, either from a state event, or from a lazily loaded member
- * @returns the mxc avatar url
- */
- public getMxcAvatarUrl(): string | undefined {
- if (this.events.member) {
- return this.events.member.getDirectionalContent().avatar_url;
- } else if (this.user) {
- return this.user.avatarUrl;
- }
- }
-}
-
-const MXID_PATTERN = /@.+:.+/;
-const LTR_RTL_PATTERN = /[\u200E\u200F\u202A-\u202F]/;
-
-function shouldDisambiguate(selfUserId: string, displayName?: string, roomState?: RoomState): boolean {
- if (!displayName || displayName === selfUserId) return false;
-
- // First check if the displayname is something we consider truthy
- // after stripping it of zero width characters and padding spaces
- if (!utils.removeHiddenChars(displayName)) return false;
-
- if (!roomState) return false;
-
- // Next check if the name contains something that look like a mxid
- // If it does, it may be someone trying to impersonate someone else
- // Show full mxid in this case
- if (MXID_PATTERN.test(displayName)) return true;
-
- // Also show mxid if the display name contains any LTR/RTL characters as these
- // make it very difficult for us to find similar *looking* display names
- // E.g "Mark" could be cloned by writing "kraM" but in RTL.
- if (LTR_RTL_PATTERN.test(displayName)) return true;
-
- // Also show mxid if there are other people with the same or similar
- // displayname, after hidden character removal.
- const userIds = roomState.getUserIdsWithDisplayName(displayName);
- if (userIds.some((u) => u !== selfUserId)) return true;
-
- return false;
-}
-
-function calculateDisplayName(selfUserId: string, displayName: string | undefined, disambiguate: boolean): string {
- if (!displayName || displayName === selfUserId) return selfUserId;
-
- if (disambiguate) return utils.removeDirectionOverrideChars(displayName) + " (" + selfUserId + ")";
-
- // First check if the displayname is something we consider truthy
- // after stripping it of zero width characters and padding spaces
- if (!utils.removeHiddenChars(displayName)) return selfUserId;
-
- // We always strip the direction override characters (LRO and RLO).
- // These override the text direction for all subsequent characters
- // in the paragraph so if display names contained these, they'd
- // need to be wrapped in something to prevent this from leaking out
- // (which we can do in HTML but not text) or we'd need to add
- // control characters to the string to reset any overrides (eg.
- // adding PDF characters at the end). As far as we can see,
- // there should be no reason these would be necessary - rtl display
- // names should flip into the correct direction automatically based on
- // the characters, and you can still embed rtl in ltr or vice versa
- // with the embed chars or marker chars.
- return utils.removeDirectionOverrideChars(displayName);
-}