Merge pull request #6208 from matrix-org/t3chguy/ts/5
						commit
						dddc32d870
					
				|  | @ -14,18 +14,23 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| import {RoomMember} from "matrix-js-sdk/src/models/room-member"; | ||||
| import {User} from "matrix-js-sdk/src/models/user"; | ||||
| import {Room} from "matrix-js-sdk/src/models/room"; | ||||
| import { RoomMember } from "matrix-js-sdk/src/models/room-member"; | ||||
| import { User } from "matrix-js-sdk/src/models/user"; | ||||
| import { Room } from "matrix-js-sdk/src/models/room"; | ||||
| 
 | ||||
| import DMRoomMap from './utils/DMRoomMap'; | ||||
| import {mediaFromMxc} from "./customisations/Media"; | ||||
| import { mediaFromMxc } from "./customisations/Media"; | ||||
| import SettingsStore from "./settings/SettingsStore"; | ||||
| 
 | ||||
| export type ResizeMethod = "crop" | "scale"; | ||||
| 
 | ||||
| // Not to be used for BaseAvatar urls as that has similar default avatar fallback already
 | ||||
| export function avatarUrlForMember(member: RoomMember, width: number, height: number, resizeMethod: ResizeMethod) { | ||||
| export function avatarUrlForMember( | ||||
|     member: RoomMember, | ||||
|     width: number, | ||||
|     height: number, | ||||
|     resizeMethod: ResizeMethod, | ||||
| ): string { | ||||
|     let url: string; | ||||
|     if (member?.getMxcAvatarUrl()) { | ||||
|         url = mediaFromMxc(member.getMxcAvatarUrl()).getThumbnailOfSourceHttp(width, height, resizeMethod); | ||||
|  | @ -39,7 +44,12 @@ export function avatarUrlForMember(member: RoomMember, width: number, height: nu | |||
|     return url; | ||||
| } | ||||
| 
 | ||||
| export function avatarUrlForUser(user: User, width: number, height: number, resizeMethod?: ResizeMethod) { | ||||
| export function avatarUrlForUser( | ||||
|     user: Pick<User, "avatarUrl">, | ||||
|     width: number, | ||||
|     height: number, | ||||
|     resizeMethod?: ResizeMethod, | ||||
| ): string | null { | ||||
|     if (!user.avatarUrl) return null; | ||||
|     return mediaFromMxc(user.avatarUrl).getThumbnailOfSourceHttp(width, height, resizeMethod); | ||||
| } | ||||
|  |  | |||
|  | @ -468,7 +468,7 @@ function restoreEncryptionInfo(searchResultSlice = []) { | |||
|                     ev.event.curve25519Key, | ||||
|                     ev.event.ed25519Key, | ||||
|                 ); | ||||
|                 ev._forwardingCurve25519KeyChain = ev.event.forwardingCurve25519KeyChain; | ||||
|                 ev.forwardingCurve25519KeyChain = ev.event.forwardingCurve25519KeyChain; | ||||
| 
 | ||||
|                 delete ev.event.curve25519Key; | ||||
|                 delete ev.event.ed25519Key; | ||||
|  |  | |||
|  | @ -20,19 +20,19 @@ limitations under the License. | |||
| import React from 'react'; | ||||
| import { _t } from '../languageHandler'; | ||||
| import AutocompleteProvider from './AutocompleteProvider'; | ||||
| import {PillCompletion} from './Components'; | ||||
| import { PillCompletion } from './Components'; | ||||
| import * as sdk from '../index'; | ||||
| import QueryMatcher from './QueryMatcher'; | ||||
| import {sortBy} from 'lodash'; | ||||
| import {MatrixClientPeg} from '../MatrixClientPeg'; | ||||
| import { sortBy } from 'lodash'; | ||||
| import { MatrixClientPeg } from '../MatrixClientPeg'; | ||||
| 
 | ||||
| import MatrixEvent from "matrix-js-sdk/src/models/event"; | ||||
| import Room from "matrix-js-sdk/src/models/room"; | ||||
| import RoomMember from "matrix-js-sdk/src/models/room-member"; | ||||
| import RoomState from "matrix-js-sdk/src/models/room-state"; | ||||
| import EventTimeline from "matrix-js-sdk/src/models/event-timeline"; | ||||
| import {makeUserPermalink} from "../utils/permalinks/Permalinks"; | ||||
| import {ICompletion, ISelectionRange} from "./Autocompleter"; | ||||
| import { MatrixEvent } from "matrix-js-sdk/src/models/event"; | ||||
| import { Room } from "matrix-js-sdk/src/models/room"; | ||||
| import { RoomMember } from "matrix-js-sdk/src/models/room-member"; | ||||
| import { RoomState } from "matrix-js-sdk/src/models/room-state"; | ||||
| import { EventTimeline } from "matrix-js-sdk/src/models/event-timeline"; | ||||
| import { makeUserPermalink } from "../utils/permalinks/Permalinks"; | ||||
| import { ICompletion, ISelectionRange } from "./Autocompleter"; | ||||
| 
 | ||||
| const USER_REGEX = /\B@\S*/g; | ||||
| 
 | ||||
|  |  | |||
|  | @ -25,6 +25,7 @@ import React, { createRef } from 'react'; | |||
| import classNames from 'classnames'; | ||||
| import { Room } from "matrix-js-sdk/src/models/room"; | ||||
| import { MatrixEvent } from "matrix-js-sdk/src/models/event"; | ||||
| import { SearchResult } from "matrix-js-sdk/src/models/search-result"; | ||||
| import { EventSubscription } from "fbemitter"; | ||||
| 
 | ||||
| import shouldHideEvent from '../../shouldHideEvent'; | ||||
|  | @ -142,7 +143,7 @@ export interface IState { | |||
|     searchResults?: XOR<{}, { | ||||
|         count: number; | ||||
|         highlights: string[]; | ||||
|         results: MatrixEvent[]; | ||||
|         results: SearchResult[]; | ||||
|         next_batch: string; // eslint-disable-line camelcase
 | ||||
|     }>; | ||||
|     searchHighlights?: string[]; | ||||
|  |  | |||
|  | @ -525,11 +525,11 @@ class RoomStateExplorer extends React.PureComponent<IExplorerProps, IRoomStateEx | |||
| } | ||||
| 
 | ||||
| interface IAccountDataExplorerState { | ||||
|     [inputId: string]: boolean | string | any; | ||||
|     isRoomAccountData: boolean; | ||||
|     event?: MatrixEvent; | ||||
|     editing: boolean; | ||||
|     queryEventType: string; | ||||
|     [inputId: string]: boolean | string; | ||||
| } | ||||
| 
 | ||||
| class AccountDataExplorer extends React.PureComponent<IExplorerProps, IAccountDataExplorerState> { | ||||
|  |  | |||
|  | @ -153,8 +153,8 @@ class ThreepidMember extends Member { | |||
| } | ||||
| 
 | ||||
| interface IDMUserTileProps { | ||||
|     member: RoomMember; | ||||
|     onRemove(member: RoomMember): void; | ||||
|     member: Member; | ||||
|     onRemove(member: Member): void; | ||||
| } | ||||
| 
 | ||||
| class DMUserTile extends React.PureComponent<IDMUserTileProps> { | ||||
|  | @ -168,7 +168,7 @@ class DMUserTile extends React.PureComponent<IDMUserTileProps> { | |||
| 
 | ||||
|     render() { | ||||
|         const avatarSize = 20; | ||||
|         const avatar = this.props.member.isEmail | ||||
|         const avatar = (this.props.member as ThreepidMember).isEmail | ||||
|             ? <img | ||||
|                 className='mx_InviteDialog_userTile_avatar mx_InviteDialog_userTile_threepidAvatar' | ||||
|                 src={require("../../../../res/img/icon-email-pill-avatar.svg")} | ||||
|  | @ -210,9 +210,9 @@ class DMUserTile extends React.PureComponent<IDMUserTileProps> { | |||
| } | ||||
| 
 | ||||
| interface IDMRoomTileProps { | ||||
|     member: RoomMember; | ||||
|     member: Member; | ||||
|     lastActiveTs: number; | ||||
|     onToggle(member: RoomMember): void; | ||||
|     onToggle(member: Member): void; | ||||
|     highlightWord: string; | ||||
|     isSelected: boolean; | ||||
| } | ||||
|  | @ -270,7 +270,7 @@ class DMRoomTile extends React.PureComponent<IDMRoomTileProps> { | |||
|         } | ||||
| 
 | ||||
|         const avatarSize = 36; | ||||
|         const avatar = this.props.member.isEmail | ||||
|         const avatar = (this.props.member as ThreepidMember).isEmail | ||||
|             ? <img | ||||
|                 src={require("../../../../res/img/icon-email-pill-avatar.svg")} | ||||
|                 width={avatarSize} height={avatarSize} /> | ||||
|  | @ -298,7 +298,7 @@ class DMRoomTile extends React.PureComponent<IDMRoomTileProps> { | |||
|             </span> | ||||
|         ); | ||||
| 
 | ||||
|         const caption = this.props.member.isEmail | ||||
|         const caption = (this.props.member as ThreepidMember).isEmail | ||||
|             ? _t("Invite by email") | ||||
|             : this.highlightName(this.props.member.userId); | ||||
| 
 | ||||
|  | @ -334,7 +334,7 @@ interface IInviteDialogProps { | |||
| } | ||||
| 
 | ||||
| interface IInviteDialogState { | ||||
|     targets: RoomMember[]; // array of Member objects (see interface above)
 | ||||
|     targets: Member[]; // array of Member objects (see interface above)
 | ||||
|     filterText: string; | ||||
|     recents: { user: Member, userId: string }[]; | ||||
|     numRecentsShown: number; | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ import { _t } from '../../../languageHandler'; | |||
| import { formatCommaSeparatedList } from '../../../utils/FormattingUtils'; | ||||
| import { isValid3pidInvite } from "../../../RoomInvite"; | ||||
| import EventListSummary from "./EventListSummary"; | ||||
| import {replaceableComponent} from "../../../utils/replaceableComponent"; | ||||
| import { replaceableComponent } from "../../../utils/replaceableComponent"; | ||||
| 
 | ||||
| interface IProps { | ||||
|     // An array of member events to summarise
 | ||||
|  | @ -303,7 +303,7 @@ export default class MemberEventListSummary extends React.Component<IProps> { | |||
|         return res; | ||||
|     } | ||||
| 
 | ||||
|     private static getTransitionSequence(events: MatrixEvent[]) { | ||||
|     private static getTransitionSequence(events: IUserEvents[]) { | ||||
|         return events.map(MemberEventListSummary.getTransition); | ||||
|     } | ||||
| 
 | ||||
|  | @ -315,7 +315,7 @@ export default class MemberEventListSummary extends React.Component<IProps> { | |||
|      * @returns {string?} the transition type given to this event. This defaults to `null` | ||||
|      * if a transition is not recognised. | ||||
|      */ | ||||
|     private static getTransition(e: MatrixEvent): TransitionType { | ||||
|     private static getTransition(e: IUserEvents): TransitionType { | ||||
|         if (e.mxEvent.getType() === 'm.room.third_party_invite') { | ||||
|             // Handle 3pid invites the same as invites so they get bundled together
 | ||||
|             if (!isValid3pidInvite(e.mxEvent)) { | ||||
|  |  | |||
|  | @ -24,6 +24,7 @@ import {_t} from "../../../languageHandler"; | |||
| import {mediaFromContent} from "../../../customisations/Media"; | ||||
| import {decryptFile} from "../../../utils/DecryptFile"; | ||||
| import RecordingPlayback from "../voice_messages/RecordingPlayback"; | ||||
| import {IMediaEventContent} from "../../../customisations/models/IMediaEventContent"; | ||||
| 
 | ||||
| interface IProps { | ||||
|     mxEvent: MatrixEvent; | ||||
|  | @ -45,7 +46,7 @@ export default class MVoiceMessageBody extends React.PureComponent<IProps, IStat | |||
| 
 | ||||
|     public async componentDidMount() { | ||||
|         let buffer: ArrayBuffer; | ||||
|         const content = this.props.mxEvent.getContent(); | ||||
|         const content: IMediaEventContent = this.props.mxEvent.getContent(); | ||||
|         const media = mediaFromContent(content); | ||||
|         if (media.isEncrypted) { | ||||
|             try { | ||||
|  |  | |||
|  | @ -17,10 +17,10 @@ | |||
| import React from 'react'; | ||||
| import Flair from '../elements/Flair.js'; | ||||
| import FlairStore from '../../../stores/FlairStore'; | ||||
| import {getUserNameColorClass} from '../../../utils/FormattingUtils'; | ||||
| import { getUserNameColorClass } from '../../../utils/FormattingUtils'; | ||||
| import MatrixClientContext from "../../../contexts/MatrixClientContext"; | ||||
| import {replaceableComponent} from "../../../utils/replaceableComponent"; | ||||
| import MatrixEvent from "matrix-js-sdk/src/models/event"; | ||||
| import { replaceableComponent } from "../../../utils/replaceableComponent"; | ||||
| import { MatrixEvent } from "matrix-js-sdk/src/models/event"; | ||||
| 
 | ||||
| interface IProps { | ||||
|     mxEvent: MatrixEvent; | ||||
|  |  | |||
|  | @ -17,8 +17,9 @@ limitations under the License. | |||
| import React from "react"; | ||||
| 
 | ||||
| import * as sdk from "../../../index"; | ||||
| import {_t} from "../../../languageHandler"; | ||||
| import {RoomMember} from "matrix-js-sdk/src/models/room-member"; | ||||
| import { _t } from "../../../languageHandler"; | ||||
| import { RoomMember } from "matrix-js-sdk/src/models/room-member"; | ||||
| import { User } from "matrix-js-sdk/src/models/user"; | ||||
| 
 | ||||
| export const PendingActionSpinner = ({text}) => { | ||||
|     const Spinner = sdk.getComponent('elements.Spinner'); | ||||
|  | @ -31,7 +32,7 @@ export const PendingActionSpinner = ({text}) => { | |||
| interface IProps { | ||||
|     waitingForOtherParty: boolean; | ||||
|     waitingForNetwork: boolean; | ||||
|     member: RoomMember; | ||||
|     member: RoomMember | User; | ||||
|     onStartVerification: () => Promise<void>; | ||||
|     isRoomEncrypted: boolean; | ||||
|     inDialog: boolean; | ||||
|  | @ -55,7 +56,7 @@ const EncryptionInfo: React.FC<IProps> = ({ | |||
|                 text = _t("Accept on your other login…"); | ||||
|             } else { | ||||
|                 text = _t("Waiting for %(displayName)s to accept…", { | ||||
|                     displayName: member.displayName || member.name || member.userId, | ||||
|                     displayName: (member as User).displayName || (member as RoomMember).name || member.userId, | ||||
|                 }); | ||||
|             } | ||||
|         } else { | ||||
|  |  | |||
|  | @ -147,7 +147,7 @@ async function openDMForUser(matrixClient: MatrixClient, userId: string) { | |||
| 
 | ||||
| type SetUpdating = (updating: boolean) => void; | ||||
| 
 | ||||
| function useHasCrossSigningKeys(cli: MatrixClient, member: RoomMember, canVerify: boolean, setUpdating: SetUpdating) { | ||||
| function useHasCrossSigningKeys(cli: MatrixClient, member: User, canVerify: boolean, setUpdating: SetUpdating) { | ||||
|     return useAsyncMemo(async () => { | ||||
|         if (!canVerify) { | ||||
|             return undefined; | ||||
|  | @ -972,7 +972,7 @@ interface IRoomPermissions { | |||
|     canInvite: boolean; | ||||
| } | ||||
| 
 | ||||
| function useRoomPermissions(cli: MatrixClient, room: Room, user: User): IRoomPermissions { | ||||
| function useRoomPermissions(cli: MatrixClient, room: Room, user: RoomMember): IRoomPermissions { | ||||
|     const [roomPermissions, setRoomPermissions] = useState<IRoomPermissions>({ | ||||
|         // modifyLevelMax is the max PL we can set this user to, typically min(their PL, our PL) && canSetPL
 | ||||
|         modifyLevelMax: -1, | ||||
|  | @ -1029,7 +1029,7 @@ function useRoomPermissions(cli: MatrixClient, room: Room, user: User): IRoomPer | |||
| } | ||||
| 
 | ||||
| const PowerLevelSection: React.FC<{ | ||||
|     user: User; | ||||
|     user: RoomMember; | ||||
|     room: Room; | ||||
|     roomPermissions: IRoomPermissions; | ||||
|     powerLevels: IPowerLevelsContent; | ||||
|  | @ -1038,7 +1038,7 @@ const PowerLevelSection: React.FC<{ | |||
|         return (<PowerLevelEditor user={user} room={room} roomPermissions={roomPermissions} />); | ||||
|     } else { | ||||
|         const powerLevelUsersDefault = powerLevels.users_default || 0; | ||||
|         const powerLevel = parseInt(user.powerLevel, 10); | ||||
|         const powerLevel = user.powerLevel; | ||||
|         const role = textualPowerLevel(powerLevel, powerLevelUsersDefault); | ||||
|         return ( | ||||
|             <div className="mx_UserInfo_profileField"> | ||||
|  | @ -1049,13 +1049,13 @@ const PowerLevelSection: React.FC<{ | |||
| }; | ||||
| 
 | ||||
| const PowerLevelEditor: React.FC<{ | ||||
|     user: User; | ||||
|     user: RoomMember; | ||||
|     room: Room; | ||||
|     roomPermissions: IRoomPermissions; | ||||
| }> = ({user, room, roomPermissions}) => { | ||||
|     const cli = useContext(MatrixClientContext); | ||||
| 
 | ||||
|     const [selectedPowerLevel, setSelectedPowerLevel] = useState(parseInt(user.powerLevel, 10)); | ||||
|     const [selectedPowerLevel, setSelectedPowerLevel] = useState(user.powerLevel); | ||||
|     const onPowerChange = useCallback(async (powerLevelStr: string) => { | ||||
|         const powerLevel = parseInt(powerLevelStr, 10); | ||||
|         setSelectedPowerLevel(powerLevel); | ||||
|  | @ -1232,7 +1232,7 @@ const BasicUserInfo: React.FC<{ | |||
|         setPendingUpdateCount(pendingUpdateCount - 1); | ||||
|     }, [pendingUpdateCount]); | ||||
| 
 | ||||
|     const roomPermissions = useRoomPermissions(cli, room, member); | ||||
|     const roomPermissions = useRoomPermissions(cli, room, member as RoomMember); | ||||
| 
 | ||||
|     const onSynapseDeactivate = useCallback(async () => { | ||||
|         const {finished} = Modal.createTrackedDialog('Synapse User Deactivation', '', QuestionDialog, { | ||||
|  | @ -1276,12 +1276,26 @@ const BasicUserInfo: React.FC<{ | |||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     let memberDetails; | ||||
|     let adminToolsContainer; | ||||
|     if (room && member.roomId) { | ||||
|     if (room && (member as RoomMember).roomId) { | ||||
|         // hide the Roles section for DMs as it doesn't make sense there
 | ||||
|         if (!DMRoomMap.shared().getUserIdForRoomId((member as RoomMember).roomId)) { | ||||
|             memberDetails = <div className="mx_UserInfo_container"> | ||||
|                 <h3>{ _t("Role") }</h3> | ||||
|                 <PowerLevelSection | ||||
|                     powerLevels={powerLevels} | ||||
|                     user={member as RoomMember} | ||||
|                     room={room} | ||||
|                     roomPermissions={roomPermissions} | ||||
|                 /> | ||||
|             </div>; | ||||
|         } | ||||
| 
 | ||||
|         adminToolsContainer = ( | ||||
|             <RoomAdminToolsContainer | ||||
|                 powerLevels={powerLevels} | ||||
|                 member={member} | ||||
|                 member={member as RoomMember} | ||||
|                 room={room} | ||||
|                 startUpdating={startUpdating} | ||||
|                 stopUpdating={stopUpdating}> | ||||
|  | @ -1310,20 +1324,6 @@ const BasicUserInfo: React.FC<{ | |||
|         spinner = <Spinner />; | ||||
|     } | ||||
| 
 | ||||
|     let memberDetails; | ||||
|     // hide the Roles section for DMs as it doesn't make sense there
 | ||||
|     if (room && member.roomId && !DMRoomMap.shared().getUserIdForRoomId(member.roomId)) { | ||||
|         memberDetails = <div className="mx_UserInfo_container"> | ||||
|             <h3>{ _t("Role") }</h3> | ||||
|             <PowerLevelSection | ||||
|                 powerLevels={powerLevels} | ||||
|                 user={member} | ||||
|                 room={room} | ||||
|                 roomPermissions={roomPermissions} | ||||
|             /> | ||||
|         </div>; | ||||
|     } | ||||
| 
 | ||||
|     // only display the devices list if our client supports E2E
 | ||||
|     const cryptoEnabled = cli.isCryptoEnabled(); | ||||
| 
 | ||||
|  | @ -1350,8 +1350,7 @@ const BasicUserInfo: React.FC<{ | |||
|     const setUpdating = (updating) => { | ||||
|         setPendingUpdateCount(count => count + (updating ? 1 : -1)); | ||||
|     }; | ||||
|     const hasCrossSigningKeys = | ||||
|         useHasCrossSigningKeys(cli, member, canVerify, setUpdating ); | ||||
|     const hasCrossSigningKeys = useHasCrossSigningKeys(cli, member as User, canVerify, setUpdating); | ||||
| 
 | ||||
|     const showDeviceListSpinner = devices === undefined; | ||||
|     if (canVerify) { | ||||
|  | @ -1360,9 +1359,9 @@ const BasicUserInfo: React.FC<{ | |||
|             verifyButton = ( | ||||
|                 <AccessibleButton className="mx_UserInfo_field mx_UserInfo_verifyButton" onClick={() => { | ||||
|                     if (hasCrossSigningKeys) { | ||||
|                         verifyUser(member); | ||||
|                         verifyUser(member as User); | ||||
|                     } else { | ||||
|                         legacyVerifyUser(member); | ||||
|                         legacyVerifyUser(member as User); | ||||
|                     } | ||||
|                 }}> | ||||
|                     {_t("Verify")} | ||||
|  | @ -1410,7 +1409,7 @@ const BasicUserInfo: React.FC<{ | |||
|         <UserOptionsSection | ||||
|             canInvite={roomPermissions.canInvite} | ||||
|             isIgnored={isIgnored} | ||||
|             member={member} | ||||
|             member={member as RoomMember} | ||||
|             isSpace={SettingsStore.getValue("feature_spaces") && room?.isSpaceRoom()} | ||||
|         /> | ||||
| 
 | ||||
|  | @ -1429,13 +1428,15 @@ const UserInfoHeader: React.FC<{ | |||
|     const cli = useContext(MatrixClientContext); | ||||
| 
 | ||||
|     const onMemberAvatarClick = useCallback(() => { | ||||
|         const avatarUrl = member.getMxcAvatarUrl ? member.getMxcAvatarUrl() : member.avatarUrl; | ||||
|         const avatarUrl = (member as RoomMember).getMxcAvatarUrl | ||||
|             ? (member as RoomMember).getMxcAvatarUrl() | ||||
|             : (member as User).avatarUrl; | ||||
|         if (!avatarUrl) return; | ||||
| 
 | ||||
|         const httpUrl = mediaFromMxc(avatarUrl).srcHttp; | ||||
|         const params = { | ||||
|             src: httpUrl, | ||||
|             name: member.name, | ||||
|             name: (member as RoomMember).name || (member as User).displayName, | ||||
|         }; | ||||
| 
 | ||||
|         Modal.createDialog(ImageView, params, "mx_Dialog_lightbox", null, true); | ||||
|  | @ -1447,13 +1448,13 @@ const UserInfoHeader: React.FC<{ | |||
|                 <div> | ||||
|                     <MemberAvatar | ||||
|                         key={member.userId} // to instantly blank the avatar when UserInfo changes members
 | ||||
|                         member={member} | ||||
|                         member={member as RoomMember} | ||||
|                         width={2 * 0.3 * UIStore.instance.windowHeight} // 2x@30vh
 | ||||
|                         height={2 * 0.3 * UIStore.instance.windowHeight} // 2x@30vh
 | ||||
|                         resizeMethod="scale" | ||||
|                         fallbackUserId={member.userId} | ||||
|                         onClick={onMemberAvatarClick} | ||||
|                         urls={member.avatarUrl ? [member.avatarUrl] : undefined} /> | ||||
|                         urls={(member as User).avatarUrl ? [(member as User).avatarUrl] : undefined} /> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|  | @ -1470,7 +1471,11 @@ const UserInfoHeader: React.FC<{ | |||
|         presenceCurrentlyActive = member.user.currentlyActive; | ||||
| 
 | ||||
|         if (SettingsStore.getValue("feature_custom_status")) { | ||||
|             statusMessage = member.user._unstable_statusMessage; | ||||
|             if ((member as RoomMember).user) { | ||||
|                 statusMessage = member.user.unstable_statusMessage; | ||||
|             } else { | ||||
|                 statusMessage = (member as unknown as User).unstable_statusMessage; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -1501,7 +1506,7 @@ const UserInfoHeader: React.FC<{ | |||
|         e2eIcon = <E2EIcon size={18} status={e2eStatus} isUser={true} />; | ||||
|     } | ||||
| 
 | ||||
|     const displayName = member.rawDisplayName || member.displayname; | ||||
|     const displayName = (member as RoomMember).rawDisplayName || (member as GroupMember).displayname; | ||||
|     return <React.Fragment> | ||||
|         { avatarElement } | ||||
| 
 | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ import {verificationMethods} from 'matrix-js-sdk/src/crypto'; | |||
| import {SCAN_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode"; | ||||
| import {VerificationRequest} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; | ||||
| import {RoomMember} from "matrix-js-sdk/src/models/room-member"; | ||||
| import { User } from "matrix-js-sdk/src/models/user"; | ||||
| import {ReciprocateQRCode} from "matrix-js-sdk/src/crypto/verification/QRCode"; | ||||
| import {SAS} from "matrix-js-sdk/src/crypto/verification/SAS"; | ||||
| 
 | ||||
|  | @ -51,7 +52,7 @@ enum VerificationPhase { | |||
| interface IProps { | ||||
|     layout: string; | ||||
|     request: VerificationRequest; | ||||
|     member: RoomMember; | ||||
|     member: RoomMember | User; | ||||
|     phase: VerificationPhase; | ||||
|     onClose: () => void; | ||||
|     isRoomEncrypted: boolean; | ||||
|  | @ -134,7 +135,7 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat | |||
|             qrBlock = <div className="mx_UserInfo_container"> | ||||
|                 <h3>{_t("Verify by scanning")}</h3> | ||||
|                 <p>{_t("Ask %(displayName)s to scan your code:", { | ||||
|                     displayName: member.displayName || member.name || member.userId, | ||||
|                     displayName: (member as User).displayName || (member as RoomMember).name || member.userId, | ||||
|                 })}</p> | ||||
| 
 | ||||
|                 <div className="mx_VerificationPanel_qrCode"> | ||||
|  | @ -205,7 +206,7 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat | |||
|         const description = request.isSelfVerification ? | ||||
|             _t("Almost there! Is your other session showing the same shield?") : | ||||
|             _t("Almost there! Is %(displayName)s showing the same shield?", { | ||||
|                 displayName: member.displayName || member.name || member.userId, | ||||
|                 displayName: (member as User).displayName || (member as RoomMember).name || member.userId, | ||||
|             }); | ||||
|         let body: JSX.Element; | ||||
|         if (this.state.reciprocateQREvent) { | ||||
|  | @ -264,7 +265,7 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat | |||
|             } | ||||
|         } else { | ||||
|             description = _t("You've successfully verified %(displayName)s!", { | ||||
|                 displayName: member.displayName || member.name || member.userId, | ||||
|                 displayName: (member as User).displayName || (member as RoomMember).name || member.userId, | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|  | @ -302,7 +303,7 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat | |||
|                 text = _t("You cancelled verification on your other session."); | ||||
|             } else { | ||||
|                 text = _t("%(displayName)s cancelled verification.", { | ||||
|                     displayName: member.displayName || member.name || member.userId, | ||||
|                     displayName: (member as User).displayName || (member as RoomMember).name || member.userId, | ||||
|                 }); | ||||
|             } | ||||
|             text = `${text} ${startAgainInstruction}`; | ||||
|  | @ -325,7 +326,7 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat | |||
|     public render() { | ||||
|         const {member, phase, request} = this.props; | ||||
| 
 | ||||
|         const displayName = member.displayName || member.name || member.userId; | ||||
|         const displayName = (member as User).displayName || (member as RoomMember).name || member.userId; | ||||
| 
 | ||||
|         switch (phase) { | ||||
|             case PHASE_READY: | ||||
|  |  | |||
|  | @ -378,7 +378,7 @@ export default class EventTile extends React.Component<IProps, IState> { | |||
|             EventType.RoomMessage, | ||||
|             EventType.RoomMessageEncrypted, | ||||
|         ]; | ||||
|         if (!simpleSendableEvents.includes(this.props.mxEvent.getType())) return false; | ||||
|         if (!simpleSendableEvents.includes(this.props.mxEvent.getType() as EventType)) return false; | ||||
| 
 | ||||
|         // Default case
 | ||||
|         return true; | ||||
|  |  | |||
|  | @ -44,14 +44,11 @@ export default class BridgeSettingsTab extends React.Component<IProps> { | |||
|         return <BridgeTile key={event.getId()} room={room} ev={event} />; | ||||
|     } | ||||
| 
 | ||||
|     static getBridgeStateEvents(roomId: string) { | ||||
|     static getBridgeStateEvents(roomId: string): MatrixEvent[] { | ||||
|         const client = MatrixClientPeg.get(); | ||||
|         const roomState = client.getRoom(roomId).currentState; | ||||
| 
 | ||||
|         return BRIDGE_EVENT_TYPES.map(typeName => { | ||||
|             const events = roomState.events.get(typeName); | ||||
|             return events ? Array.from(events.values()) : []; | ||||
|         }).flat(1); | ||||
|         return BRIDGE_EVENT_TYPES.map(typeName => roomState.getStateEvents(typeName)).flat(1); | ||||
|     } | ||||
| 
 | ||||
|     render() { | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ limitations under the License. | |||
| import { VerificationRequest } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; | ||||
| import { Room } from "matrix-js-sdk/src/models/room"; | ||||
| import { RoomMember } from "matrix-js-sdk/src/models/room-member"; | ||||
| import { User } from "matrix-js-sdk/src/models/user"; | ||||
| import { RightPanelPhases } from "../../stores/RightPanelStorePhases"; | ||||
| import { ActionPayload } from "../payloads"; | ||||
| import { Action } from "../actions"; | ||||
|  | @ -29,7 +30,7 @@ export interface SetRightPanelPhasePayload extends ActionPayload { | |||
| } | ||||
| 
 | ||||
| export interface SetRightPanelPhaseRefireParams { | ||||
|     member?: RoomMember; | ||||
|     member?: RoomMember | User; | ||||
|     verificationRequest?: VerificationRequest; | ||||
|     groupId?: string; | ||||
|     groupRoomId?: string; | ||||
|  |  | |||
|  | @ -21,11 +21,11 @@ import {Room} from "matrix-js-sdk/src/models/room"; | |||
| 
 | ||||
| import {useEventEmitter} from "./useEventEmitter"; | ||||
| 
 | ||||
| const tryGetContent = (ev?: MatrixEvent) => ev ? ev.getContent() : undefined; | ||||
| const tryGetContent = <T extends {}>(ev?: MatrixEvent) => ev ? ev.getContent<T>() : undefined; | ||||
| 
 | ||||
| // Hook to simplify listening to Matrix account data
 | ||||
| export const useAccountData = <T extends {}>(cli: MatrixClient, eventType: string) => { | ||||
|     const [value, setValue] = useState<T>(() => tryGetContent(cli.getAccountData(eventType))); | ||||
|     const [value, setValue] = useState<T>(() => tryGetContent<T>(cli.getAccountData(eventType))); | ||||
| 
 | ||||
|     const handler = useCallback((event) => { | ||||
|         if (event.getType() !== eventType) return; | ||||
|  | @ -38,7 +38,7 @@ export const useAccountData = <T extends {}>(cli: MatrixClient, eventType: strin | |||
| 
 | ||||
| // Hook to simplify listening to Matrix room account data
 | ||||
| export const useRoomAccountData = <T extends {}>(room: Room, eventType: string) => { | ||||
|     const [value, setValue] = useState<T>(() => tryGetContent(room.getAccountData(eventType))); | ||||
|     const [value, setValue] = useState<T>(() => tryGetContent<T>(room.getAccountData(eventType))); | ||||
| 
 | ||||
|     const handler = useCallback((event) => { | ||||
|         if (event.getType() !== eventType) return; | ||||
|  |  | |||
|  | @ -300,7 +300,7 @@ export default class EventIndex extends EventEmitter { | |||
|     } | ||||
| 
 | ||||
|     private eventToJson(ev: MatrixEvent) { | ||||
|         const jsonEvent = ev.toJSON(); | ||||
|         const jsonEvent: any = ev.toJSON(); | ||||
|         const e = ev.isEncrypted() ? jsonEvent.decrypted : jsonEvent; | ||||
| 
 | ||||
|         if (ev.isEncrypted()) { | ||||
|  |  | |||
|  | @ -16,8 +16,8 @@ limitations under the License. | |||
| 
 | ||||
| import EventEmitter from 'events'; | ||||
| import { IWidget } from 'matrix-widget-api'; | ||||
| import MatrixEvent from "matrix-js-sdk/src/models/event"; | ||||
| import {WidgetType} from "../widgets/WidgetType"; | ||||
| import { MatrixEvent } from "matrix-js-sdk/src/models/event"; | ||||
| import { WidgetType } from "../widgets/WidgetType"; | ||||
| 
 | ||||
| /** | ||||
|  * Acts as a place to get & set widget state, storing local echo state and | ||||
|  |  | |||
|  | @ -51,7 +51,7 @@ import ThemeWatcher from "../../settings/watchers/ThemeWatcher"; | |||
| import {getCustomTheme} from "../../theme"; | ||||
| import CountlyAnalytics from "../../CountlyAnalytics"; | ||||
| import { ElementWidgetCapabilities } from "./ElementWidgetCapabilities"; | ||||
| import { MatrixEvent } from "matrix-js-sdk/src/models/event"; | ||||
| import { MatrixEvent, IEvent } from "matrix-js-sdk/src/models/event"; | ||||
| import { ELEMENT_CLIENT_ID } from "../../identifiers"; | ||||
| import { getUserLanguage } from "../../languageHandler"; | ||||
| 
 | ||||
|  | @ -415,7 +415,7 @@ export class StopGapWidget extends EventEmitter { | |||
|     private feedEvent(ev: MatrixEvent) { | ||||
|         if (!this.messaging) return; | ||||
| 
 | ||||
|         const raw = ev.event; | ||||
|         const raw = ev.event as IEvent; | ||||
|         this.messaging.feedEvent(raw).catch(e => { | ||||
|             console.error("Error sending event to widget: ", e); | ||||
|         }); | ||||
|  |  | |||
|  | @ -145,7 +145,7 @@ export class StopGapWidgetDriver extends WidgetDriver { | |||
|         return {roomId, eventId: r.event_id}; | ||||
|     } | ||||
| 
 | ||||
|     public async readRoomEvents(eventType: string, msgtype: string | undefined, limit: number): Promise<MatrixEvent[]> { | ||||
|     public async readRoomEvents(eventType: string, msgtype: string | undefined, limit: number): Promise<object[]> { | ||||
|         limit = limit > 0 ? Math.min(limit, 25) : 25; // arbitrary choice
 | ||||
| 
 | ||||
|         const client = MatrixClientPeg.get(); | ||||
|  | @ -167,9 +167,7 @@ export class StopGapWidgetDriver extends WidgetDriver { | |||
|         return results.map(e => e.event); | ||||
|     } | ||||
| 
 | ||||
|     public async readStateEvents( | ||||
|         eventType: string, stateKey: string | undefined, limit: number, | ||||
|     ): Promise<MatrixEvent[]> { | ||||
|     public async readStateEvents(eventType: string, stateKey: string | undefined, limit: number): Promise<object[]> { | ||||
|         limit = limit > 0 ? Math.min(limit, 100) : 100; // arbitrary choice
 | ||||
| 
 | ||||
|         const client = MatrixClientPeg.get(); | ||||
|  | @ -178,7 +176,7 @@ export class StopGapWidgetDriver extends WidgetDriver { | |||
|         if (!client || !roomId || !room) throw new Error("Not in a room or not attached to a client"); | ||||
| 
 | ||||
|         const results: MatrixEvent[] = []; | ||||
|         const state = room.currentState.events.get(eventType); | ||||
|         const state: Map<string, MatrixEvent> = room.currentState.events.get(eventType); | ||||
|         if (state) { | ||||
|             if (stateKey === "" || !!stateKey) { | ||||
|                 const forKey = state.get(stateKey); | ||||
|  |  | |||
|  | @ -14,11 +14,11 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| import {MatrixClientPeg} from '../MatrixClientPeg'; | ||||
| import {uniq} from "lodash"; | ||||
| import {Room} from "matrix-js-sdk/src/models/room"; | ||||
| import {Event} from "matrix-js-sdk/src/models/event"; | ||||
| import {MatrixClient} from "matrix-js-sdk/src/client"; | ||||
| import { uniq } from "lodash"; | ||||
| import { Room } from "matrix-js-sdk/src/models/room"; | ||||
| import { MatrixClient } from "matrix-js-sdk/src/client"; | ||||
| 
 | ||||
| import { MatrixClientPeg } from '../MatrixClientPeg'; | ||||
| 
 | ||||
| /** | ||||
|  * Class that takes a Matrix Client and flips the m.direct map | ||||
|  | @ -30,15 +30,13 @@ import {MatrixClient} from "matrix-js-sdk/src/client"; | |||
| export default class DMRoomMap { | ||||
|     private static sharedInstance: DMRoomMap; | ||||
| 
 | ||||
|     private matrixClient: MatrixClient; | ||||
|     // TODO: convert these to maps
 | ||||
|     private roomToUser: {[key: string]: string} = null; | ||||
|     private userToRooms: {[key: string]: string[]} = null; | ||||
|     private hasSentOutPatchDirectAccountDataPatch: boolean; | ||||
|     private mDirectEvent: Event; | ||||
|     private mDirectEvent: object; | ||||
| 
 | ||||
|     constructor(matrixClient) { | ||||
|         this.matrixClient = matrixClient; | ||||
|     constructor(private readonly matrixClient: MatrixClient) { | ||||
|         // see onAccountData
 | ||||
|         this.hasSentOutPatchDirectAccountDataPatch = false; | ||||
| 
 | ||||
|  |  | |||
|  | @ -392,7 +392,7 @@ export default class WidgetUtils { | |||
|         } | ||||
|         const widgets = client.getAccountData('m.widgets'); | ||||
|         if (!widgets) return; | ||||
|         const userWidgets: IWidgetEvent[] = widgets.getContent() || {}; | ||||
|         const userWidgets: Record<string, IWidgetEvent> = widgets.getContent() || {}; | ||||
|         Object.entries(userWidgets).forEach(([key, widget]) => { | ||||
|             if (widget.content && widget.content.type === "m.integration_manager") { | ||||
|                 delete userWidgets[key]; | ||||
|  |  | |||
|  | @ -30,9 +30,7 @@ function createFailedDecryptionEvent() { | |||
|     const event = new MatrixEvent({ | ||||
|         event_id: "event-id-" + Math.random().toString(16).slice(2), | ||||
|     }); | ||||
|     event._setClearData( | ||||
|         event._badEncryptedMessage(":("), | ||||
|     ); | ||||
|     event.setClearData(event.badEncryptedMessage(":(")); | ||||
|     return event; | ||||
| } | ||||
| 
 | ||||
|  | @ -67,7 +65,7 @@ describe('DecryptionFailureTracker', function() { | |||
|         tracker.eventDecrypted(decryptedEvent, err); | ||||
| 
 | ||||
|         // Indicate successful decryption: clear data can be anything where the msgtype is not m.bad.encrypted
 | ||||
|         decryptedEvent._setClearData({}); | ||||
|         decryptedEvent.setClearData({}); | ||||
|         tracker.eventDecrypted(decryptedEvent, null); | ||||
| 
 | ||||
|         // Pretend "now" is Infinity
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Michael Telatynski
						Michael Telatynski