From 171874ae30ca36513c01a5ac74596dba33bc6826 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 2 Jul 2021 16:31:37 +0100 Subject: [PATCH 01/46] Use FocusLock around ContextMenus to simplify focus management --- src/components/structures/ContextMenu.tsx | 27 +++++++------------ .../views/spaces/SpaceCreateMenu.tsx | 23 +++++++--------- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx index 407dc6f04c..9bc9c0a8b2 100644 --- a/src/components/structures/ContextMenu.tsx +++ b/src/components/structures/ContextMenu.tsx @@ -19,6 +19,7 @@ limitations under the License. import React, { CSSProperties, RefObject, useRef, useState } from "react"; import ReactDOM from "react-dom"; import classNames from "classnames"; +import FocusLock from "react-focus-lock"; import { Key } from "../../Keyboard"; import { Writeable } from "../../@types/common"; @@ -44,6 +45,7 @@ function getOrCreateContainer(): HTMLDivElement { } const ARIA_MENU_ITEM_ROLES = new Set(["menuitem", "menuitemcheckbox", "menuitemradio"]); +const ARIA_MENU_ITEM_SELECTOR = '[role^="menuitem"], [role^="menuitemcheckbox"], [role^="menuitemradio"]'; interface IPosition { top?: number; @@ -95,8 +97,6 @@ interface IState { // this will allow the ContextMenu to manage its own focus using arrow keys as per the ARIA guidelines. @replaceableComponent("structures.ContextMenu") export class ContextMenu extends React.PureComponent { - private initialFocus: HTMLElement; - static defaultProps = { hasBackground: true, managed: true, @@ -107,24 +107,15 @@ export class ContextMenu extends React.PureComponent { this.state = { contextMenuElem: null, }; - - // persist what had focus when we got initialized so we can return it after - this.initialFocus = document.activeElement as HTMLElement; } - componentWillUnmount() { - // return focus to the thing which had it before us - this.initialFocus.focus(); - } - - private collectContextMenuRect = (element) => { + private collectContextMenuRect = (element: HTMLDivElement) => { // We don't need to clean up when unmounting, so ignore if (!element) return; - let first = element.querySelector('[role^="menuitem"]'); - if (!first) { - first = element.querySelector('[tab-index]'); - } + const first = element.querySelector(ARIA_MENU_ITEM_SELECTOR) + || element.querySelector('[tab-index]'); + if (first) { first.focus(); } @@ -381,8 +372,10 @@ export class ContextMenu extends React.PureComponent { ref={this.collectContextMenuRect} role={this.props.managed ? "menu" : undefined} > - { chevron } - { props.children } + + { chevron } + { props.children } + { background } diff --git a/src/components/views/spaces/SpaceCreateMenu.tsx b/src/components/views/spaces/SpaceCreateMenu.tsx index 4bb61d7ccb..11f68698ee 100644 --- a/src/components/views/spaces/SpaceCreateMenu.tsx +++ b/src/components/views/spaces/SpaceCreateMenu.tsx @@ -17,7 +17,8 @@ limitations under the License. import React, { useContext, useRef, useState } from "react"; import classNames from "classnames"; import { EventType, RoomType, RoomCreateTypeField } from "matrix-js-sdk/src/@types/event"; -import FocusLock from "react-focus-lock"; +import { Preset } from "matrix-js-sdk/src/@types/partials"; +import { ICreateRoomStateEvent } from "matrix-js-sdk/src/@types/requests"; import { _t } from "../../../languageHandler"; import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; @@ -33,8 +34,6 @@ import { UserTab } from "../dialogs/UserSettingsDialog"; import Field from "../elements/Field"; import withValidation from "../elements/Validation"; import { SpaceFeedbackPrompt } from "../../structures/SpaceRoomView"; -import { Preset } from "matrix-js-sdk/src/@types/partials"; -import { ICreateRoomStateEvent } from "matrix-js-sdk/src/@types/requests"; import RoomAliasField from "../elements/RoomAliasField"; const SpaceCreateMenuType = ({ title, description, className, onClick }) => { @@ -250,16 +249,14 @@ const SpaceCreateMenu = ({ onFinished }) => { wrapperClassName="mx_SpaceCreateMenu_wrapper" managed={false} > - - { - onFinished(); - defaultDispatcher.dispatch({ - action: Action.ViewUserSettings, - initialTabId: UserTab.Labs, - }); - }} /> - { body } - + { + onFinished(); + defaultDispatcher.dispatch({ + action: Action.ViewUserSettings, + initialTabId: UserTab.Labs, + }); + }} /> + { body } ; }; From b257393d74d5fc6c0b731e6696f136e906af6542 Mon Sep 17 00:00:00 2001 From: William Lachance Date: Sun, 19 Sep 2021 07:48:35 -0400 Subject: [PATCH 02/46] Make placeholder more grey when no input (fixes #17243) The placeholder is actually the label in this case. --- res/css/views/auth/_AuthBody.scss | 4 ---- res/css/views/elements/_Field.scss | 1 - 2 files changed, 5 deletions(-) diff --git a/res/css/views/auth/_AuthBody.scss b/res/css/views/auth/_AuthBody.scss index 90dca32e48..3c2736459a 100644 --- a/res/css/views/auth/_AuthBody.scss +++ b/res/css/views/auth/_AuthBody.scss @@ -58,10 +58,6 @@ limitations under the License. background-color: $authpage-body-bg-color; } - .mx_Field label { - color: $authpage-primary-color; - } - .mx_Field_labelAlwaysTopLeft label, .mx_Field select + label /* Always show a select's label on top to not collide with the value */, .mx_Field input:focus + label, diff --git a/res/css/views/elements/_Field.scss b/res/css/views/elements/_Field.scss index 71d37a015d..37d335b76d 100644 --- a/res/css/views/elements/_Field.scss +++ b/res/css/views/elements/_Field.scss @@ -100,7 +100,6 @@ limitations under the License. color 0.25s ease-out 0.1s, transform 0.25s ease-out 0.1s, background-color 0.25s ease-out 0.1s; - color: $primary-content; background-color: transparent; font-size: $font-14px; transform: translateY(0); From 8ac77c498f76f871648aad0a4c4589a5a61fc1ed Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 30 Sep 2021 13:43:59 +0100 Subject: [PATCH 03/46] Add progress bar to Community to Space migration tool and invite-one-by-one to workaround Synapse ratelimits --- .../dialogs/_AddExistingToSpaceDialog.scss | 2 +- .../_CreateSpaceFromCommunityDialog.scss | 1 + src/RoomInvite.tsx | 13 ++-- .../CreateSpaceFromCommunityDialog.tsx | 71 ++++++++++++++++--- src/i18n/strings/en_EN.json | 2 + src/utils/MultiInviter.ts | 4 +- 6 files changed, 78 insertions(+), 15 deletions(-) diff --git a/res/css/views/dialogs/_AddExistingToSpaceDialog.scss b/res/css/views/dialogs/_AddExistingToSpaceDialog.scss index 444b29c9bf..8b19f506f5 100644 --- a/res/css/views/dialogs/_AddExistingToSpaceDialog.scss +++ b/res/css/views/dialogs/_AddExistingToSpaceDialog.scss @@ -75,7 +75,7 @@ limitations under the License. @mixin ProgressBarBorderRadius 8px; } - .mx_AddExistingToSpace_progressText { + .mx_AddExistingToSpaceDialog_progressText { margin-top: 8px; font-size: $font-15px; line-height: $font-24px; diff --git a/res/css/views/dialogs/_CreateSpaceFromCommunityDialog.scss b/res/css/views/dialogs/_CreateSpaceFromCommunityDialog.scss index 6ff328f6ab..f1af24cc5f 100644 --- a/res/css/views/dialogs/_CreateSpaceFromCommunityDialog.scss +++ b/res/css/views/dialogs/_CreateSpaceFromCommunityDialog.scss @@ -74,6 +74,7 @@ limitations under the License. font-size: $font-12px; line-height: $font-15px; color: $secondary-content; + margin-top: -13px; // match height of buttons to prevent height changing .mx_ProgressBar { height: 8px; diff --git a/src/RoomInvite.tsx b/src/RoomInvite.tsx index 7d093f4092..5c9d96f509 100644 --- a/src/RoomInvite.tsx +++ b/src/RoomInvite.tsx @@ -42,10 +42,15 @@ export interface IInviteResult { * * @param {string} roomId The ID of the room to invite to * @param {string[]} addresses Array of strings of addresses to invite. May be matrix IDs or 3pids. + * @param {function} progressCallback optional callback, fired after each invite. * @returns {Promise} Promise */ -export function inviteMultipleToRoom(roomId: string, addresses: string[]): Promise { - const inviter = new MultiInviter(roomId); +export function inviteMultipleToRoom( + roomId: string, + addresses: string[], + progressCallback?: () => void, +): Promise { + const inviter = new MultiInviter(roomId, progressCallback); return inviter.invite(addresses).then(states => Promise.resolve({ states, inviter })); } @@ -104,8 +109,8 @@ export function isValid3pidInvite(event: MatrixEvent): boolean { return true; } -export function inviteUsersToRoom(roomId: string, userIds: string[]): Promise { - return inviteMultipleToRoom(roomId, userIds).then((result) => { +export function inviteUsersToRoom(roomId: string, userIds: string[], progressCallback?: () => void): Promise { + return inviteMultipleToRoom(roomId, userIds, progressCallback).then((result) => { const room = MatrixClientPeg.get().getRoom(roomId); showAnyInviteErrors(result.states, room, result.inviter); }).catch((err) => { diff --git a/src/components/views/dialogs/CreateSpaceFromCommunityDialog.tsx b/src/components/views/dialogs/CreateSpaceFromCommunityDialog.tsx index e74082427f..c7706c115c 100644 --- a/src/components/views/dialogs/CreateSpaceFromCommunityDialog.tsx +++ b/src/components/views/dialogs/CreateSpaceFromCommunityDialog.tsx @@ -39,6 +39,8 @@ import dis from "../../../dispatcher/dispatcher"; import { Action } from "../../../dispatcher/actions"; import { UserTab } from "./UserSettingsDialog"; import TagOrderActions from "../../../actions/TagOrderActions"; +import { inviteUsersToRoom } from "../../../RoomInvite"; +import ProgressBar from "../elements/ProgressBar"; interface IProps { matrixClient: MatrixClient; @@ -90,10 +92,22 @@ export interface IGroupSummary { } /* eslint-enable camelcase */ +enum Progress { + NotStarted, + ValidatingInputs, + FetchingData, + CreatingSpace, + InvitingUsers, + // anything beyond here is inviting user n - 4 +} + const CreateSpaceFromCommunityDialog: React.FC = ({ matrixClient: cli, groupId, onFinished }) => { const [loading, setLoading] = useState(true); const [error, setError] = useState(null); - const [busy, setBusy] = useState(false); + + const [progress, setProgress] = useState(Progress.NotStarted); + const [numInvites, setNumInvites] = useState(0); + const busy = progress > 0; const [avatar, setAvatar] = useState(null); // undefined means to remove avatar const [name, setName] = useState(""); @@ -122,30 +136,34 @@ const CreateSpaceFromCommunityDialog: React.FC = ({ matrixClient: cli, g if (busy) return; setError(null); - setBusy(true); + setProgress(Progress.ValidatingInputs); // require & validate the space name field if (!(await spaceNameField.current.validate({ allowEmpty: false }))) { - setBusy(false); + setProgress(0); spaceNameField.current.focus(); spaceNameField.current.validate({ allowEmpty: false, focused: true }); return; } // validate the space name alias field but do not require it if (joinRule === JoinRule.Public && !(await spaceAliasField.current.validate({ allowEmpty: true }))) { - setBusy(false); + setProgress(0); spaceAliasField.current.focus(); spaceAliasField.current.validate({ allowEmpty: true, focused: true }); return; } try { + setProgress(Progress.FetchingData); + const [rooms, members, invitedMembers] = await Promise.all([ cli.getGroupRooms(groupId).then(parseRoomsResponse) as Promise, cli.getGroupUsers(groupId).then(parseMembersResponse) as Promise, cli.getGroupInvitedUsers(groupId).then(parseMembersResponse) as Promise, ]); + setNumInvites(members.length + invitedMembers.length); + const viaMap = new Map(); for (const { roomId, canonicalAlias } of rooms) { const room = cli.getRoom(roomId); @@ -167,6 +185,8 @@ const CreateSpaceFromCommunityDialog: React.FC = ({ matrixClient: cli, g } } + setProgress(Progress.CreatingSpace); + const spaceAvatar = avatar !== undefined ? avatar : groupSummary.profile.avatar_url; const roomId = await createSpace(name, joinRule === JoinRule.Public, alias, topic, spaceAvatar, { creation_content: { @@ -179,11 +199,16 @@ const CreateSpaceFromCommunityDialog: React.FC = ({ matrixClient: cli, g via: viaMap.get(roomId) || [], }, })), - invite: [...members, ...invitedMembers].map(m => m.userId).filter(m => m !== cli.getUserId()), + // we do not specify the inviters here because Synapse applies a limit and this may cause it to trip }, { andView: false, }); + setProgress(Progress.InvitingUsers); + + const userIds = [...members, ...invitedMembers].map(m => m.userId).filter(m => m !== cli.getUserId()); + await inviteUsersToRoom(roomId, userIds, () => setProgress(p => p + 1)); + // eagerly remove it from the community panel dis.dispatch(TagOrderActions.removeTag(cli, groupId)); @@ -250,7 +275,7 @@ const CreateSpaceFromCommunityDialog: React.FC = ({ matrixClient: cli, g setError(e); } - setBusy(false); + setProgress(Progress.NotStarted); }; let footer; @@ -267,13 +292,41 @@ const CreateSpaceFromCommunityDialog: React.FC = ({ matrixClient: cli, g { _t("Retry") } ; + } else if (busy) { + let description: string; + switch (progress) { + case Progress.ValidatingInputs: + case Progress.FetchingData: + description = _t("Fetching data..."); + break; + case Progress.CreatingSpace: + description = _t("Creating Space..."); + break; + case Progress.InvitingUsers: + default: + description = _t("Adding rooms... (%(progress)s out of %(count)s)", { + count: numInvites, + progress, + }); + break; + } + + footer = + Progress.FetchingData ? progress : 0} + max={numInvites + Progress.InvitingUsers} + /> +
+ { description } +
+
; } else { footer = <> - onFinished()}> + onFinished()}> { _t("Cancel") } - - { busy ? _t("Creating...") : _t("Create Space") } + + { _t("Create Space") } ; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 9f245b8dab..8fc5fd0afd 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2280,6 +2280,8 @@ " has been made and everyone who was a part of the community has been invited to it.": " has been made and everyone who was a part of the community has been invited to it.", "To create a Space from another community, just pick the community in Preferences.": "To create a Space from another community, just pick the community in Preferences.", "Failed to migrate community": "Failed to migrate community", + "Fetching data...": "Fetching data...", + "Creating Space...": "Creating Space...", "Create Space from community": "Create Space from community", "A link to the Space will be put in your community description.": "A link to the Space will be put in your community description.", "All rooms will be added and all community members will be invited.": "All rooms will be added and all community members will be invited.", diff --git a/src/utils/MultiInviter.ts b/src/utils/MultiInviter.ts index 5b79a2ff93..abf72c97ff 100644 --- a/src/utils/MultiInviter.ts +++ b/src/utils/MultiInviter.ts @@ -62,8 +62,9 @@ export default class MultiInviter { /** * @param {string} targetId The ID of the room or group to invite to + * @param {function} progressCallback optional callback, fired after each invite. */ - constructor(targetId: string) { + constructor(targetId: string, private readonly progressCallback?: () => void) { if (targetId[0] === '+') { this.roomId = null; this.groupId = targetId; @@ -181,6 +182,7 @@ export default class MultiInviter { delete this.errors[address]; resolve(); + this.progressCallback?.(); }).catch((err) => { if (this.canceled) { return; From 7fc4f54ae74002012fdc36a041eb773c373dd642 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 4 Oct 2021 12:01:31 +0100 Subject: [PATCH 04/46] Upgrade matrix-js-sdk to 14.0.0-rc.1 --- package.json | 2 +- yarn.lock | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 46ff26bf32..8be5283117 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "katex": "^0.12.0", "linkifyjs": "^2.1.9", "lodash": "^4.17.20", - "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop", + "matrix-js-sdk": "14.0.0-rc.1", "matrix-widget-api": "^0.1.0-beta.16", "minimist": "^1.2.5", "opus-recorder": "^8.0.3", diff --git a/yarn.lock b/yarn.lock index ec2d9e08ea..0b17dc1284 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5862,9 +5862,10 @@ mathml-tag-names@^2.1.3: resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3" integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg== -"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop": - version "13.0.0" - resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/2515d07c8fc3bf5e1afc8352e3e330cca30dde85" +matrix-js-sdk@14.0.0-rc.1: + version "14.0.0-rc.1" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-14.0.0-rc.1.tgz#1cb3dfd2949d3a4414986f8ab0a92575f5fff0d1" + integrity sha512-idDBJRGOOdn9yOQWoZxwLSWv2xn7jF3IJ7W5UCmOZ0EKYmH7C1VlKAfvkGDpxdbrNCRs84SUvqJqImAuQoV4Gw== dependencies: "@babel/runtime" "^7.12.5" another-json "^0.2.0" From c0258187a28e1de5b2903c4924541cdef12d7bc7 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 4 Oct 2021 12:03:40 +0100 Subject: [PATCH 05/46] Prepare changelog for v3.32.0-rc.1 --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c28d72a3eb..327890d4da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,29 @@ +Changes in [3.32.0-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v3.32.0-rc.1) (2021-10-04) +============================================================================================================= + +## ✨ Features + * Decrease profile button touch target ([\#6900](https://github.com/matrix-org/matrix-react-sdk/pull/6900)). Contributed by [ColonisationCaptain](https://github.com/ColonisationCaptain). + * Don't let click events propagate out of context menus ([\#6892](https://github.com/matrix-org/matrix-react-sdk/pull/6892)). + * Allow closing Dropdown via its chevron ([\#6885](https://github.com/matrix-org/matrix-react-sdk/pull/6885)). Fixes vector-im/element-web#19030 and vector-im/element-web#19030. + * Improve AUX panel behaviour ([\#6699](https://github.com/matrix-org/matrix-react-sdk/pull/6699)). Fixes vector-im/element-web#18787 and vector-im/element-web#18787. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * A nicer opening animation for the Image View ([\#6454](https://github.com/matrix-org/matrix-react-sdk/pull/6454)). Fixes vector-im/element-web#18186 and vector-im/element-web#18186. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + +## 🐛 Bug Fixes + * Fix leaving space via other client leaving you in undefined-land ([\#6891](https://github.com/matrix-org/matrix-react-sdk/pull/6891)). Fixes vector-im/element-web#18455 and vector-im/element-web#18455. + * Handle newer voice message encrypted event format for chat export ([\#6893](https://github.com/matrix-org/matrix-react-sdk/pull/6893)). Contributed by [jaiwanth-v](https://github.com/jaiwanth-v). + * Fix pagination when filtering space hierarchy ([\#6876](https://github.com/matrix-org/matrix-react-sdk/pull/6876)). Fixes vector-im/element-web#19235 and vector-im/element-web#19235. + * Fix spaces null-guard breaking the dispatcher settings watching ([\#6886](https://github.com/matrix-org/matrix-react-sdk/pull/6886)). Fixes vector-im/element-web#19223 and vector-im/element-web#19223. + * Fix space children without specific `order` being sorted after those with one ([\#6878](https://github.com/matrix-org/matrix-react-sdk/pull/6878)). Fixes vector-im/element-web#19192 and vector-im/element-web#19192. + * Ensure that sub-spaces aren't considered for notification badges ([\#6881](https://github.com/matrix-org/matrix-react-sdk/pull/6881)). Fixes vector-im/element-web#18975 and vector-im/element-web#18975. + * Fix timeline autoscroll with non-standard DPI settings. ([\#6880](https://github.com/matrix-org/matrix-react-sdk/pull/6880)). Fixes vector-im/element-web#18984 and vector-im/element-web#18984. + * Pluck out JoinRuleSettings styles so they apply in space settings too ([\#6879](https://github.com/matrix-org/matrix-react-sdk/pull/6879)). Fixes vector-im/element-web#19164 and vector-im/element-web#19164. + * Null guard around the matrixClient in SpaceStore ([\#6874](https://github.com/matrix-org/matrix-react-sdk/pull/6874)). + * Fix issue (https ([\#6871](https://github.com/matrix-org/matrix-react-sdk/pull/6871)). Fixes vector-im/element-web#19138 and vector-im/element-web#19138. Contributed by [psrpinto](https://github.com/psrpinto). + * Fix pills being cut off in message bubble layout ([\#6865](https://github.com/matrix-org/matrix-react-sdk/pull/6865)). Fixes vector-im/element-web#18627 and vector-im/element-web#18627. Contributed by [robintown](https://github.com/robintown). + * Fix space admin check false positive on multiple admins ([\#6824](https://github.com/matrix-org/matrix-react-sdk/pull/6824)). + * Fix the User View ([\#6860](https://github.com/matrix-org/matrix-react-sdk/pull/6860)). Fixes vector-im/element-web#19158 and vector-im/element-web#19158. + * Fix spacing for message composer buttons ([\#6852](https://github.com/matrix-org/matrix-react-sdk/pull/6852)). Fixes vector-im/element-web#18999 and vector-im/element-web#18999. + Changes in [3.31.0](https://github.com/vector-im/element-desktop/releases/tag/v3.31.0) (2021-09-27) =================================================================================================== From 425eeada6fd6cfca6d714a602e96ff87225490b9 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 4 Oct 2021 12:03:41 +0100 Subject: [PATCH 06/46] v3.32.0-rc.1 --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 8be5283117..40633b9723 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "3.31.0", + "version": "3.32.0-rc.1", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { @@ -25,7 +25,7 @@ "bin": { "reskindex": "scripts/reskindex.js" }, - "main": "./src/index.ts", + "main": "./lib/index.ts", "matrix_src_main": "./src/index.ts", "matrix_lib_main": "./lib/index.ts", "matrix_lib_typings": "./lib/index.d.ts", @@ -215,5 +215,6 @@ "coverageReporters": [ "text" ] - } + }, + "typings": "./lib/index.d.ts" } From fa800796c78978d74634c549c074ef70b3395e4f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 6 Oct 2021 09:41:57 +0100 Subject: [PATCH 07/46] Respect tombstones in locally known rooms for Space children --- src/components/structures/SpaceHierarchy.tsx | 43 ++++++++++++++++---- src/stores/SpaceStore.ts | 31 ++++++++++++-- 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/src/components/structures/SpaceHierarchy.tsx b/src/components/structures/SpaceHierarchy.tsx index ed87b04c8a..8e1a472984 100644 --- a/src/components/structures/SpaceHierarchy.tsx +++ b/src/components/structures/SpaceHierarchy.tsx @@ -15,17 +15,17 @@ limitations under the License. */ import React, { + Dispatch, + KeyboardEvent, + KeyboardEventHandler, ReactNode, + SetStateAction, useCallback, + useContext, useEffect, useMemo, useRef, useState, - KeyboardEvent, - KeyboardEventHandler, - useContext, - SetStateAction, - Dispatch, } from "react"; import { Room } from "matrix-js-sdk/src/models/room"; import { RoomHierarchy } from "matrix-js-sdk/src/room-hierarchy"; @@ -33,7 +33,8 @@ import { EventType, RoomType } from "matrix-js-sdk/src/@types/event"; import { IHierarchyRelation, IHierarchyRoom } from "matrix-js-sdk/src/@types/spaces"; import { MatrixClient } from "matrix-js-sdk/src/matrix"; import classNames from "classnames"; -import { sortBy } from "lodash"; +import { sortBy, uniqBy } from "lodash"; +import { GuestAccess, HistoryVisibility } from "matrix-js-sdk/src/@types/partials"; import dis from "../../dispatcher/dispatcher"; import defaultDispatcher from "../../dispatcher/dispatcher"; @@ -48,7 +49,7 @@ import { mediaFromMxc } from "../../customisations/Media"; import InfoTooltip from "../views/elements/InfoTooltip"; import TextWithTooltip from "../views/elements/TextWithTooltip"; import { useStateToggle } from "../../hooks/useStateToggle"; -import { getChildOrder } from "../../stores/SpaceStore"; +import SpaceStore, { getChildOrder } from "../../stores/SpaceStore"; import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton"; import { linkifyElement } from "../../HtmlUtils"; import { useDispatcher } from "../../hooks/useDispatcher"; @@ -333,6 +334,29 @@ interface IHierarchyLevelProps { onToggleClick?(parentId: string, childId: string): void; } +const toLocalRoom = (cli: MatrixClient, room: IHierarchyRoom, upgradedRoomMap: Map): IHierarchyRoom => { + const cliRoom = cli.getRoom(SpaceStore.instance.findMostUpgradedVersion(room.room_id, upgradedRoomMap)); + if (cliRoom) { + return { + ...room, + room_id: cliRoom.roomId, + room_type: cliRoom.getType(), + name: cliRoom.name, + topic: cliRoom.currentState.getStateEvents(EventType.RoomTopic, "")?.getContent().topic, + avatar_url: cliRoom.getMxcAvatarUrl(), + canonical_alias: cliRoom.getCanonicalAlias(), + aliases: cliRoom.getAltAliases(), + world_readable: cliRoom.currentState.getStateEvents(EventType.RoomHistoryVisibility, "")?.getContent() + .history_visibility === HistoryVisibility.WorldReadable, + guest_can_join: cliRoom.currentState.getStateEvents(EventType.RoomGuestAccess, "")?.getContent() + .guest_access === GuestAccess.CanJoin, + num_joined_members: cliRoom.getJoinedMemberCount(), + }; + } + + return room; +}; + export const HierarchyLevel = ({ root, roomSet, @@ -350,10 +374,11 @@ export const HierarchyLevel = ({ return getChildOrder(ev.content.order, ev.origin_server_ts, ev.state_key); }); + const upgradedRoomMap = new Map(); const [subspaces, childRooms] = sortedChildren.reduce((result, ev: IHierarchyRelation) => { const room = hierarchy.roomMap.get(ev.state_key); if (room && roomSet.has(room)) { - result[room.room_type === RoomType.Space ? 0 : 1].push(room); + result[room.room_type === RoomType.Space ? 0 : 1].push(toLocalRoom(cli, room, upgradedRoomMap)); } return result; }, [[] as IHierarchyRoom[], [] as IHierarchyRoom[]]); @@ -361,7 +386,7 @@ export const HierarchyLevel = ({ const newParents = new Set(parents).add(root.room_id); return { - childRooms.map(room => ( + uniqBy(childRooms, "room_id").map(room => ( { const createTs = childRoom?.currentState.getStateEvents(EventType.RoomCreate, "")?.getTs(); return getChildOrder(ev.getContent().order, createTs, roomId); }).map(ev => { - return this.matrixClient.getRoom(ev.getStateKey()); + return this.matrixClient.getRoom(this.findMostUpgradedVersion(ev.getStateKey())); }).filter(room => { return room?.getMyMembership() === "join" || room?.getMyMembership() === "invite"; }) || []; @@ -452,6 +452,28 @@ export class SpaceStoreClass extends AsyncStoreWithClient { this.onRoomsUpdate(); }; + // Utility to walk tombstones and find the most updated variant of the given room, + // takes a Map to enable caching of the responses given the recursive nature of the function. + public findMostUpgradedVersion( + roomId: string, + upgradedRoomMap?: Map, + seen= new Set(), + ): string { + if (seen.has(roomId)) return roomId; + if (upgradedRoomMap?.has(roomId)) return upgradedRoomMap.get(roomId); + const room = this.matrixClient.getRoom(roomId); + const tombstone = room?.currentState.getStateEvents(EventType.RoomTombstone, ""); + const replacementRoom = tombstone?.getContent().replacement_room; + if (replacementRoom && this.matrixClient.getRoom(replacementRoom)?.getMyMembership() === "join") { + seen.add(roomId); + const result = this.findMostUpgradedVersion(replacementRoom, upgradedRoomMap); + upgradedRoomMap?.set(roomId, result); + return result; + } + upgradedRoomMap?.set(roomId, roomId); + return roomId; + } + private onRoomsUpdate = throttle(() => { // TODO resolve some updates as deltas const visibleRooms = this.matrixClient.getVisibleRooms(); @@ -479,6 +501,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { }); }); + const upgradedRoomMap = new Map(); this.rootSpaces.forEach(s => { // traverse each space tree in DFS to build up the supersets as you go up, // reusing results from like subtrees. @@ -491,7 +514,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { } const [childSpaces, childRooms] = partitionSpacesAndRooms(this.getChildren(spaceId)); - const roomIds = new Set(childRooms.map(r => r.roomId)); + const roomIds = new Set(childRooms.map(r => this.findMostUpgradedVersion(r.roomId, upgradedRoomMap))); const space = this.matrixClient?.getRoom(spaceId); // Add relevant DMs @@ -505,11 +528,11 @@ export class SpaceStoreClass extends AsyncStoreWithClient { const newPath = new Set(parentPath).add(spaceId); childSpaces.forEach(childSpace => { fn(childSpace.roomId, newPath)?.forEach(roomId => { - roomIds.add(roomId); + roomIds.add(this.findMostUpgradedVersion(roomId, upgradedRoomMap)); }); }); hiddenChildren.get(spaceId)?.forEach(roomId => { - roomIds.add(roomId); + roomIds.add(this.findMostUpgradedVersion(roomId, upgradedRoomMap)); }); this.spaceFilteredRooms.set(spaceId, roomIds); return roomIds; From cadc9d29905ebb84213f7230906e5291c6ab6363 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 6 Oct 2021 09:47:56 +0100 Subject: [PATCH 08/46] Improve emoji shortcodes generated from annotations --- src/emoji.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emoji.ts b/src/emoji.ts index ee84583fc9..73898c12eb 100644 --- a/src/emoji.ts +++ b/src/emoji.ts @@ -74,7 +74,7 @@ export const EMOJI: IEmoji[] = EMOJIBASE.map((emojiData: Omit Date: Wed, 6 Oct 2021 10:27:16 +0100 Subject: [PATCH 09/46] Simplify and improve useRoomHierarchy hook --- src/components/structures/SpaceHierarchy.tsx | 25 ++++++-------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/components/structures/SpaceHierarchy.tsx b/src/components/structures/SpaceHierarchy.tsx index ed87b04c8a..069454f842 100644 --- a/src/components/structures/SpaceHierarchy.tsx +++ b/src/components/structures/SpaceHierarchy.tsx @@ -410,50 +410,39 @@ export const HierarchyLevel = ({ const INITIAL_PAGE_SIZE = 20; -export const useSpaceSummary = (space: Room): { +export const useRoomHierarchy = (space: Room): { loading: boolean; rooms: IHierarchyRoom[]; hierarchy: RoomHierarchy; loadMore(pageSize?: number): Promise ; } => { const [rooms, setRooms] = useState([]); - const [loading, setLoading] = useState(true); const [hierarchy, setHierarchy] = useState(); const resetHierarchy = useCallback(() => { const hierarchy = new RoomHierarchy(space, INITIAL_PAGE_SIZE); - setHierarchy(hierarchy); - - let discard = false; hierarchy.load().then(() => { - if (discard) return; + if (space !== hierarchy.root) return; // discard stale results setRooms(hierarchy.rooms); - setLoading(false); }); - - return () => { - discard = true; - }; + setHierarchy(hierarchy); }, [space]); useEffect(resetHierarchy, [resetHierarchy]); useDispatcher(defaultDispatcher, (payload => { if (payload.action === Action.UpdateSpaceHierarchy) { - setLoading(true); setRooms([]); // TODO resetHierarchy(); } })); const loadMore = useCallback(async (pageSize?: number) => { - if (loading || !hierarchy.canLoadMore || hierarchy.noSupport) return; - - setLoading(true); + if (hierarchy.loading || !hierarchy.canLoadMore || hierarchy.noSupport) return; await hierarchy.load(pageSize); setRooms(hierarchy.rooms); - setLoading(false); - }, [loading, hierarchy]); + }, [hierarchy]); + const loading = hierarchy?.loading ?? true; return { loading, rooms, hierarchy, loadMore }; }; @@ -587,7 +576,7 @@ const SpaceHierarchy = ({ const [selected, setSelected] = useState(new Map>()); // Map> - const { loading, rooms, hierarchy, loadMore } = useSpaceSummary(space); + const { loading, rooms, hierarchy, loadMore } = useRoomHierarchy(space); const filteredRoomSet = useMemo>(() => { if (!rooms?.length) return new Set(); From d8bc868e79d3f2dff5eae89503ba0fae82f999d3 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 6 Oct 2021 10:56:11 +0100 Subject: [PATCH 10/46] Fix spaces keyboard shortcuts not working for last space --- src/stores/SpaceStore.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stores/SpaceStore.ts b/src/stores/SpaceStore.ts index bb22aa4dbb..87562d6a07 100644 --- a/src/stores/SpaceStore.ts +++ b/src/stores/SpaceStore.ts @@ -793,7 +793,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { // 1 is Home, 2-9 are the spaces after Home if (payload.num === 1) { this.setActiveSpace(null); - } else if (this.spacePanelSpaces.length >= payload.num) { + } else if (payload.num > 0 && this.spacePanelSpaces.length > payload.num - 2) { this.setActiveSpace(this.spacePanelSpaces[payload.num - 2]); } break; From a0c0eea4fdecde03f1e54c869e481bc8a94351e5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 6 Oct 2021 10:27:16 +0100 Subject: [PATCH 11/46] Simplify and improve useRoomHierarchy hook --- src/components/structures/SpaceHierarchy.tsx | 25 ++++++-------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/components/structures/SpaceHierarchy.tsx b/src/components/structures/SpaceHierarchy.tsx index ed87b04c8a..069454f842 100644 --- a/src/components/structures/SpaceHierarchy.tsx +++ b/src/components/structures/SpaceHierarchy.tsx @@ -410,50 +410,39 @@ export const HierarchyLevel = ({ const INITIAL_PAGE_SIZE = 20; -export const useSpaceSummary = (space: Room): { +export const useRoomHierarchy = (space: Room): { loading: boolean; rooms: IHierarchyRoom[]; hierarchy: RoomHierarchy; loadMore(pageSize?: number): Promise ; } => { const [rooms, setRooms] = useState([]); - const [loading, setLoading] = useState(true); const [hierarchy, setHierarchy] = useState(); const resetHierarchy = useCallback(() => { const hierarchy = new RoomHierarchy(space, INITIAL_PAGE_SIZE); - setHierarchy(hierarchy); - - let discard = false; hierarchy.load().then(() => { - if (discard) return; + if (space !== hierarchy.root) return; // discard stale results setRooms(hierarchy.rooms); - setLoading(false); }); - - return () => { - discard = true; - }; + setHierarchy(hierarchy); }, [space]); useEffect(resetHierarchy, [resetHierarchy]); useDispatcher(defaultDispatcher, (payload => { if (payload.action === Action.UpdateSpaceHierarchy) { - setLoading(true); setRooms([]); // TODO resetHierarchy(); } })); const loadMore = useCallback(async (pageSize?: number) => { - if (loading || !hierarchy.canLoadMore || hierarchy.noSupport) return; - - setLoading(true); + if (hierarchy.loading || !hierarchy.canLoadMore || hierarchy.noSupport) return; await hierarchy.load(pageSize); setRooms(hierarchy.rooms); - setLoading(false); - }, [loading, hierarchy]); + }, [hierarchy]); + const loading = hierarchy?.loading ?? true; return { loading, rooms, hierarchy, loadMore }; }; @@ -587,7 +576,7 @@ const SpaceHierarchy = ({ const [selected, setSelected] = useState(new Map>()); // Map> - const { loading, rooms, hierarchy, loadMore } = useSpaceSummary(space); + const { loading, rooms, hierarchy, loadMore } = useRoomHierarchy(space); const filteredRoomSet = useMemo>(() => { if (!rooms?.length) return new Set(); From 52d0b0133ce0e68b23af91e585da2f5ccb2d8341 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 6 Oct 2021 14:46:39 +0100 Subject: [PATCH 12/46] Hide kick & ban options in UserInfo when looking at own profile --- src/components/views/right_panel/UserInfo.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/views/right_panel/UserInfo.tsx b/src/components/views/right_panel/UserInfo.tsx index 3ac4088182..829710185d 100644 --- a/src/components/views/right_panel/UserInfo.tsx +++ b/src/components/views/right_panel/UserInfo.tsx @@ -535,6 +535,8 @@ interface IBaseProps { const RoomKickButton: React.FC = ({ member, startUpdating, stopUpdating }) => { const cli = useContext(MatrixClientContext); + // don't render this button on our own profile, we don't want to kick ourselves + if (member.userId === cli.getUserId()) return null; // check if user can be kicked/disinvited if (member.membership !== "invite" && member.membership !== "join") return null; @@ -659,6 +661,9 @@ const RedactMessagesButton: React.FC = ({ member }) => { const BanToggleButton: React.FC = ({ member, startUpdating, stopUpdating }) => { const cli = useContext(MatrixClientContext); + // don't render this button on our own profile, we don't want to ban ourselves and can't unban ourselves anyhow + if (member.userId === cli.getUserId()) return null; + const onBanOrUnban = async () => { const { finished } = Modal.createTrackedDialog( 'Confirm User Action Dialog', From 3f6f2bcbb33df749d673a2023fcdbb165aaef595 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 6 Oct 2021 16:48:17 +0100 Subject: [PATCH 13/46] no-op a setBotPower request from the integration manager when the PL is equal to or greater to the requested PL When configured --- src/ScalarMessaging.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/ScalarMessaging.ts b/src/ScalarMessaging.ts index 888b9ce9ed..3fc362c0eb 100644 --- a/src/ScalarMessaging.ts +++ b/src/ScalarMessaging.ts @@ -452,7 +452,7 @@ function setBotOptions(event: MessageEvent, roomId: string, userId: string) }); } -function setBotPower(event: MessageEvent, roomId: string, userId: string, level: number): void { +function setBotPower(event: MessageEvent, roomId: string, userId: string, level: number, ignoreIfGreater?: boolean): void { if (!(Number.isInteger(level) && level >= 0)) { sendError(event, _t('Power level must be positive integer.')); return; @@ -473,6 +473,18 @@ function setBotPower(event: MessageEvent, roomId: string, userId: string, l }, ); + // If the PL is equal to or greater than the requested PL, ignore. + if (ignoreIfGreater) { + // As per https://matrix.org/docs/spec/client_server/r0.6.0#m-room-power-levels + const currentPl = (powerLevels.content.users && powerLevels.content.users[userId]) || powerLevels.content.users_default || 0; + + if (currentPl >= level) { + sendResponse(event, { + success: true, + }); + } + } + client.setPowerLevel(roomId, userId, level, powerEvent).then(() => { sendResponse(event, { success: true, @@ -678,7 +690,7 @@ const onMessage = function(event: MessageEvent): void { setBotOptions(event, roomId, userId); break; case Action.SetBotPower: - setBotPower(event, roomId, userId, event.data.level); + setBotPower(event, roomId, userId, event.data.level, event.data.ignoreIfGreater); break; default: console.warn("Unhandled postMessage event with action '" + event.data.action +"'"); From b373b98d487a2ca3305113f62026ea6e52dd425b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 6 Oct 2021 16:49:53 +0100 Subject: [PATCH 14/46] Simplify aria menu item roles/selectors --- src/components/structures/ContextMenu.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx index e2ec5d232c..dc6cbb59cd 100644 --- a/src/components/structures/ContextMenu.tsx +++ b/src/components/structures/ContextMenu.tsx @@ -44,9 +44,6 @@ function getOrCreateContainer(): HTMLDivElement { return container; } -const ARIA_MENU_ITEM_ROLES = new Set(["menuitem", "menuitemcheckbox", "menuitemradio"]); -const ARIA_MENU_ITEM_SELECTOR = '[role^="menuitem"], [role^="menuitemcheckbox"], [role^="menuitemradio"]'; - export interface IPosition { top?: number; bottom?: number; @@ -117,7 +114,7 @@ export class ContextMenu extends React.PureComponent { // We don't need to clean up when unmounting, so ignore if (!element) return; - const first = element.querySelector(ARIA_MENU_ITEM_SELECTOR) + const first = element.querySelector('[role^="menuitem"]') || element.querySelector('[tab-index]'); if (first) { @@ -196,7 +193,7 @@ export class ContextMenu extends React.PureComponent { descending = true; } } - } while (element && !ARIA_MENU_ITEM_ROLES.has(element.getAttribute("role"))); + } while (element && !element.getAttribute("role")?.startsWith("menuitem")); if (element) { (element as HTMLElement).focus(); From 88410a1b295ae1b2e89f449fbc7a9353073df90f Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 6 Oct 2021 16:51:07 +0100 Subject: [PATCH 15/46] Make function async --- src/ScalarMessaging.ts | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/ScalarMessaging.ts b/src/ScalarMessaging.ts index 3fc362c0eb..d068c1f924 100644 --- a/src/ScalarMessaging.ts +++ b/src/ScalarMessaging.ts @@ -452,7 +452,9 @@ function setBotOptions(event: MessageEvent, roomId: string, userId: string) }); } -function setBotPower(event: MessageEvent, roomId: string, userId: string, level: number, ignoreIfGreater?: boolean): void { +async function setBotPower( + event: MessageEvent, roomId: string, userId: string, level: number, ignoreIfGreater?: boolean, +): Promise { if (!(Number.isInteger(level) && level >= 0)) { sendError(event, _t('Power level must be positive integer.')); return; @@ -465,34 +467,34 @@ function setBotPower(event: MessageEvent, roomId: string, userId: string, l return; } - client.getStateEvent(roomId, "m.room.power_levels", "").then((powerLevels) => { - const powerEvent = new MatrixEvent( - { - type: "m.room.power_levels", - content: powerLevels, - }, - ); + try { + const powerLevels = await client.getStateEvent(roomId, "m.room.power_levels", ""); // If the PL is equal to or greater than the requested PL, ignore. - if (ignoreIfGreater) { + if (ignoreIfGreater === true) { // As per https://matrix.org/docs/spec/client_server/r0.6.0#m-room-power-levels - const currentPl = (powerLevels.content.users && powerLevels.content.users[userId]) || powerLevels.content.users_default || 0; + const currentPl = ( + powerLevels.content.users && powerLevels.content.users[userId] + ) || powerLevels.content.users_default || 0; if (currentPl >= level) { - sendResponse(event, { + return sendResponse(event, { success: true, }); } } - - client.setPowerLevel(roomId, userId, level, powerEvent).then(() => { - sendResponse(event, { - success: true, - }); - }, (err) => { - sendError(event, err.message ? err.message : _t('Failed to send request.'), err); + await client.setPowerLevel(roomId, userId, level, new MatrixEvent( + { + type: "m.room.power_levels", + content: powerLevels, + }, + )); + return sendResponse(event, { + success: true, }); - }); + } catch (err) { + sendError(event, err.message ? err.message : _t('Failed to send request.'), err); + } } function getMembershipState(event: MessageEvent, roomId: string, userId: string): void { From ab98549fff4cce1df885e20e031484a3f81f0369 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 6 Oct 2021 17:08:32 +0100 Subject: [PATCH 16/46] move the logic to the parent so that the section hiding works --- src/components/views/right_panel/UserInfo.tsx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/components/views/right_panel/UserInfo.tsx b/src/components/views/right_panel/UserInfo.tsx index 829710185d..7de38b587f 100644 --- a/src/components/views/right_panel/UserInfo.tsx +++ b/src/components/views/right_panel/UserInfo.tsx @@ -535,8 +535,6 @@ interface IBaseProps { const RoomKickButton: React.FC = ({ member, startUpdating, stopUpdating }) => { const cli = useContext(MatrixClientContext); - // don't render this button on our own profile, we don't want to kick ourselves - if (member.userId === cli.getUserId()) return null; // check if user can be kicked/disinvited if (member.membership !== "invite" && member.membership !== "join") return null; @@ -661,9 +659,6 @@ const RedactMessagesButton: React.FC = ({ member }) => { const BanToggleButton: React.FC = ({ member, startUpdating, stopUpdating }) => { const cli = useContext(MatrixClientContext); - // don't render this button on our own profile, we don't want to ban ourselves and can't unban ourselves anyhow - if (member.userId === cli.getUserId()) return null; - const onBanOrUnban = async () => { const { finished } = Modal.createTrackedDialog( 'Confirm User Action Dialog', @@ -822,7 +817,7 @@ const RoomAdminToolsContainer: React.FC = ({ const isMe = me.userId === member.userId; const canAffectUser = member.powerLevel < me.powerLevel || isMe; - if (canAffectUser && me.powerLevel >= kickPowerLevel) { + if (!isMe && canAffectUser && me.powerLevel >= kickPowerLevel) { kickButton = ; } if (me.powerLevel >= redactPowerLevel && (!SpaceStore.spacesEnabled || !room.isSpaceRoom())) { @@ -830,10 +825,10 @@ const RoomAdminToolsContainer: React.FC = ({ ); } - if (canAffectUser && me.powerLevel >= banPowerLevel) { + if (!isMe && canAffectUser && me.powerLevel >= banPowerLevel) { banButton = ; } - if (canAffectUser && me.powerLevel >= editPowerLevel && !room.isSpaceRoom()) { + if (!isMe && canAffectUser && me.powerLevel >= editPowerLevel && !room.isSpaceRoom()) { muteButton = ( Date: Thu, 7 Oct 2021 10:57:23 +0100 Subject: [PATCH 17/46] Allow the header container to collapse on itself when room list not minimised --- res/css/views/rooms/_RoomSublist.scss | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/res/css/views/rooms/_RoomSublist.scss b/res/css/views/rooms/_RoomSublist.scss index 6db2185dd5..5f92108e72 100644 --- a/res/css/views/rooms/_RoomSublist.scss +++ b/res/css/views/rooms/_RoomSublist.scss @@ -22,6 +22,12 @@ limitations under the License. display: none; } + &:not(.mx_RoomSublist_minimized) { + .mx_RoomSublist_headerContainer { + height: auto; + } + } + .mx_RoomSublist_headerContainer { // Create a flexbox to make alignment easy display: flex; @@ -41,9 +47,7 @@ limitations under the License. // The combined height must be set in the LeftPanel component for sticky headers // to work correctly. padding-bottom: 8px; - // Allow the container to collapse on itself if its children - // are not in the normal document flow - max-height: 24px; + height: 24px; color: $roomlist-header-color; .mx_RoomSublist_stickable { @@ -176,9 +180,9 @@ limitations under the License. // scroll jumps when they become sticky. However, that leaves a gap when // scrolled to the top above the first sublist (whose header can only ever // stick to top), so we make sure to exclude the first visible sublist. - &:not(.mx_RoomSublist_hidden) ~ .mx_RoomSublist .mx_RoomSublist_headerContainer { - height: 24px; - } + // &:not(.mx_RoomSublist_hidden) ~ .mx_RoomSublist .mx_RoomSublist_headerContainer { + // height: 24px; + // } .mx_RoomSublist_resizeBox { position: relative; From 047f182cd8f42d82424e960ba3d4ea768f484f3e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 7 Oct 2021 11:04:10 +0100 Subject: [PATCH 18/46] focusLock only specific context menus --- src/components/structures/ContextMenu.tsx | 31 ++++++++++++++++--- .../views/directory/NetworkDropdown.tsx | 2 +- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx index dc6cbb59cd..90d16a2eff 100644 --- a/src/components/structures/ContextMenu.tsx +++ b/src/components/structures/ContextMenu.tsx @@ -83,6 +83,10 @@ export interface IProps extends IPosition { // it will be mounted to a container at the root of the DOM. mountAsChild?: boolean; + // If specified, contents will be wrapped in a FocusLock, this is only needed if the context menu is being rendered + // within an existing FocusLock e.g inside a modal. + focusLock?: boolean; + // Function to be called on menu close onFinished(); // on resize callback @@ -98,6 +102,8 @@ interface IState { // this will allow the ContextMenu to manage its own focus using arrow keys as per the ARIA guidelines. @replaceableComponent("structures.ContextMenu") export class ContextMenu extends React.PureComponent { + private readonly initialFocus: HTMLElement; + static defaultProps = { hasBackground: true, managed: true, @@ -105,9 +111,18 @@ export class ContextMenu extends React.PureComponent { constructor(props, context) { super(props, context); + this.state = { contextMenuElem: null, }; + + // persist what had focus when we got initialized so we can return it after + this.initialFocus = document.activeElement as HTMLElement; + } + + componentWillUnmount() { + // return focus to the thing which had it before us after the unmount + this.initialFocus.focus(); } private collectContextMenuRect = (element: HTMLDivElement) => { @@ -371,6 +386,17 @@ export class ContextMenu extends React.PureComponent { ); } + let body = <> + { chevron } + { props.children } + ; + + if (props.focusLock) { + body = + { body } + ; + } + return (
{ ref={this.collectContextMenuRect} role={this.props.managed ? "menu" : undefined} > - - { chevron } - { props.children } - + { body }
{ background } diff --git a/src/components/views/directory/NetworkDropdown.tsx b/src/components/views/directory/NetworkDropdown.tsx index dbad2ca024..9a999625d7 100644 --- a/src/components/views/directory/NetworkDropdown.tsx +++ b/src/components/views/directory/NetworkDropdown.tsx @@ -268,7 +268,7 @@ const NetworkDropdown = ({ onOptionChange, protocols = {}, selectedServerName, s }; const buttonRect = handle.current.getBoundingClientRect(); - content = + content =
{ options } From 1c8bcce0ede25ac8c7a07a17aadb88ed3adeb4f1 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 7 Oct 2021 11:13:13 +0100 Subject: [PATCH 19/46] comment --- src/components/structures/ContextMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx index 90d16a2eff..4250b5925b 100644 --- a/src/components/structures/ContextMenu.tsx +++ b/src/components/structures/ContextMenu.tsx @@ -121,7 +121,7 @@ export class ContextMenu extends React.PureComponent { } componentWillUnmount() { - // return focus to the thing which had it before us after the unmount + // return focus to the thing which had it before us this.initialFocus.focus(); } From e470d7d030562d032f568296e29f5aaec6755950 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 7 Oct 2021 13:19:51 +0100 Subject: [PATCH 20/46] Make use of MatrixClient::getRoomUpgradeHistory --- src/components/structures/SpaceHierarchy.tsx | 10 ++--- src/stores/SpaceStore.ts | 41 ++++++-------------- 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/src/components/structures/SpaceHierarchy.tsx b/src/components/structures/SpaceHierarchy.tsx index 8e1a472984..38d4129294 100644 --- a/src/components/structures/SpaceHierarchy.tsx +++ b/src/components/structures/SpaceHierarchy.tsx @@ -49,7 +49,7 @@ import { mediaFromMxc } from "../../customisations/Media"; import InfoTooltip from "../views/elements/InfoTooltip"; import TextWithTooltip from "../views/elements/TextWithTooltip"; import { useStateToggle } from "../../hooks/useStateToggle"; -import SpaceStore, { getChildOrder } from "../../stores/SpaceStore"; +import { getChildOrder } from "../../stores/SpaceStore"; import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton"; import { linkifyElement } from "../../HtmlUtils"; import { useDispatcher } from "../../hooks/useDispatcher"; @@ -334,8 +334,9 @@ interface IHierarchyLevelProps { onToggleClick?(parentId: string, childId: string): void; } -const toLocalRoom = (cli: MatrixClient, room: IHierarchyRoom, upgradedRoomMap: Map): IHierarchyRoom => { - const cliRoom = cli.getRoom(SpaceStore.instance.findMostUpgradedVersion(room.room_id, upgradedRoomMap)); +const toLocalRoom = (cli: MatrixClient, room: IHierarchyRoom): IHierarchyRoom => { + const history = cli.getRoomUpgradeHistory(room.room_id, true); + const cliRoom = history[history.length - 1]; if (cliRoom) { return { ...room, @@ -374,11 +375,10 @@ export const HierarchyLevel = ({ return getChildOrder(ev.content.order, ev.origin_server_ts, ev.state_key); }); - const upgradedRoomMap = new Map(); const [subspaces, childRooms] = sortedChildren.reduce((result, ev: IHierarchyRelation) => { const room = hierarchy.roomMap.get(ev.state_key); if (room && roomSet.has(room)) { - result[room.room_type === RoomType.Space ? 0 : 1].push(toLocalRoom(cli, room, upgradedRoomMap)); + result[room.room_type === RoomType.Space ? 0 : 1].push(toLocalRoom(cli, room)); } return result; }, [[] as IHierarchyRoom[], [] as IHierarchyRoom[]]); diff --git a/src/stores/SpaceStore.ts b/src/stores/SpaceStore.ts index e8bdce738b..3b28cda57f 100644 --- a/src/stores/SpaceStore.ts +++ b/src/stores/SpaceStore.ts @@ -283,7 +283,8 @@ export class SpaceStoreClass extends AsyncStoreWithClient { const createTs = childRoom?.currentState.getStateEvents(EventType.RoomCreate, "")?.getTs(); return getChildOrder(ev.getContent().order, createTs, roomId); }).map(ev => { - return this.matrixClient.getRoom(this.findMostUpgradedVersion(ev.getStateKey())); + const history = this.matrixClient.getRoomUpgradeHistory(ev.getStateKey(), true); + return history[history.length - 1]; }).filter(room => { return room?.getMyMembership() === "join" || room?.getMyMembership() === "invite"; }) || []; @@ -452,28 +453,6 @@ export class SpaceStoreClass extends AsyncStoreWithClient { this.onRoomsUpdate(); }; - // Utility to walk tombstones and find the most updated variant of the given room, - // takes a Map to enable caching of the responses given the recursive nature of the function. - public findMostUpgradedVersion( - roomId: string, - upgradedRoomMap?: Map, - seen= new Set(), - ): string { - if (seen.has(roomId)) return roomId; - if (upgradedRoomMap?.has(roomId)) return upgradedRoomMap.get(roomId); - const room = this.matrixClient.getRoom(roomId); - const tombstone = room?.currentState.getStateEvents(EventType.RoomTombstone, ""); - const replacementRoom = tombstone?.getContent().replacement_room; - if (replacementRoom && this.matrixClient.getRoom(replacementRoom)?.getMyMembership() === "join") { - seen.add(roomId); - const result = this.findMostUpgradedVersion(replacementRoom, upgradedRoomMap); - upgradedRoomMap?.set(roomId, result); - return result; - } - upgradedRoomMap?.set(roomId, roomId); - return roomId; - } - private onRoomsUpdate = throttle(() => { // TODO resolve some updates as deltas const visibleRooms = this.matrixClient.getVisibleRooms(); @@ -501,7 +480,6 @@ export class SpaceStoreClass extends AsyncStoreWithClient { }); }); - const upgradedRoomMap = new Map(); this.rootSpaces.forEach(s => { // traverse each space tree in DFS to build up the supersets as you go up, // reusing results from like subtrees. @@ -514,7 +492,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { } const [childSpaces, childRooms] = partitionSpacesAndRooms(this.getChildren(spaceId)); - const roomIds = new Set(childRooms.map(r => this.findMostUpgradedVersion(r.roomId, upgradedRoomMap))); + const roomIds = new Set(childRooms.map(r => r.roomId)); const space = this.matrixClient?.getRoom(spaceId); // Add relevant DMs @@ -528,14 +506,19 @@ export class SpaceStoreClass extends AsyncStoreWithClient { const newPath = new Set(parentPath).add(spaceId); childSpaces.forEach(childSpace => { fn(childSpace.roomId, newPath)?.forEach(roomId => { - roomIds.add(this.findMostUpgradedVersion(roomId, upgradedRoomMap)); + roomIds.add(roomId); }); }); hiddenChildren.get(spaceId)?.forEach(roomId => { - roomIds.add(this.findMostUpgradedVersion(roomId, upgradedRoomMap)); + roomIds.add(roomId); }); - this.spaceFilteredRooms.set(spaceId, roomIds); - return roomIds; + + // Expand room IDs to all known versions of the given rooms + const expandedRoomIds = new Set(Array.from(roomIds).flatMap(roomId => { + return this.matrixClient.getRoomUpgradeHistory(roomId, true).map(r => r.roomId); + })); + this.spaceFilteredRooms.set(spaceId, expandedRoomIds); + return expandedRoomIds; }; fn(s.roomId, new Set()); From 1b334e47aae6959d2c6d5949701f0f5bd8431013 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Thu, 7 Oct 2021 15:42:23 +0100 Subject: [PATCH 21/46] Fix issue that caused the value of certain settings to be inverted (#6896) When using the SettingsStore.watchSetting() method for settings which have an invertedSettingName, the newValueAt argument passed to the callback function, would erroneously contain the inverted value. This was making it so that such settings appeared to be disabled when they should in fact be enabled, or vice-versa. This was however only the case for code which took in account the newValueAt argument. Code using the newValue argument was not affected. The settings which have an invertedSettingName, and were thus potentially impacted are: - MessageComposerInput.dontSuggestEmoji - hideRedactions - hideJoinLeaves - hideAvatarChanges - hideDisplaynameChanges - hideReadReceipts - Pill.shouldHidePillAvatar - TextualBody.disableBigEmoji - dontSendTypingNotifications - TagPanel.disableTagPanel - webRtcForceTURN Signed-off-by: Paulo Pinto --- src/settings/SettingsStore.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/settings/SettingsStore.ts b/src/settings/SettingsStore.ts index af858d2379..d2f5568988 100644 --- a/src/settings/SettingsStore.ts +++ b/src/settings/SettingsStore.ts @@ -162,9 +162,10 @@ export default class SettingsStore { const watcherId = `${new Date().getTime()}_${SettingsStore.watcherCount++}_${settingName}_${roomId}`; - const localizedCallback = (changedInRoomId, atLevel, newValAtLevel) => { + const localizedCallback = (changedInRoomId: string | null, atLevel: SettingLevel, newValAtLevel: any) => { const newValue = SettingsStore.getValue(originalSettingName); - callbackFn(originalSettingName, changedInRoomId, atLevel, newValAtLevel, newValue); + const newValueAtLevel = SettingsStore.getValueAt(atLevel, originalSettingName) ?? newValAtLevel; + callbackFn(originalSettingName, changedInRoomId, atLevel, newValueAtLevel, newValue); }; SettingsStore.watchers.set(watcherId, localizedCallback); From 57b919b10af21663aa56793281d13cad5544c701 Mon Sep 17 00:00:00 2001 From: Germain Date: Thu, 7 Oct 2021 16:51:39 +0100 Subject: [PATCH 22/46] Delete fixed headerContainer height Co-authored-by: Travis Ralston --- res/css/views/rooms/_RoomSublist.scss | 3 --- 1 file changed, 3 deletions(-) diff --git a/res/css/views/rooms/_RoomSublist.scss b/res/css/views/rooms/_RoomSublist.scss index 5f92108e72..494c8174d7 100644 --- a/res/css/views/rooms/_RoomSublist.scss +++ b/res/css/views/rooms/_RoomSublist.scss @@ -180,9 +180,6 @@ limitations under the License. // scroll jumps when they become sticky. However, that leaves a gap when // scrolled to the top above the first sublist (whose header can only ever // stick to top), so we make sure to exclude the first visible sublist. - // &:not(.mx_RoomSublist_hidden) ~ .mx_RoomSublist .mx_RoomSublist_headerContainer { - // height: 24px; - // } .mx_RoomSublist_resizeBox { position: relative; From ea55b0d45f713751066831c451a40ef57819ed9e Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Thu, 7 Oct 2021 17:01:39 +0100 Subject: [PATCH 23/46] Add room name to component state Signed-off-by: Paulo Pinto --- .../views/dialogs/RoomSettingsDialog.tsx | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/RoomSettingsDialog.tsx b/src/components/views/dialogs/RoomSettingsDialog.tsx index a73f0a595b..b1c21d5044 100644 --- a/src/components/views/dialogs/RoomSettingsDialog.tsx +++ b/src/components/views/dialogs/RoomSettingsDialog.tsx @@ -44,12 +44,22 @@ interface IProps { initialTabId?: string; } +interface IState { + roomName: string; +} + @replaceableComponent("views.dialogs.RoomSettingsDialog") -export default class RoomSettingsDialog extends React.Component { +export default class RoomSettingsDialog extends React.Component { private dispatcherRef: string; + constructor(props: IProps) { + super(props); + this.state = { roomName: '' }; + } + public componentDidMount() { this.dispatcherRef = dis.register(this.onAction); + this.setRoomName(); } public componentWillUnmount() { @@ -66,6 +76,12 @@ export default class RoomSettingsDialog extends React.Component { } }; + private setRoomName = (): void => { + this.setState({ + roomName: MatrixClientPeg.get().getRoom(this.props.roomId).name, + }); + }; + private getTabs(): Tab[] { const tabs: Tab[] = []; @@ -122,7 +138,7 @@ export default class RoomSettingsDialog extends React.Component { } render() { - const roomName = MatrixClientPeg.get().getRoom(this.props.roomId).name; + const roomName = this.state.roomName; return ( Date: Thu, 7 Oct 2021 17:04:30 +0100 Subject: [PATCH 24/46] Keep room name up-to-date in settings dialog Signed-off-by: Paulo Pinto --- src/components/views/dialogs/RoomSettingsDialog.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/views/dialogs/RoomSettingsDialog.tsx b/src/components/views/dialogs/RoomSettingsDialog.tsx index b1c21d5044..a0f1c10884 100644 --- a/src/components/views/dialogs/RoomSettingsDialog.tsx +++ b/src/components/views/dialogs/RoomSettingsDialog.tsx @@ -59,6 +59,7 @@ export default class RoomSettingsDialog extends React.Component public componentDidMount() { this.dispatcherRef = dis.register(this.onAction); + MatrixClientPeg.get().on("Room.name", this.setRoomName); this.setRoomName(); } @@ -66,6 +67,8 @@ export default class RoomSettingsDialog extends React.Component if (this.dispatcherRef) { dis.unregister(this.dispatcherRef); } + + MatrixClientPeg.get().removeListener("Room.name", this.setRoomName); } private onAction = (payload): void => { From 6aa325ed543a2af9efeea032774a8ff3df0d2d7b Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Thu, 7 Oct 2021 17:13:57 +0100 Subject: [PATCH 25/46] Rename method to onRoomName Signed-off-by: Paulo Pinto --- src/components/views/dialogs/RoomSettingsDialog.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/dialogs/RoomSettingsDialog.tsx b/src/components/views/dialogs/RoomSettingsDialog.tsx index a0f1c10884..b0c6fc4050 100644 --- a/src/components/views/dialogs/RoomSettingsDialog.tsx +++ b/src/components/views/dialogs/RoomSettingsDialog.tsx @@ -59,8 +59,8 @@ export default class RoomSettingsDialog extends React.Component public componentDidMount() { this.dispatcherRef = dis.register(this.onAction); - MatrixClientPeg.get().on("Room.name", this.setRoomName); - this.setRoomName(); + MatrixClientPeg.get().on("Room.name", this.onRoomName); + this.onRoomName(); } public componentWillUnmount() { @@ -68,7 +68,7 @@ export default class RoomSettingsDialog extends React.Component dis.unregister(this.dispatcherRef); } - MatrixClientPeg.get().removeListener("Room.name", this.setRoomName); + MatrixClientPeg.get().removeListener("Room.name", this.onRoomName); } private onAction = (payload): void => { @@ -79,7 +79,7 @@ export default class RoomSettingsDialog extends React.Component } }; - private setRoomName = (): void => { + private onRoomName = (): void => { this.setState({ roomName: MatrixClientPeg.get().getRoom(this.props.roomId).name, }); From 822f73edf7b5a5c8203e297cce95dd279e7a650e Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 7 Oct 2021 17:28:37 +0100 Subject: [PATCH 26/46] Remove stale comments in _RoomSublist.scss --- res/css/views/rooms/_RoomSublist.scss | 5 ----- 1 file changed, 5 deletions(-) diff --git a/res/css/views/rooms/_RoomSublist.scss b/res/css/views/rooms/_RoomSublist.scss index 494c8174d7..95b9f1822d 100644 --- a/res/css/views/rooms/_RoomSublist.scss +++ b/res/css/views/rooms/_RoomSublist.scss @@ -176,11 +176,6 @@ limitations under the License. } } - // In the general case, we reserve space for each sublist header to prevent - // scroll jumps when they become sticky. However, that leaves a gap when - // scrolled to the top above the first sublist (whose header can only ever - // stick to top), so we make sure to exclude the first visible sublist. - .mx_RoomSublist_resizeBox { position: relative; From c56d6ba539d00c737544134cea3cb22f765530ac Mon Sep 17 00:00:00 2001 From: Logan Arnett Date: Thu, 7 Oct 2021 13:22:43 -0400 Subject: [PATCH 27/46] updating from boolean to object in order to track if more than one thing is edited --- .../room_settings/RoomProfileSettings.tsx | 62 ++++++++++++++----- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/src/components/views/room_settings/RoomProfileSettings.tsx b/src/components/views/room_settings/RoomProfileSettings.tsx index 6533028e8c..71c0094026 100644 --- a/src/components/views/room_settings/RoomProfileSettings.tsx +++ b/src/components/views/room_settings/RoomProfileSettings.tsx @@ -35,7 +35,7 @@ interface IState { avatarFile: File; originalTopic: string; topic: string; - enableProfileSave: boolean; + profileFieldsTouched: Record; canSetName: boolean; canSetTopic: boolean; canSetAvatar: boolean; @@ -71,7 +71,7 @@ export default class RoomProfileSettings extends React.Component avatarFile: null, originalTopic: topic, topic: topic, - enableProfileSave: false, + profileFieldsTouched: {}, canSetName: room.currentState.maySendStateEvent('m.room.name', client.getUserId()), canSetTopic: room.currentState.maySendStateEvent('m.room.topic', client.getUserId()), canSetAvatar: room.currentState.maySendStateEvent('m.room.avatar', client.getUserId()), @@ -88,17 +88,24 @@ export default class RoomProfileSettings extends React.Component this.setState({ avatarUrl: null, avatarFile: null, - enableProfileSave: true, + profileFieldsTouched: { + ...this.state.profileFieldsTouched, + avatar: true + }, }); }; + private isSaveEnabled = () => { + return Boolean(Object.values(this.state.profileFieldsTouched).length) + } + private cancelProfileChanges = async (e: React.MouseEvent): Promise => { e.stopPropagation(); e.preventDefault(); - if (!this.state.enableProfileSave) return; + if (!this.isSaveEnabled()) return; this.setState({ - enableProfileSave: false, + profileFieldsTouched: {}, displayName: this.state.originalDisplayName, topic: this.state.originalTopic, avatarUrl: this.state.originalAvatarUrl, @@ -110,8 +117,8 @@ export default class RoomProfileSettings extends React.Component e.stopPropagation(); e.preventDefault(); - if (!this.state.enableProfileSave) return; - this.setState({ enableProfileSave: false }); + if (!this.isSaveEnabled()) return; + this.setState({ profileFieldsTouched: {} }); const client = MatrixClientPeg.get(); @@ -156,18 +163,37 @@ export default class RoomProfileSettings extends React.Component private onDisplayNameChanged = (e: React.ChangeEvent): void => { this.setState({ displayName: e.target.value }); if (this.state.originalDisplayName === e.target.value) { - this.setState({ enableProfileSave: false }); + this.setState({ + profileFieldsTouched: { + ...this.state.profileFieldsTouched, + name: false + }, }); } else { - this.setState({ enableProfileSave: true }); + this.setState({ + profileFieldsTouched: { + ...this.state.profileFieldsTouched, + name: true + }, + }); } }; private onTopicChanged = (e: React.ChangeEvent): void => { this.setState({ topic: e.target.value }); if (this.state.originalTopic === e.target.value) { - this.setState({ enableProfileSave: false }); + this.setState({ + profileFieldsTouched: { + ...this.state.profileFieldsTouched, + topic: false + }, + }); } else { - this.setState({ enableProfileSave: true }); + this.setState({ + profileFieldsTouched: { + ...this.state.profileFieldsTouched, + topic: true + }, + }); } }; @@ -176,7 +202,10 @@ export default class RoomProfileSettings extends React.Component this.setState({ avatarUrl: this.state.originalAvatarUrl, avatarFile: null, - enableProfileSave: false, + profileFieldsTouched: { + ...this.state.profileFieldsTouched, + avatar: false + }, }); return; } @@ -187,7 +216,10 @@ export default class RoomProfileSettings extends React.Component this.setState({ avatarUrl: String(ev.target.result), avatarFile: file, - enableProfileSave: true, + profileFieldsTouched: { + ...this.state.profileFieldsTouched, + avatar: true + }, }); }; reader.readAsDataURL(file); @@ -205,14 +237,14 @@ export default class RoomProfileSettings extends React.Component { _t("Cancel") } { _t("Save") } From 0b64dfa59ab60ae57767fbda7997fdc2eee108fd Mon Sep 17 00:00:00 2001 From: Vitor Eller Date: Thu, 7 Oct 2021 15:23:54 -0300 Subject: [PATCH 28/46] Alter phone verification button disable label --- src/components/views/settings/account/PhoneNumbers.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/settings/account/PhoneNumbers.tsx b/src/components/views/settings/account/PhoneNumbers.tsx index e5cca72867..9105dfc312 100644 --- a/src/components/views/settings/account/PhoneNumbers.tsx +++ b/src/components/views/settings/account/PhoneNumbers.tsx @@ -268,7 +268,7 @@ export default class PhoneNumbers extends React.Component { { _t("Continue") } From 4759b4fb5d7184fa5c34ccf09908b8e24d2c7687 Mon Sep 17 00:00:00 2001 From: Logan Arnett Date: Thu, 7 Oct 2021 14:58:35 -0400 Subject: [PATCH 29/46] updating for lint issues --- .../room_settings/RoomProfileSettings.tsx | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/components/views/room_settings/RoomProfileSettings.tsx b/src/components/views/room_settings/RoomProfileSettings.tsx index 71c0094026..8cc7a620f8 100644 --- a/src/components/views/room_settings/RoomProfileSettings.tsx +++ b/src/components/views/room_settings/RoomProfileSettings.tsx @@ -90,14 +90,14 @@ export default class RoomProfileSettings extends React.Component avatarFile: null, profileFieldsTouched: { ...this.state.profileFieldsTouched, - avatar: true + avatar: true, }, }); }; private isSaveEnabled = () => { - return Boolean(Object.values(this.state.profileFieldsTouched).length) - } + return Boolean(Object.values(this.state.profileFieldsTouched).length); + }; private cancelProfileChanges = async (e: React.MouseEvent): Promise => { e.stopPropagation(); @@ -166,13 +166,14 @@ export default class RoomProfileSettings extends React.Component this.setState({ profileFieldsTouched: { ...this.state.profileFieldsTouched, - name: false - }, }); + name: false, + }, + }); } else { this.setState({ profileFieldsTouched: { ...this.state.profileFieldsTouched, - name: true + name: true, }, }); } @@ -184,14 +185,14 @@ export default class RoomProfileSettings extends React.Component this.setState({ profileFieldsTouched: { ...this.state.profileFieldsTouched, - topic: false + topic: false, }, }); } else { this.setState({ profileFieldsTouched: { ...this.state.profileFieldsTouched, - topic: true + topic: true, }, }); } @@ -204,7 +205,7 @@ export default class RoomProfileSettings extends React.Component avatarFile: null, profileFieldsTouched: { ...this.state.profileFieldsTouched, - avatar: false + avatar: false, }, }); return; @@ -218,7 +219,7 @@ export default class RoomProfileSettings extends React.Component avatarFile: file, profileFieldsTouched: { ...this.state.profileFieldsTouched, - avatar: true + avatar: true, }, }); }; From 0af5f8a173c84054c1ce61b9fb4bf3e307d06733 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Fri, 8 Oct 2021 08:30:34 +0100 Subject: [PATCH 30/46] Upgrade matrix-js-sdk to 14.0.0-rc.2 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 40633b9723..5b750f176b 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "katex": "^0.12.0", "linkifyjs": "^2.1.9", "lodash": "^4.17.20", - "matrix-js-sdk": "14.0.0-rc.1", + "matrix-js-sdk": "14.0.0-rc.2", "matrix-widget-api": "^0.1.0-beta.16", "minimist": "^1.2.5", "opus-recorder": "^8.0.3", diff --git a/yarn.lock b/yarn.lock index 0b17dc1284..0bd21610ea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5862,10 +5862,10 @@ mathml-tag-names@^2.1.3: resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3" integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg== -matrix-js-sdk@14.0.0-rc.1: - version "14.0.0-rc.1" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-14.0.0-rc.1.tgz#1cb3dfd2949d3a4414986f8ab0a92575f5fff0d1" - integrity sha512-idDBJRGOOdn9yOQWoZxwLSWv2xn7jF3IJ7W5UCmOZ0EKYmH7C1VlKAfvkGDpxdbrNCRs84SUvqJqImAuQoV4Gw== +matrix-js-sdk@14.0.0-rc.2: + version "14.0.0-rc.2" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-14.0.0-rc.2.tgz#36415152740c07a99eb7ed07fad032296fac59d8" + integrity sha512-6s9WP+GKzI4/SkunULHVfs+LnkcwvopQzVyN62+7HbfEOmlzrR77JbtIfPLZmcbcm9e+g4IkoiBMOFYt35bwvA== dependencies: "@babel/runtime" "^7.12.5" another-json "^0.2.0" From 4c1e2e3f3dbfcf804714ddebf7446b205ff445f8 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Fri, 8 Oct 2021 08:32:25 +0100 Subject: [PATCH 31/46] Prepare changelog for v3.32.0-rc.2 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 327890d4da..95a9c605ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +Changes in [3.32.0-rc.2](https://github.com/vector-im/element-desktop/releases/tag/v3.32.0-rc.2) (2021-10-08) +============================================================================================================= + +## 🐛 Bug Fixes + * [Release] Fix space hierarchy pagination ([\#6910](https://github.com/matrix-org/matrix-react-sdk/pull/6910)). + Changes in [3.32.0-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v3.32.0-rc.1) (2021-10-04) ============================================================================================================= From 2a440e90cbef0c076e4bcc95fbe31e04aeb2fc88 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Fri, 8 Oct 2021 08:32:27 +0100 Subject: [PATCH 32/46] v3.32.0-rc.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5b750f176b..f4f6e3c4f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "3.32.0-rc.1", + "version": "3.32.0-rc.2", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 82ad85a9744b0da3f1f3128138ba6064989e15b6 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 8 Oct 2021 10:30:46 +0100 Subject: [PATCH 33/46] Mock usage of getRoomUpgradeHistory in SpaceStore tests --- test/stores/SpaceStore-test.ts | 1 + test/test-utils.js | 1 + 2 files changed, 2 insertions(+) diff --git a/test/stores/SpaceStore-test.ts b/test/stores/SpaceStore-test.ts index e7ca727e28..cdc3e58a4f 100644 --- a/test/stores/SpaceStore-test.ts +++ b/test/stores/SpaceStore-test.ts @@ -77,6 +77,7 @@ describe("SpaceStore", () => { const run = async () => { client.getRoom.mockImplementation(roomId => rooms.find(room => room.roomId === roomId)); + client.getRoomUpgradeHistory.mockImplementation(roomId => [rooms.find(room => room.roomId === roomId)]); await testUtils.setupAsyncStoreWithClient(store, client); jest.runAllTimers(); }; diff --git a/test/test-utils.js b/test/test-utils.js index 2091a6e0ed..d43a08ab3a 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -103,6 +103,7 @@ export function createTestClient() { isUserIgnored: jest.fn().mockReturnValue(false), getCapabilities: jest.fn().mockResolvedValue({}), supportsExperimentalThreads: () => false, + getRoomUpgradeHistory: jest.fn().mockReturnValue([]), }; } From 436996dc303a0f4552f908b421db3841c87108be Mon Sep 17 00:00:00 2001 From: rom4nik <46846000+rom4nik@users.noreply.github.com> Date: Mon, 11 Oct 2021 02:21:09 +0200 Subject: [PATCH 34/46] Prevent backdrop image from being selected --- res/css/structures/_BackdropPanel.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/css/structures/_BackdropPanel.scss b/res/css/structures/_BackdropPanel.scss index 482507cb15..63a33276e1 100644 --- a/res/css/structures/_BackdropPanel.scss +++ b/res/css/structures/_BackdropPanel.scss @@ -34,4 +34,5 @@ limitations under the License. z-index: 0; pointer-events: none; overflow: hidden; + user-select: none; } From 414b20f17e8b7a2baf0d20ee499709cbf8959d1d Mon Sep 17 00:00:00 2001 From: Dariusz Niemczyk <3636685+Palid@users.noreply.github.com> Date: Mon, 11 Oct 2021 11:26:05 +0200 Subject: [PATCH 35/46] Make thread button always visible (#6903) Fix https://github.com/vector-im/element-web/issues/18956 --- src/components/structures/FilePanel.tsx | 66 +++++++++++-------- .../structures/NotificationPanel.tsx | 13 +++- .../views/messages/MessageActionBar.tsx | 15 ++++- src/contexts/RoomContext.ts | 2 + 4 files changed, 64 insertions(+), 32 deletions(-) diff --git a/src/components/structures/FilePanel.tsx b/src/components/structures/FilePanel.tsx index 52cf5ae55b..77629839d9 100644 --- a/src/components/structures/FilePanel.tsx +++ b/src/components/structures/FilePanel.tsx @@ -37,6 +37,7 @@ import TimelinePanel from "./TimelinePanel"; import Spinner from "../views/elements/Spinner"; import { TileShape } from '../views/rooms/EventTile'; import { Layout } from "../../settings/Layout"; +import RoomContext, { TimelineRenderingType } from '../../contexts/RoomContext'; interface IProps { roomId: string; @@ -57,6 +58,7 @@ class FilePanel extends React.Component { // added to the timeline. private decryptingEvents = new Set(); public noRoom: boolean; + static contextType = RoomContext; state = { timelineSet: null, @@ -249,38 +251,46 @@ class FilePanel extends React.Component { const isRoomEncrypted = this.noRoom ? false : MatrixClientPeg.get().isRoomEncrypted(this.props.roomId); if (this.state.timelineSet) { - // console.log("rendering TimelinePanel for timelineSet " + this.state.timelineSet.room.roomId + " " + - // "(" + this.state.timelineSet._timelines.join(", ") + ")" + " with key " + this.props.roomId); return ( - - - - + + + + + + ); } else { return ( - - - + + + + + ); } } diff --git a/src/components/structures/NotificationPanel.tsx b/src/components/structures/NotificationPanel.tsx index f71c017c06..68c9049067 100644 --- a/src/components/structures/NotificationPanel.tsx +++ b/src/components/structures/NotificationPanel.tsx @@ -24,6 +24,7 @@ import TimelinePanel from "./TimelinePanel"; import Spinner from "../views/elements/Spinner"; import { TileShape } from "../views/rooms/EventTile"; import { Layout } from "../../settings/Layout"; +import RoomContext, { TimelineRenderingType } from "../../contexts/RoomContext"; interface IProps { onClose(): void; @@ -34,6 +35,7 @@ interface IProps { */ @replaceableComponent("structures.NotificationPanel") export default class NotificationPanel extends React.PureComponent { + static contextType = RoomContext; render() { const emptyState = (

{ _t('You’re all caught up') }

@@ -61,8 +63,13 @@ export default class NotificationPanel extends React.PureComponent { content = ; } - return - { content } - ; + return + + { content } + ; + ; } } diff --git a/src/components/views/messages/MessageActionBar.tsx b/src/components/views/messages/MessageActionBar.tsx index 7ee951a812..2246d2bacc 100644 --- a/src/components/views/messages/MessageActionBar.tsx +++ b/src/components/views/messages/MessageActionBar.tsx @@ -289,7 +289,7 @@ export default class MessageActionBar extends React.PureComponent ); } } + // Show thread icon even for deleted messages, but only within main timeline + if (this.context.timelineRenderingType === TimelineRenderingType.Room && + SettingsStore.getValue("feature_thread") && + this.props.mxEvent.getThread() && + !isContentActionable(this.props.mxEvent) + ) { + toolbarOpts.unshift(); + } if (allowCancel) { toolbarOpts.push(cancelSendingButton); diff --git a/src/contexts/RoomContext.ts b/src/contexts/RoomContext.ts index a57c14d90f..d3a4fadd19 100644 --- a/src/contexts/RoomContext.ts +++ b/src/contexts/RoomContext.ts @@ -21,6 +21,8 @@ import { Layout } from "../settings/Layout"; export enum TimelineRenderingType { Room, + File, + Notification, Thread } From 0d524ae70b13548a861c5f4352a793789ec10644 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 11 Oct 2021 10:43:37 +0100 Subject: [PATCH 36/46] Iterate invite your teammates to Space view --- res/css/structures/_SpaceRoomView.scss | 11 ++++++++--- src/components/structures/SpaceRoomView.tsx | 1 - 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/res/css/structures/_SpaceRoomView.scss b/res/css/structures/_SpaceRoomView.scss index 812b6dcea9..e116885047 100644 --- a/res/css/structures/_SpaceRoomView.scss +++ b/res/css/structures/_SpaceRoomView.scss @@ -422,7 +422,7 @@ $SpaceRoomViewInnerWidth: 428px; .mx_SpaceRoomView_inviteTeammates { // XXX remove this when spaces leaves Beta .mx_SpaceRoomView_inviteTeammates_betaDisclaimer { - padding: 58px 16px 16px; + padding: 16px; position: relative; border-radius: 8px; background-color: $header-panel-bg-color; @@ -465,8 +465,13 @@ $SpaceRoomViewInnerWidth: 428px; } } - .mx_SpaceRoomView_inviteTeammates_inviteDialogButton::before { - mask-image: url('$(res)/img/element-icons/room/invite.svg'); + .mx_SpaceRoomView_inviteTeammates_inviteDialogButton { + color: $accent-color; + + &::before { + mask-image: url('$(res)/img/element-icons/room/invite.svg'); + background-color: $accent-color; + } } } } diff --git a/src/components/structures/SpaceRoomView.tsx b/src/components/structures/SpaceRoomView.tsx index 270db21408..629c62cde0 100644 --- a/src/components/structures/SpaceRoomView.tsx +++ b/src/components/structures/SpaceRoomView.tsx @@ -729,7 +729,6 @@ const SpaceSetupPrivateInvite = ({ space, onFinished }) => {
- { _t("This is an experimental feature. For now, " + "new users receiving an invite will have to open the invite on to actually join.", {}, { b: sub => { sub }, From 93cdda869379d6995a0c658bda97eb742150f93d Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 11 Oct 2021 11:55:21 +0100 Subject: [PATCH 37/46] Upgrade matrix-js-sdk to 14.0.0 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index f4f6e3c4f0..d2254bfa26 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "katex": "^0.12.0", "linkifyjs": "^2.1.9", "lodash": "^4.17.20", - "matrix-js-sdk": "14.0.0-rc.2", + "matrix-js-sdk": "14.0.0", "matrix-widget-api": "^0.1.0-beta.16", "minimist": "^1.2.5", "opus-recorder": "^8.0.3", diff --git a/yarn.lock b/yarn.lock index 0bd21610ea..4a810366fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5862,10 +5862,10 @@ mathml-tag-names@^2.1.3: resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3" integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg== -matrix-js-sdk@14.0.0-rc.2: - version "14.0.0-rc.2" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-14.0.0-rc.2.tgz#36415152740c07a99eb7ed07fad032296fac59d8" - integrity sha512-6s9WP+GKzI4/SkunULHVfs+LnkcwvopQzVyN62+7HbfEOmlzrR77JbtIfPLZmcbcm9e+g4IkoiBMOFYt35bwvA== +matrix-js-sdk@14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-14.0.0.tgz#e04bca71a3dc3e3256171e184ac7614973e00db2" + integrity sha512-7OOSYpGUW7iRyNQrl/gdRxFRmbpW/C7L0gEdMbZwbOPqpbcvp6DVgl0eO+ibHoX0C8t0+rGAl/hMdOST9agGWg== dependencies: "@babel/runtime" "^7.12.5" another-json "^0.2.0" From e91d591c9070bb5e9e389591e5da453209685eb6 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 11 Oct 2021 11:57:03 +0100 Subject: [PATCH 38/46] Prepare changelog for v3.32.0 --- CHANGELOG.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95a9c605ad..a647e376f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,31 @@ +Changes in [3.32.0](https://github.com/vector-im/element-desktop/releases/tag/v3.32.0) (2021-10-11) +=================================================================================================== + +## ✨ Features + * Decrease profile button touch target ([\#6900](https://github.com/matrix-org/matrix-react-sdk/pull/6900)). Contributed by [ColonisationCaptain](https://github.com/ColonisationCaptain). + * Don't let click events propagate out of context menus ([\#6892](https://github.com/matrix-org/matrix-react-sdk/pull/6892)). + * Allow closing Dropdown via its chevron ([\#6885](https://github.com/matrix-org/matrix-react-sdk/pull/6885)). Fixes vector-im/element-web#19030 and vector-im/element-web#19030. + * Improve AUX panel behaviour ([\#6699](https://github.com/matrix-org/matrix-react-sdk/pull/6699)). Fixes vector-im/element-web#18787 and vector-im/element-web#18787. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * A nicer opening animation for the Image View ([\#6454](https://github.com/matrix-org/matrix-react-sdk/pull/6454)). Fixes vector-im/element-web#18186 and vector-im/element-web#18186. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + +## 🐛 Bug Fixes + * [Release] Fix space hierarchy pagination ([\#6910](https://github.com/matrix-org/matrix-react-sdk/pull/6910)). + * Fix leaving space via other client leaving you in undefined-land ([\#6891](https://github.com/matrix-org/matrix-react-sdk/pull/6891)). Fixes vector-im/element-web#18455 and vector-im/element-web#18455. + * Handle newer voice message encrypted event format for chat export ([\#6893](https://github.com/matrix-org/matrix-react-sdk/pull/6893)). Contributed by [jaiwanth-v](https://github.com/jaiwanth-v). + * Fix pagination when filtering space hierarchy ([\#6876](https://github.com/matrix-org/matrix-react-sdk/pull/6876)). Fixes vector-im/element-web#19235 and vector-im/element-web#19235. + * Fix spaces null-guard breaking the dispatcher settings watching ([\#6886](https://github.com/matrix-org/matrix-react-sdk/pull/6886)). Fixes vector-im/element-web#19223 and vector-im/element-web#19223. + * Fix space children without specific `order` being sorted after those with one ([\#6878](https://github.com/matrix-org/matrix-react-sdk/pull/6878)). Fixes vector-im/element-web#19192 and vector-im/element-web#19192. + * Ensure that sub-spaces aren't considered for notification badges ([\#6881](https://github.com/matrix-org/matrix-react-sdk/pull/6881)). Fixes vector-im/element-web#18975 and vector-im/element-web#18975. + * Fix timeline autoscroll with non-standard DPI settings. ([\#6880](https://github.com/matrix-org/matrix-react-sdk/pull/6880)). Fixes vector-im/element-web#18984 and vector-im/element-web#18984. + * Pluck out JoinRuleSettings styles so they apply in space settings too ([\#6879](https://github.com/matrix-org/matrix-react-sdk/pull/6879)). Fixes vector-im/element-web#19164 and vector-im/element-web#19164. + * Null guard around the matrixClient in SpaceStore ([\#6874](https://github.com/matrix-org/matrix-react-sdk/pull/6874)). + * Fix issue (https ([\#6871](https://github.com/matrix-org/matrix-react-sdk/pull/6871)). Fixes vector-im/element-web#19138 and vector-im/element-web#19138. Contributed by [psrpinto](https://github.com/psrpinto). + * Fix pills being cut off in message bubble layout ([\#6865](https://github.com/matrix-org/matrix-react-sdk/pull/6865)). Fixes vector-im/element-web#18627 and vector-im/element-web#18627. Contributed by [robintown](https://github.com/robintown). + * Fix space admin check false positive on multiple admins ([\#6824](https://github.com/matrix-org/matrix-react-sdk/pull/6824)). + * Fix the User View ([\#6860](https://github.com/matrix-org/matrix-react-sdk/pull/6860)). Fixes vector-im/element-web#19158 and vector-im/element-web#19158. + * Fix spacing for message composer buttons ([\#6852](https://github.com/matrix-org/matrix-react-sdk/pull/6852)). Fixes vector-im/element-web#18999 and vector-im/element-web#18999. + * Always show root event of a thread in room's timeline ([\#6842](https://github.com/matrix-org/matrix-react-sdk/pull/6842)). Fixes vector-im/element-web#19016 and vector-im/element-web#19016. + Changes in [3.32.0-rc.2](https://github.com/vector-im/element-desktop/releases/tag/v3.32.0-rc.2) (2021-10-08) ============================================================================================================= From 4ceb2a74cf44daf21322e25adcdf5ad6a72b5f8f Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 11 Oct 2021 11:57:04 +0100 Subject: [PATCH 39/46] v3.32.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d2254bfa26..b364f0b33c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "3.32.0-rc.2", + "version": "3.32.0", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 79a46782d6cc72fbd9018de6ea8c54c97afba55c Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 11 Oct 2021 12:03:50 +0100 Subject: [PATCH 40/46] Resetting package fields for development --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index b364f0b33c..56e413acc4 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "bin": { "reskindex": "scripts/reskindex.js" }, - "main": "./lib/index.ts", + "main": "./src/index.ts", "matrix_src_main": "./src/index.ts", "matrix_lib_main": "./lib/index.ts", "matrix_lib_typings": "./lib/index.d.ts", @@ -215,6 +215,5 @@ "coverageReporters": [ "text" ] - }, - "typings": "./lib/index.d.ts" + } } From c078e89f5953557184f7649a8f9da63c5b304bb5 Mon Sep 17 00:00:00 2001 From: Robin Townsend Date: Mon, 11 Oct 2021 14:33:40 -0400 Subject: [PATCH 41/46] Remove semicolon from notifications panel Signed-off-by: Robin Townsend --- src/components/structures/NotificationPanel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/NotificationPanel.tsx b/src/components/structures/NotificationPanel.tsx index 68c9049067..c37eeca091 100644 --- a/src/components/structures/NotificationPanel.tsx +++ b/src/components/structures/NotificationPanel.tsx @@ -69,7 +69,7 @@ export default class NotificationPanel extends React.PureComponent { }}> { content } - ; + ; } } From 6b4bcbd289860f320966360722e0d51e34904bce Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 12 Oct 2021 08:40:57 +0100 Subject: [PATCH 42/46] Upgrade matrix-js-sdk to 14.0.1 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 40633b9723..b2b09e334f 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "katex": "^0.12.0", "linkifyjs": "^2.1.9", "lodash": "^4.17.20", - "matrix-js-sdk": "14.0.0-rc.1", + "matrix-js-sdk": "14.0.1", "matrix-widget-api": "^0.1.0-beta.16", "minimist": "^1.2.5", "opus-recorder": "^8.0.3", diff --git a/yarn.lock b/yarn.lock index 0b17dc1284..15cc106ebd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5862,10 +5862,10 @@ mathml-tag-names@^2.1.3: resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3" integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg== -matrix-js-sdk@14.0.0-rc.1: - version "14.0.0-rc.1" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-14.0.0-rc.1.tgz#1cb3dfd2949d3a4414986f8ab0a92575f5fff0d1" - integrity sha512-idDBJRGOOdn9yOQWoZxwLSWv2xn7jF3IJ7W5UCmOZ0EKYmH7C1VlKAfvkGDpxdbrNCRs84SUvqJqImAuQoV4Gw== +matrix-js-sdk@14.0.1: + version "14.0.1" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-14.0.1.tgz#5984d9fafb2eda435fbe7d04a0daf37b48d595fd" + integrity sha512-+x+TaftVUXY8otBBSEHuVQp1B9UACEcHuKxmocFN/cmsjJGlk3z8hmthMbwnyq3HyOX9apme1TdbqqsoC2IlWg== dependencies: "@babel/runtime" "^7.12.5" another-json "^0.2.0" From acce5ea43af30b97c7727af797da6445a84f3bee Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 12 Oct 2021 08:42:34 +0100 Subject: [PATCH 43/46] Prepare changelog for v3.32.1 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 327890d4da..28875dcfc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [3.32.1](https://github.com/vector-im/element-desktop/releases/tag/v3.32.1) (2021-10-12) +=================================================================================================== + +## 🐛 Bug Fixes + + * Upgrade to matrix-js-sdk#14.0.1 + Changes in [3.32.0-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v3.32.0-rc.1) (2021-10-04) ============================================================================================================= From b1baa3575a54f1d06450d75338073eb61d56fa40 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 12 Oct 2021 08:42:35 +0100 Subject: [PATCH 44/46] v3.32.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b2b09e334f..9fb603eaae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "3.32.0-rc.1", + "version": "3.32.1", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 89365d943b4eb9d45ee6bb13ae5c4e47b6c653e5 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 12 Oct 2021 08:48:24 +0100 Subject: [PATCH 45/46] Resetting package fields for development --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 9fb603eaae..1433e45a44 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "bin": { "reskindex": "scripts/reskindex.js" }, - "main": "./lib/index.ts", + "main": "./src/index.ts", "matrix_src_main": "./src/index.ts", "matrix_lib_main": "./lib/index.ts", "matrix_lib_typings": "./lib/index.d.ts", @@ -215,6 +215,5 @@ "coverageReporters": [ "text" ] - }, - "typings": "./lib/index.d.ts" + } } From 193a060ec9c5278615a2698880320c24357a800d Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 12 Oct 2021 09:13:06 +0100 Subject: [PATCH 46/46] Reset matrix-js-sdk back to develop branch --- package.json | 2 +- yarn.lock | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 1433e45a44..599f61dc38 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "katex": "^0.12.0", "linkifyjs": "^2.1.9", "lodash": "^4.17.20", - "matrix-js-sdk": "14.0.1", + "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop", "matrix-widget-api": "^0.1.0-beta.16", "minimist": "^1.2.5", "opus-recorder": "^8.0.3", diff --git a/yarn.lock b/yarn.lock index dea4566b59..3d39a5344c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5840,10 +5840,9 @@ mathml-tag-names@^2.1.3: resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3" integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg== -matrix-js-sdk@14.0.1: +"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop": version "14.0.1" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-14.0.1.tgz#5984d9fafb2eda435fbe7d04a0daf37b48d595fd" - integrity sha512-+x+TaftVUXY8otBBSEHuVQp1B9UACEcHuKxmocFN/cmsjJGlk3z8hmthMbwnyq3HyOX9apme1TdbqqsoC2IlWg== + resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/e7b41fadd0d6eda7423a369c99ec7b94afd48d5d" dependencies: "@babel/runtime" "^7.12.5" another-json "^0.2.0"