From 9cce5ef10f116a13167a04ae42954adc8569c1f3 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 18 Jun 2021 15:31:12 +0100 Subject: [PATCH 01/10] Consolidate types with js-sdk changes --- src/Avatar.ts | 3 +-- src/components/structures/RoomView.tsx | 8 ++------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/Avatar.ts b/src/Avatar.ts index 8ea0b0c9fa..4c4bd1c265 100644 --- a/src/Avatar.ts +++ b/src/Avatar.ts @@ -17,13 +17,12 @@ 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 { ResizeMethod } from "matrix-js-sdk/src/@types/partials"; import DMRoomMap from './utils/DMRoomMap'; 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, diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 1e3adcb518..d9f2d5231b 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -23,7 +23,7 @@ limitations under the License. import React, { createRef } from 'react'; import classNames from 'classnames'; -import { Room } from "matrix-js-sdk/src/models/room"; +import { IRecommendedVersion, 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"; @@ -172,11 +172,7 @@ export interface IState { // We load this later by asking the js-sdk to suggest a version for us. // This object is the result of Room#getRecommendedVersion() - upgradeRecommendation?: { - version: string; - needsUpgrade: boolean; - urgent: boolean; - }; + upgradeRecommendation?: IRecommendedVersion; canReact: boolean; canReply: boolean; layout: Layout; From 058cbbbd0c6c2534e390d000844ccde74683f690 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 18 Jun 2021 16:13:55 +0100 Subject: [PATCH 02/10] Fix imports --- src/autocomplete/Autocompleter.ts | 7 ++-- src/autocomplete/NotifProvider.tsx | 3 +- src/autocomplete/RoomProvider.tsx | 12 +++--- src/components/views/avatars/BaseAvatar.tsx | 9 +++-- src/components/views/avatars/GroupAvatar.tsx | 7 ++-- src/components/views/avatars/MemberAvatar.tsx | 10 ++--- src/components/views/avatars/RoomAvatar.tsx | 12 +++--- src/components/views/elements/RoomName.tsx | 8 ++-- .../views/rooms/WhoIsTypingTile.tsx | 2 +- src/customisations/Media.ts | 9 +++-- src/utils/ShieldUtils.ts | 39 ++++++++++--------- 11 files changed, 62 insertions(+), 56 deletions(-) diff --git a/src/autocomplete/Autocompleter.ts b/src/autocomplete/Autocompleter.ts index 5409825f45..ea8eddbb8d 100644 --- a/src/autocomplete/Autocompleter.ts +++ b/src/autocomplete/Autocompleter.ts @@ -15,8 +15,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {ReactElement} from 'react'; -import Room from 'matrix-js-sdk/src/models/room'; +import { ReactElement } from 'react'; +import { Room } from 'matrix-js-sdk/src/models/room'; + import CommandProvider from './CommandProvider'; import CommunityProvider from './CommunityProvider'; import DuckDuckGoProvider from './DuckDuckGoProvider'; @@ -24,7 +25,7 @@ import RoomProvider from './RoomProvider'; import UserProvider from './UserProvider'; import EmojiProvider from './EmojiProvider'; import NotifProvider from './NotifProvider'; -import {timeout} from "../utils/promise"; +import { timeout } from "../utils/promise"; import AutocompleteProvider, {ICommand} from "./AutocompleteProvider"; import SettingsStore from "../settings/SettingsStore"; import SpaceProvider from "./SpaceProvider"; diff --git a/src/autocomplete/NotifProvider.tsx b/src/autocomplete/NotifProvider.tsx index 0bc7ead097..827f4aa885 100644 --- a/src/autocomplete/NotifProvider.tsx +++ b/src/autocomplete/NotifProvider.tsx @@ -15,7 +15,8 @@ limitations under the License. */ import React from 'react'; -import Room from "matrix-js-sdk/src/models/room"; +import { Room } from "matrix-js-sdk/src/models/room"; + import AutocompleteProvider from './AutocompleteProvider'; import { _t } from '../languageHandler'; import {MatrixClientPeg} from '../MatrixClientPeg'; diff --git a/src/autocomplete/RoomProvider.tsx b/src/autocomplete/RoomProvider.tsx index ad55b19101..a82a757a78 100644 --- a/src/autocomplete/RoomProvider.tsx +++ b/src/autocomplete/RoomProvider.tsx @@ -17,16 +17,16 @@ limitations under the License. */ import React from "react"; -import {uniqBy, sortBy} from "lodash"; -import Room from "matrix-js-sdk/src/models/room"; +import { uniqBy, sortBy } from "lodash"; +import { Room } from "matrix-js-sdk/src/models/room"; import { _t } from '../languageHandler'; import AutocompleteProvider from './AutocompleteProvider'; -import {MatrixClientPeg} from '../MatrixClientPeg'; +import { MatrixClientPeg } from '../MatrixClientPeg'; import QueryMatcher from './QueryMatcher'; -import {PillCompletion} from './Components'; -import {makeRoomPermalink} from "../utils/permalinks/Permalinks"; -import {ICompletion, ISelectionRange} from "./Autocompleter"; +import { PillCompletion } from './Components'; +import { makeRoomPermalink } from "../utils/permalinks/Permalinks"; +import { ICompletion, ISelectionRange } from "./Autocompleter"; import RoomAvatar from '../components/views/avatars/RoomAvatar'; import SettingsStore from "../settings/SettingsStore"; diff --git a/src/components/views/avatars/BaseAvatar.tsx b/src/components/views/avatars/BaseAvatar.tsx index 6949c14636..f98f8c88a1 100644 --- a/src/components/views/avatars/BaseAvatar.tsx +++ b/src/components/views/avatars/BaseAvatar.tsx @@ -17,16 +17,17 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, {useCallback, useContext, useEffect, useState} from 'react'; +import React, { useCallback, useContext, useEffect, useState } from 'react'; import classNames from 'classnames'; +import { ResizeMethod } from 'matrix-js-sdk/src/@types/partials'; + import * as AvatarLogic from '../../../Avatar'; import SettingsStore from "../../../settings/SettingsStore"; import AccessibleButton from '../elements/AccessibleButton'; import RoomContext from "../../../contexts/RoomContext"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; -import {useEventEmitter} from "../../../hooks/useEventEmitter"; -import {toPx} from "../../../utils/units"; -import {ResizeMethod} from "../../../Avatar"; +import { useEventEmitter } from "../../../hooks/useEventEmitter"; +import { toPx } from "../../../utils/units"; import { _t } from '../../../languageHandler'; interface IProps { diff --git a/src/components/views/avatars/GroupAvatar.tsx b/src/components/views/avatars/GroupAvatar.tsx index 3734ba9504..13dbbfec09 100644 --- a/src/components/views/avatars/GroupAvatar.tsx +++ b/src/components/views/avatars/GroupAvatar.tsx @@ -15,10 +15,11 @@ limitations under the License. */ import React from 'react'; +import { ResizeMethod } from 'matrix-js-sdk/src/@types/partials'; + import BaseAvatar from './BaseAvatar'; -import {replaceableComponent} from "../../../utils/replaceableComponent"; -import {mediaFromMxc} from "../../../customisations/Media"; -import {ResizeMethod} from "../../../Avatar"; +import { replaceableComponent } from "../../../utils/replaceableComponent"; +import { mediaFromMxc } from "../../../customisations/Media"; export interface IProps { groupId?: string; diff --git a/src/components/views/avatars/MemberAvatar.tsx b/src/components/views/avatars/MemberAvatar.tsx index 3205ca372c..862563a8b4 100644 --- a/src/components/views/avatars/MemberAvatar.tsx +++ b/src/components/views/avatars/MemberAvatar.tsx @@ -16,14 +16,14 @@ limitations under the License. */ import React from 'react'; -import {RoomMember} from "matrix-js-sdk/src/models/room-member"; +import { RoomMember } from "matrix-js-sdk/src/models/room-member"; +import { ResizeMethod } from 'matrix-js-sdk/src/@types/partials'; import dis from "../../../dispatcher/dispatcher"; -import {Action} from "../../../dispatcher/actions"; +import { Action } from "../../../dispatcher/actions"; import BaseAvatar from "./BaseAvatar"; -import {replaceableComponent} from "../../../utils/replaceableComponent"; -import {mediaFromMxc} from "../../../customisations/Media"; -import {ResizeMethod} from "../../../Avatar"; +import { replaceableComponent } from "../../../utils/replaceableComponent"; +import { mediaFromMxc } from "../../../customisations/Media"; interface IProps extends Omit, "name" | "idName" | "url"> { member: RoomMember; diff --git a/src/components/views/avatars/RoomAvatar.tsx b/src/components/views/avatars/RoomAvatar.tsx index 4693d907ba..bd820509c5 100644 --- a/src/components/views/avatars/RoomAvatar.tsx +++ b/src/components/views/avatars/RoomAvatar.tsx @@ -13,17 +13,17 @@ 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 React, {ComponentProps} from 'react'; -import Room from 'matrix-js-sdk/src/models/room'; +import React, { ComponentProps } from 'react'; +import { Room } from 'matrix-js-sdk/src/models/room'; +import { ResizeMethod } from 'matrix-js-sdk/src/@types/partials'; import BaseAvatar from './BaseAvatar'; import ImageView from '../elements/ImageView'; -import {MatrixClientPeg} from '../../../MatrixClientPeg'; +import { MatrixClientPeg } from '../../../MatrixClientPeg'; import Modal from '../../../Modal'; import * as Avatar from '../../../Avatar'; -import {ResizeMethod} from "../../../Avatar"; -import {replaceableComponent} from "../../../utils/replaceableComponent"; -import {mediaFromMxc} from "../../../customisations/Media"; +import { replaceableComponent } from "../../../utils/replaceableComponent"; +import { mediaFromMxc } from "../../../customisations/Media"; interface IProps extends Omit, "name" | "idName" | "url" | "onClick"> { // Room may be left unset here, but if it is, diff --git a/src/components/views/elements/RoomName.tsx b/src/components/views/elements/RoomName.tsx index 9178155d19..cdd83aedc2 100644 --- a/src/components/views/elements/RoomName.tsx +++ b/src/components/views/elements/RoomName.tsx @@ -14,10 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {useEffect, useState} from "react"; -import {Room} from "matrix-js-sdk/src/models/room"; +import React, { useEffect, useState } from "react"; +import { Room } from "matrix-js-sdk/src/models/room"; -import {useEventEmitter} from "../../../hooks/useEventEmitter"; +import { useEventEmitter } from "../../../hooks/useEventEmitter"; interface IProps { room: Room; @@ -34,7 +34,7 @@ const RoomName = ({ room, children }: IProps): JSX.Element => { }, [room]); if (children) return children(name); - return name || ""; + return <>{ name || "" }; }; export default RoomName; diff --git a/src/components/views/rooms/WhoIsTypingTile.tsx b/src/components/views/rooms/WhoIsTypingTile.tsx index 3a1d2051b4..93078ff645 100644 --- a/src/components/views/rooms/WhoIsTypingTile.tsx +++ b/src/components/views/rooms/WhoIsTypingTile.tsx @@ -16,7 +16,7 @@ limitations under the License. */ import React from 'react'; -import Room from "matrix-js-sdk/src/models/room"; +import { Room } from "matrix-js-sdk/src/models/room"; import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { MatrixEvent } from "matrix-js-sdk/src/models/event"; diff --git a/src/customisations/Media.ts b/src/customisations/Media.ts index f9d957b60c..37e91fc54b 100644 --- a/src/customisations/Media.ts +++ b/src/customisations/Media.ts @@ -14,10 +14,11 @@ * limitations under the License. */ -import {MatrixClientPeg} from "../MatrixClientPeg"; -import {IMediaEventContent, IPreparedMedia, prepEventContentAsMedia} from "./models/IMediaEventContent"; -import {ResizeMethod} from "../Avatar"; -import {MatrixClient} from "matrix-js-sdk/src/client"; +import { MatrixClient } from "matrix-js-sdk/src/client"; +import { ResizeMethod } from "matrix-js-sdk/src/@types/partials"; + +import { MatrixClientPeg } from "../MatrixClientPeg"; +import { IMediaEventContent, IPreparedMedia, prepEventContentAsMedia } from "./models/IMediaEventContent"; // Populate this class with the details of your customisations when copying it. diff --git a/src/utils/ShieldUtils.ts b/src/utils/ShieldUtils.ts index 5fe653fed0..c855b81bf8 100644 --- a/src/utils/ShieldUtils.ts +++ b/src/utils/ShieldUtils.ts @@ -1,30 +1,31 @@ +/* +Copyright 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 { MatrixClient } from "matrix-js-sdk/src/client"; +import { Room } from "matrix-js-sdk/src/models/room"; + import DMRoomMap from './DMRoomMap'; -/* For now, a cut-down type spec for the client */ -interface Client { - getUserId: () => string; - checkUserTrust: (userId: string) => { - isCrossSigningVerified: () => boolean - wasCrossSigningVerified: () => boolean - }; - getStoredDevicesForUser: (userId: string) => [{ deviceId: string }]; - checkDeviceTrust: (userId: string, deviceId: string) => { - isVerified: () => boolean - }; -} - -interface Room { - getEncryptionTargetMembers: () => Promise<[{userId: string}]>; - roomId: string; -} - export enum E2EStatus { Warning = "warning", Verified = "verified", Normal = "normal" } -export async function shieldStatusForRoom(client: Client, room: Room): Promise { +export async function shieldStatusForRoom(client: MatrixClient, room: Room): Promise { const members = (await room.getEncryptionTargetMembers()).map(({userId}) => userId); const inDMMap = !!DMRoomMap.shared().getUserIdForRoomId(room.roomId); From 3b7c92fd9ee02961566eb52471f5883cbe12db8a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 18 Jun 2021 16:18:42 +0100 Subject: [PATCH 03/10] Use new js-sdk types properly --- src/components/structures/RoomView.tsx | 4 ++-- src/mjolnir/BanList.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index d9f2d5231b..bfc7a1972d 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -23,7 +23,7 @@ limitations under the License. import React, { createRef } from 'react'; import classNames from 'classnames'; -import { IRecommendedVersion, Room } from "matrix-js-sdk/src/models/room"; +import { IRecommendedVersion, NotificationCountType, 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"; @@ -2054,7 +2054,7 @@ export default class RoomView extends React.Component { if (!this.state.atEndOfLiveTimeline && !this.state.searchResults) { const JumpToBottomButton = sdk.getComponent('rooms.JumpToBottomButton'); jumpToBottom = ( 0} + highlight={this.state.room.getUnreadNotificationCount(NotificationCountType.Highlight) > 0} numUnreadMessages={this.state.numUnreadMessages} onScrollToBottomClick={this.jumpToLiveTimeline} roomId={this.state.roomId} diff --git a/src/mjolnir/BanList.ts b/src/mjolnir/BanList.ts index 21cd5d4cf7..89eec89500 100644 --- a/src/mjolnir/BanList.ts +++ b/src/mjolnir/BanList.ts @@ -92,7 +92,7 @@ export class BanList { if (!room) return; for (const eventType of ALL_RULE_TYPES) { - const events = room.currentState.getStateEvents(eventType, undefined); + const events = room.currentState.getStateEvents(eventType); for (const ev of events) { if (!ev.getStateKey()) continue; From 0ae4e7b11de934dcd28645f55f73646722b507ee Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 18 Jun 2021 16:21:46 +0100 Subject: [PATCH 04/10] Fix typescript types --- src/SlashCommands.tsx | 7 +++--- .../views/right_panel/EncryptionPanel.tsx | 23 ++++++++++--------- src/components/views/right_panel/UserInfo.tsx | 4 ++-- src/components/views/rooms/NewRoomIntro.tsx | 21 +++++++++-------- src/dispatcher/payloads/ViewUserPayload.ts | 3 ++- src/stores/RoomViewStore.tsx | 2 +- .../room-list/filters/SpaceFilterCondition.ts | 2 +- src/utils/WidgetUtils.ts | 23 ++++++++++--------- 8 files changed, 44 insertions(+), 41 deletions(-) diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index 9700c57d67..bd2133f3d9 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -17,8 +17,8 @@ See the License for the specific language governing permissions and limitations under the License. */ - import * as React from 'react'; +import { User } from "matrix-js-sdk/src/models/user"; import * as ContentHelpers from 'matrix-js-sdk/src/content-helpers'; import {MatrixClientPeg} from './MatrixClientPeg'; @@ -1019,9 +1019,8 @@ export const Commands = [ const member = MatrixClientPeg.get().getRoom(roomId).getMember(userId); dis.dispatch({ action: Action.ViewUser, - // XXX: We should be using a real member object and not assuming what the - // receiver wants. - member: member || {userId}, + // XXX: We should be using a real member object and not assuming what the receiver wants. + member: member || { userId } as User, }); return success(); }, diff --git a/src/components/views/right_panel/EncryptionPanel.tsx b/src/components/views/right_panel/EncryptionPanel.tsx index c237a4ade6..3a26427246 100644 --- a/src/components/views/right_panel/EncryptionPanel.tsx +++ b/src/components/views/right_panel/EncryptionPanel.tsx @@ -14,28 +14,29 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, {useCallback, useEffect, useState} from "react"; +import React, { useCallback, useEffect, useState } from "react"; +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 { PHASE_REQUESTED, PHASE_UNSENT } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; import EncryptionInfo from "./EncryptionInfo"; import VerificationPanel from "./VerificationPanel"; -import {MatrixClientPeg} from "../../../MatrixClientPeg"; -import {ensureDMExists} from "../../../createRoom"; -import {useEventEmitter} from "../../../hooks/useEventEmitter"; +import { MatrixClientPeg } from "../../../MatrixClientPeg"; +import { ensureDMExists } from "../../../createRoom"; +import { useEventEmitter } from "../../../hooks/useEventEmitter"; import Modal from "../../../Modal"; -import {PHASE_REQUESTED, PHASE_UNSENT} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; import * as sdk from "../../../index"; -import {_t} from "../../../languageHandler"; -import {VerificationRequest} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; -import {RoomMember} from "matrix-js-sdk/src/models/room-member"; +import { _t } from "../../../languageHandler"; import dis from "../../../dispatcher/dispatcher"; -import {Action} from "../../../dispatcher/actions"; -import {RightPanelPhases} from "../../../stores/RightPanelStorePhases"; +import { Action } from "../../../dispatcher/actions"; +import { RightPanelPhases } from "../../../stores/RightPanelStorePhases"; // cancellation codes which constitute a key mismatch const MISMATCHES = ["m.key_mismatch", "m.user_error", "m.mismatched_sas"]; interface IProps { - member: RoomMember; + member: RoomMember | User; onClose: () => void; verificationRequest: VerificationRequest; verificationRequestPromise: Promise; diff --git a/src/components/views/right_panel/UserInfo.tsx b/src/components/views/right_panel/UserInfo.tsx index 0b37fb9dd6..8833cb6862 100644 --- a/src/components/views/right_panel/UserInfo.tsx +++ b/src/components/views/right_panel/UserInfo.tsx @@ -1594,7 +1594,7 @@ const UserInfo: React.FC = ({ content = ( @@ -1605,7 +1605,7 @@ const UserInfo: React.FC = ({ content = ( } - member={member} + member={member as User | RoomMember} onClose={onEncryptionPanelClose} isRoomEncrypted={isRoomEncrypted} /> diff --git a/src/components/views/rooms/NewRoomIntro.tsx b/src/components/views/rooms/NewRoomIntro.tsx index 3bf9a9db33..2b2958e3f3 100644 --- a/src/components/views/rooms/NewRoomIntro.tsx +++ b/src/components/views/rooms/NewRoomIntro.tsx @@ -14,25 +14,26 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, {useContext} from "react"; -import {EventType} from "matrix-js-sdk/src/@types/event"; +import React, { useContext } from "react"; +import { EventType } from "matrix-js-sdk/src/@types/event"; +import { MatrixClient } from "matrix-js-sdk/src/client"; +import { Room } from "matrix-js-sdk/src/models/room"; +import { User } from "matrix-js-sdk/src/models/user"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import RoomContext from "../../../contexts/RoomContext"; import DMRoomMap from "../../../utils/DMRoomMap"; -import {_t} from "../../../languageHandler"; +import { _t } from "../../../languageHandler"; import AccessibleButton from "../elements/AccessibleButton"; -import MiniAvatarUploader, {AVATAR_SIZE} from "../elements/MiniAvatarUploader"; +import MiniAvatarUploader, { AVATAR_SIZE } from "../elements/MiniAvatarUploader"; import RoomAvatar from "../avatars/RoomAvatar"; import defaultDispatcher from "../../../dispatcher/dispatcher"; -import {ViewUserPayload} from "../../../dispatcher/payloads/ViewUserPayload"; -import {Action} from "../../../dispatcher/actions"; +import { ViewUserPayload } from "../../../dispatcher/payloads/ViewUserPayload"; +import { Action } from "../../../dispatcher/actions"; import dis from "../../../dispatcher/dispatcher"; import SpaceStore from "../../../stores/SpaceStore"; -import {showSpaceInvite} from "../../../utils/space"; - +import { showSpaceInvite } from "../../../utils/space"; import { privateShouldBeEncrypted } from "../../../createRoom"; - import EventTileBubble from "../messages/EventTileBubble"; import { ROOM_SECURITY_TAB } from "../dialogs/RoomSettingsDialog"; @@ -61,7 +62,7 @@ const NewRoomIntro = () => { defaultDispatcher.dispatch({ action: Action.ViewUser, // XXX: We should be using a real member object and not assuming what the receiver wants. - member: member || {userId: dmPartner}, + member: member || { userId: dmPartner } as User, }); }} /> diff --git a/src/dispatcher/payloads/ViewUserPayload.ts b/src/dispatcher/payloads/ViewUserPayload.ts index c2838d0dbb..c4d73aea6a 100644 --- a/src/dispatcher/payloads/ViewUserPayload.ts +++ b/src/dispatcher/payloads/ViewUserPayload.ts @@ -15,6 +15,7 @@ limitations under the License. */ import { RoomMember } from "matrix-js-sdk/src/models/room-member"; +import { User } from "matrix-js-sdk/src/models/user"; import { ActionPayload } from "../payloads"; import { Action } from "../actions"; @@ -25,5 +26,5 @@ export interface ViewUserPayload extends ActionPayload { * The member to view. May be null or falsy to indicate that no member * should be shown (hide whichever relevant components). */ - member?: RoomMember; + member?: RoomMember | User; } diff --git a/src/stores/RoomViewStore.tsx b/src/stores/RoomViewStore.tsx index cc3eafffcd..87978df471 100644 --- a/src/stores/RoomViewStore.tsx +++ b/src/stores/RoomViewStore.tsx @@ -276,7 +276,7 @@ class RoomViewStore extends Store { const address = this.state.roomAlias || this.state.roomId; const viaServers = this.state.viaServers || []; try { - await retry(() => cli.joinRoom(address, { + await retry(() => cli.joinRoom(address, { viaServers, ...payload.opts, }), NUM_JOIN_RETRY, (err) => { diff --git a/src/stores/room-list/filters/SpaceFilterCondition.ts b/src/stores/room-list/filters/SpaceFilterCondition.ts index 6a06bee0d8..79e258927d 100644 --- a/src/stores/room-list/filters/SpaceFilterCondition.ts +++ b/src/stores/room-list/filters/SpaceFilterCondition.ts @@ -29,7 +29,7 @@ import { setHasDiff } from "../../../utils/sets"; * + All DMs */ export class SpaceFilterCondition extends EventEmitter implements IFilterCondition, IDestroyable { - private roomIds = new Set(); + private roomIds = new Set(); private space: Room = null; public get kind(): FilterKind { diff --git a/src/utils/WidgetUtils.ts b/src/utils/WidgetUtils.ts index 7ff0529363..926278a20a 100644 --- a/src/utils/WidgetUtils.ts +++ b/src/utils/WidgetUtils.ts @@ -16,19 +16,20 @@ limitations under the License. */ import * as url from "url"; +import { Capability, IWidget, IWidgetData, MatrixCapabilities } from "matrix-widget-api"; +import { Room } from "matrix-js-sdk/src/models/room"; +import { MatrixEvent } from "matrix-js-sdk/src/models/event"; -import {MatrixClientPeg} from '../MatrixClientPeg'; +import { MatrixClientPeg } from '../MatrixClientPeg'; import SdkConfig from "../SdkConfig"; import dis from '../dispatcher/dispatcher'; import WidgetEchoStore from '../stores/WidgetEchoStore'; import SettingsStore from "../settings/SettingsStore"; -import {IntegrationManagers} from "../integrations/IntegrationManagers"; -import {Room} from "matrix-js-sdk/src/models/room"; -import {WidgetType} from "../widgets/WidgetType"; -import {objectClone} from "./objects"; -import {_t} from "../languageHandler"; -import {Capability, IWidget, IWidgetData, MatrixCapabilities} from "matrix-widget-api"; -import {IApp} from "../stores/WidgetStore"; +import { IntegrationManagers } from "../integrations/IntegrationManagers"; +import { WidgetType } from "../widgets/WidgetType"; +import { objectClone } from "./objects"; +import { _t } from "../languageHandler"; +import { IApp } from "../stores/WidgetStore"; // How long we wait for the state event echo to come back from the server // before waitFor[Room/User]Widget rejects its promise @@ -377,9 +378,9 @@ export default class WidgetUtils { return widgets.filter(w => w.content && w.content.type === "m.integration_manager"); } - static getRoomWidgetsOfType(room: Room, type: WidgetType): IWidgetEvent[] { - const widgets = WidgetUtils.getRoomWidgets(room); - return (widgets || []).filter(w => { + static getRoomWidgetsOfType(room: Room, type: WidgetType): MatrixEvent[] { + const widgets = WidgetUtils.getRoomWidgets(room) || []; + return widgets.filter(w => { const content = w.getContent(); return content.url && type.matches(content.type); }); From 233e2aa425266791f99c99aeb4f77f827c986ff9 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 18 Jun 2021 16:22:31 +0100 Subject: [PATCH 05/10] Fix bugs identified by the typescripting --- src/components/views/rooms/AuxPanel.tsx | 12 ++++++------ src/components/views/rooms/RoomTile.tsx | 4 ++-- src/stores/CommunityPrototypeStore.ts | 13 ++++++++++--- src/stores/SpaceStore.tsx | 12 +++++++++--- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/components/views/rooms/AuxPanel.tsx b/src/components/views/rooms/AuxPanel.tsx index 74609cca13..f6cc0f4d45 100644 --- a/src/components/views/rooms/AuxPanel.tsx +++ b/src/components/views/rooms/AuxPanel.tsx @@ -15,10 +15,12 @@ limitations under the License. */ import React from 'react'; -import { MatrixClientPeg } from "../../../MatrixClientPeg"; -import { Room } from 'matrix-js-sdk/src/models/room' -import AppsDrawer from './AppsDrawer'; import classNames from 'classnames'; +import { lexicographicCompare } from 'matrix-js-sdk/src/utils'; +import { Room } from 'matrix-js-sdk/src/models/room' + +import { MatrixClientPeg } from "../../../MatrixClientPeg"; +import AppsDrawer from './AppsDrawer'; import RateLimitedFunc from '../../../ratelimitedfunc'; import SettingsStore from "../../../settings/SettingsStore"; import AutoHideScrollbar from "../../structures/AutoHideScrollbar"; @@ -106,9 +108,7 @@ export default class AuxPanel extends React.Component { if (this.props.room && SettingsStore.getValue("feature_state_counters")) { const stateEvs = this.props.room.currentState.getStateEvents('re.jki.counter'); - stateEvs.sort((a, b) => { - return a.getStateKey() < b.getStateKey(); - }); + stateEvs.sort((a, b) => lexicographicCompare(a.getStateKey(), b.getStateKey())); for (const ev of stateEvs) { const title = ev.getContent().title; diff --git a/src/components/views/rooms/RoomTile.tsx b/src/components/views/rooms/RoomTile.tsx index aae182eca4..310ff29010 100644 --- a/src/components/views/rooms/RoomTile.tsx +++ b/src/components/views/rooms/RoomTile.tsx @@ -119,7 +119,7 @@ export default class RoomTile extends React.PureComponent { }; private onLocalEchoUpdated = (ev: MatrixEvent, room: Room) => { - if (!room?.roomId === this.props.room.roomId) return; + if (room?.roomId !== this.props.room.roomId) return; this.setState({hasUnsentEvents: this.countUnsentEvents() > 0}); }; @@ -316,7 +316,7 @@ export default class RoomTile extends React.PureComponent { 0, )); } else { - console.warn(`Unexpected tag ${tagId} applied to ${this.props.room.room_id}`); + console.warn(`Unexpected tag ${tagId} applied to ${this.props.room.roomId}`); } if ((ev as React.KeyboardEvent).key === Key.ENTER) { diff --git a/src/stores/CommunityPrototypeStore.ts b/src/stores/CommunityPrototypeStore.ts index 023845c9ee..a6f4574a58 100644 --- a/src/stores/CommunityPrototypeStore.ts +++ b/src/stores/CommunityPrototypeStore.ts @@ -107,8 +107,9 @@ export class CommunityPrototypeStore extends AsyncStoreWithClient { const pl = generalChat.currentState.getStateEvents("m.room.power_levels", ""); if (!pl) return this.isAdminOf(communityId); + const plContent = pl.getContent(); - const invitePl = isNullOrUndefined(pl.invite) ? 50 : Number(pl.invite); + const invitePl = isNullOrUndefined(plContent.invite) ? 50 : Number(plContent.invite); return invitePl <= myMember.powerLevel; } @@ -159,10 +160,16 @@ export class CommunityPrototypeStore extends AsyncStoreWithClient { if (SettingsStore.getValue("feature_communities_v2_prototypes")) { const data = this.matrixClient.getAccountData("im.vector.group_info." + roomId); if (data && data.getContent()) { - return {displayName: data.getContent().name, avatarMxc: data.getContent().avatar_url}; + return { + displayName: data.getContent().name, + avatarMxc: data.getContent().avatar_url, + }; } } - return {displayName: room.name, avatarMxc: room.avatar_url}; + return { + displayName: room.name, + avatarMxc: room.getMxcAvatarUrl(), + }; } protected async onReady(): Promise { diff --git a/src/stores/SpaceStore.tsx b/src/stores/SpaceStore.tsx index 40997d30a8..9463949aff 100644 --- a/src/stores/SpaceStore.tsx +++ b/src/stores/SpaceStore.tsx @@ -133,7 +133,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { // if the space being selected is an invite then always view that invite // else if the last viewed room in this space is joined then view that // else view space home or home depending on what is being clicked on - if (space?.getMyMembership !== "invite" && + if (space?.getMyMembership() !== "invite" && this.matrixClient?.getRoom(roomId)?.getMyMembership() === "join" ) { defaultDispatcher.dispatch({ @@ -423,8 +423,14 @@ export class SpaceStoreClass extends AsyncStoreWithClient { parent = this.rootSpaces.find(s => this.spaceFilteredRooms.get(s.roomId)?.has(roomId)); } if (!parent) { - const parents = Array.from(this.parentMap.get(roomId) || []); - parent = parents.find(p => this.matrixClient.getRoom(p)); + const parentIds = Array.from(this.parentMap.get(roomId) || []); + for (const parentId of parentIds) { + const room = this.matrixClient.getRoom(parentId); + if (room) { + parent = room; + break; + } + } } // don't trigger a context switch when we are switching a space to match the chosen room From ab94b284b8325f5da9cf7e662a6f92288b887149 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 18 Jun 2021 16:29:10 +0100 Subject: [PATCH 06/10] Updates around the use of private fields out of class --- src/components/views/rooms/NewRoomIntro.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/NewRoomIntro.tsx b/src/components/views/rooms/NewRoomIntro.tsx index 2b2958e3f3..cae86846d9 100644 --- a/src/components/views/rooms/NewRoomIntro.tsx +++ b/src/components/views/rooms/NewRoomIntro.tsx @@ -37,8 +37,8 @@ import { privateShouldBeEncrypted } from "../../../createRoom"; import EventTileBubble from "../messages/EventTileBubble"; import { ROOM_SECURITY_TAB } from "../dialogs/RoomSettingsDialog"; -function hasExpectedEncryptionSettings(room): boolean { - const isEncrypted: boolean = room._client?.isRoomEncrypted(room.roomId); +function hasExpectedEncryptionSettings(matrixClient: MatrixClient, room: Room): boolean { + const isEncrypted: boolean = matrixClient.isRoomEncrypted(room.roomId); const isPublic: boolean = room.getJoinRule() === "public"; return isPublic || !privateShouldBeEncrypted() || isEncrypted; } @@ -195,7 +195,7 @@ const NewRoomIntro = () => { return
- { !hasExpectedEncryptionSettings(room) && ( + { !hasExpectedEncryptionSettings(cli, room) && ( Date: Fri, 18 Jun 2021 17:56:18 +0100 Subject: [PATCH 07/10] fix tests --- test/components/structures/MessagePanel-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/components/structures/MessagePanel-test.js b/test/components/structures/MessagePanel-test.js index 8f0242eb30..d32970a278 100644 --- a/test/components/structures/MessagePanel-test.js +++ b/test/components/structures/MessagePanel-test.js @@ -42,7 +42,7 @@ import DMRoomMap from "../../../src/utils/DMRoomMap"; configure({ adapter: new Adapter() }); let client; -const room = new Matrix.Room(); +const room = new Matrix.Room("!roomId:server_name"); // wrap MessagePanel with a component which provides the MatrixClient in the context. class WrappedMessagePanel extends React.Component { From 958d4df957f065d321c08e04e73428c5020a6455 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 18 Jun 2021 18:32:45 +0100 Subject: [PATCH 08/10] Naive attempt at improving our end-to-end tests in Github Actions --- .github/workflows/develop.yml | 7 +++++-- ...d-tests.sh => prepare-end-to-end-tests.sh} | 11 +---------- scripts/ci/run-end-to-end-tests.sh | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 12 deletions(-) rename scripts/ci/{end-to-end-tests.sh => prepare-end-to-end-tests.sh} (65%) create mode 100755 scripts/ci/run-end-to-end-tests.sh diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml index 6410bd28fa..3c3807e33b 100644 --- a/.github/workflows/develop.yml +++ b/.github/workflows/develop.yml @@ -11,10 +11,13 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 - - name: End-to-End tests - run: ./scripts/ci/end-to-end-tests.sh + - name: Prepare End-to-End tests + run: ./scripts/ci/prepare-end-to-end-tests.sh + - name: Run End-to-End tests + run: ./scripts/ci/run-end-to-end-tests.sh - name: Archive logs uses: actions/upload-artifact@v2 + if: ${{ always() }} with: path: | test/end-to-end-tests/logs/**/* diff --git a/scripts/ci/end-to-end-tests.sh b/scripts/ci/prepare-end-to-end-tests.sh similarity index 65% rename from scripts/ci/end-to-end-tests.sh rename to scripts/ci/prepare-end-to-end-tests.sh index edb8870d8e..147e1f6445 100755 --- a/scripts/ci/end-to-end-tests.sh +++ b/scripts/ci/prepare-end-to-end-tests.sh @@ -1,8 +1,4 @@ #!/bin/bash -# -# script which is run by the CI build (after `yarn test`). -# -# clones element-web develop and runs the tests against our version of react-sdk. set -ev @@ -19,7 +15,7 @@ cd element-web element_web_dir=`pwd` CI_PACKAGE=true yarn build cd .. -# run end to end tests +# prepare end to end tests pushd test/end-to-end-tests ln -s $element_web_dir element/element-web # PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true ./install.sh @@ -28,9 +24,4 @@ echo "--- Install synapse & other dependencies" ./install.sh # install static webserver to server symlinked local copy of element ./element/install-webserver.sh -rm -r logs || true -mkdir logs -echo "+++ Running end-to-end tests" -TESTS_STARTED=1 -./run.sh --no-sandbox --log-directory logs/ popd diff --git a/scripts/ci/run-end-to-end-tests.sh b/scripts/ci/run-end-to-end-tests.sh new file mode 100755 index 0000000000..3c99391fc7 --- /dev/null +++ b/scripts/ci/run-end-to-end-tests.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +set -ev + +handle_error() { + EXIT_CODE=$? + exit $EXIT_CODE +} + +trap 'handle_error' ERR + +# run end to end tests +pushd test/end-to-end-tests +rm -r logs || true +mkdir logs +echo "--- Running end-to-end tests" +TESTS_STARTED=1 +./run.sh --no-sandbox --log-directory logs/ +popd From a2a515841138a3c545b6a44477df3e9ef3992b93 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 19 Jun 2021 15:37:48 +0100 Subject: [PATCH 09/10] Fix View Source accessing renamed private field on MatrixEvent --- src/components/structures/ViewSource.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/ViewSource.js b/src/components/structures/ViewSource.js index 6fe99dd464..b69a92dd61 100644 --- a/src/components/structures/ViewSource.js +++ b/src/components/structures/ViewSource.js @@ -55,7 +55,7 @@ export default class ViewSource extends React.Component { viewSourceContent() { const mxEvent = this.props.mxEvent.replacingEvent() || this.props.mxEvent; // show the replacing event, not the original, if it is an edit const isEncrypted = mxEvent.isEncrypted(); - const decryptedEventSource = mxEvent._clearEvent; // FIXME: _clearEvent is private + const decryptedEventSource = mxEvent.clearEvent; // FIXME: clearEvent is private const originalEventSource = mxEvent.event; if (isEncrypted) { From dda4c8ec4c9fc5e00c5d9cc5525433acbf8539d9 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 21 Jun 2021 21:04:29 +0100 Subject: [PATCH 10/10] Move Promise::allSettled typing from react-sdk to js-sdk --- src/@types/global.d.ts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index 0c6b63dd33..7eff341095 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -113,19 +113,6 @@ declare global { usageDetails?: {[key: string]: number}; } - export interface ISettledFulfilled { - status: "fulfilled"; - value: T; - } - export interface ISettledRejected { - status: "rejected"; - reason: any; - } - - interface PromiseConstructor { - allSettled(promises: Promise[]): Promise | ISettledRejected>>; - } - interface HTMLAudioElement { type?: string; // sinkId & setSinkId are experimental and typescript doesn't know about them