From 2cbe35cbd9d7fa10400282142fba8ce428cb606e Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 7 Sep 2021 18:26:09 +0100 Subject: [PATCH 01/37] Upgrade matrix-js-sdk to 12.5.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 9798503e9e..e02d683af2 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,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": "12.5.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 e0b4a403b8..b307aa49df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5791,9 +5791,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 "12.4.0" - resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/2783d162b77d6629c574f35e88bea9ae29765c34" +matrix-js-sdk@12.5.0-rc.1: + version "12.5.0-rc.1" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-12.5.0-rc.1.tgz#138155239b4be38ca706663ca0f2739aab41f1db" + integrity sha512-R+mNTwTWO4ppXvwtiZtMLB5rjNAR28j+tHAqItfx9yAtDskjzLZEDfjRtgm6+wl5t6us1WI4p1nR6IMb8+uESQ== dependencies: "@babel/runtime" "^7.12.5" another-json "^0.2.0" From 309c9e81dc5346aeee303d56381bb238372ec88a Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 7 Sep 2021 18:28:31 +0100 Subject: [PATCH 02/37] Prepare changelog for v3.30.0-rc.1 --- CHANGELOG.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42e186220f..20812ae052 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,59 @@ +Changes in [3.30.0-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v3.30.0-rc.1) (2021-09-07) +============================================================================================================= + +## ✨ Features + * Create narrow mode for Composer ([\#6682](https://github.com/matrix-org/matrix-react-sdk/pull/6682)). Fixes vector-im/element-web#18533 and vector-im/element-web#18533. + * Prefer matrix.to alias links over room id in spaces & share ([\#6745](https://github.com/matrix-org/matrix-react-sdk/pull/6745)). Fixes vector-im/element-web#18796 and vector-im/element-web#18796. + * Add bubble highlight styling ([\#6582](https://github.com/matrix-org/matrix-react-sdk/pull/6582)). Fixes vector-im/element-web#18295 and vector-im/element-web#18295. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Stop automatic playback of voice messages if a non-voice message is encountered ([\#6728](https://github.com/matrix-org/matrix-react-sdk/pull/6728)). Fixes vector-im/element-web#18850 and vector-im/element-web#18850. + * Show call length during a call ([\#6700](https://github.com/matrix-org/matrix-react-sdk/pull/6700)). Fixes vector-im/element-web#18566 and vector-im/element-web#18566. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Serialize and retry mass-leave when leaving space ([\#6737](https://github.com/matrix-org/matrix-react-sdk/pull/6737)). Fixes vector-im/element-web#18789 and vector-im/element-web#18789. + * Improve form handling in and around space creation ([\#6739](https://github.com/matrix-org/matrix-react-sdk/pull/6739)). Fixes vector-im/element-web#18775 and vector-im/element-web#18775. + * Split autoplay GIFs and videos into different settings ([\#6726](https://github.com/matrix-org/matrix-react-sdk/pull/6726)). Fixes vector-im/element-web#5771 and vector-im/element-web#5771. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Add autoplay for voice messages ([\#6710](https://github.com/matrix-org/matrix-react-sdk/pull/6710)). Fixes vector-im/element-web#18804, vector-im/element-web#18715, vector-im/element-web#18714 vector-im/element-web#17961 and vector-im/element-web#18804. + * Allow to use basic html to format invite messages ([\#6703](https://github.com/matrix-org/matrix-react-sdk/pull/6703)). Fixes vector-im/element-web#15738 and vector-im/element-web#15738. Contributed by [skolmer](https://github.com/skolmer). + * Allow widgets, when eligible, to interact with more rooms as per MSC2762 ([\#6684](https://github.com/matrix-org/matrix-react-sdk/pull/6684)). + * Remove arbitrary limits from send/receive events for widgets ([\#6719](https://github.com/matrix-org/matrix-react-sdk/pull/6719)). Fixes vector-im/element-web#17994 and vector-im/element-web#17994. + * Reload suggested rooms if we see the state change down /sync ([\#6715](https://github.com/matrix-org/matrix-react-sdk/pull/6715)). Fixes vector-im/element-web#18761 and vector-im/element-web#18761. + * When creating private spaces, make the initial rooms restricted if supported ([\#6721](https://github.com/matrix-org/matrix-react-sdk/pull/6721)). Fixes vector-im/element-web#18722 and vector-im/element-web#18722. + * Threading exploration work ([\#6658](https://github.com/matrix-org/matrix-react-sdk/pull/6658)). Fixes vector-im/element-web#18532 and vector-im/element-web#18532. + * Default to `Don't leave any` when leaving a space ([\#6697](https://github.com/matrix-org/matrix-react-sdk/pull/6697)). Fixes vector-im/element-web#18592 and vector-im/element-web#18592. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Special case redaction event sending from widgets per MSC2762 ([\#6686](https://github.com/matrix-org/matrix-react-sdk/pull/6686)). Fixes vector-im/element-web#18573 and vector-im/element-web#18573. + * Add active speaker indicators ([\#6639](https://github.com/matrix-org/matrix-react-sdk/pull/6639)). Fixes vector-im/element-web#17627 and vector-im/element-web#17627. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Increase general app performance by optimizing layers ([\#6644](https://github.com/matrix-org/matrix-react-sdk/pull/6644)). Fixes vector-im/element-web#18730 and vector-im/element-web#18730. Contributed by [Palid](https://github.com/Palid). + +## 🐛 Bug Fixes + * Fix Space creation wizard go to my first room button behaviour ([\#6748](https://github.com/matrix-org/matrix-react-sdk/pull/6748)). Fixes vector-im/element-web#18764 and vector-im/element-web#18764. + * Fix scroll being stuck at bottom ([\#6751](https://github.com/matrix-org/matrix-react-sdk/pull/6751)). Fixes vector-im/element-web#18903 and vector-im/element-web#18903. + * Fix widgets not remembering identity verification when asked to. ([\#6742](https://github.com/matrix-org/matrix-react-sdk/pull/6742)). Fixes vector-im/element-web#15631 and vector-im/element-web#15631. + * Add missing pluralisation i18n strings for Spaces ([\#6738](https://github.com/matrix-org/matrix-react-sdk/pull/6738)). Fixes vector-im/element-web#18780 and vector-im/element-web#18780. + * Make ForgotPassword UX slightly more user friendly ([\#6636](https://github.com/matrix-org/matrix-react-sdk/pull/6636)). Fixes vector-im/element-web#11531 and vector-im/element-web#11531. Contributed by [Palid](https://github.com/Palid). + * Don't context switch room on SpaceStore ready as it can break permalinks ([\#6730](https://github.com/matrix-org/matrix-react-sdk/pull/6730)). Fixes vector-im/element-web#17974 and vector-im/element-web#17974. + * Fix explore rooms button not working during space creation wizard ([\#6729](https://github.com/matrix-org/matrix-react-sdk/pull/6729)). Fixes vector-im/element-web#18762 and vector-im/element-web#18762. + * Fix bug where one party's media would sometimes not be shown ([\#6731](https://github.com/matrix-org/matrix-react-sdk/pull/6731)). + * Only make the initial space rooms suggested by default ([\#6714](https://github.com/matrix-org/matrix-react-sdk/pull/6714)). Fixes vector-im/element-web#18760 and vector-im/element-web#18760. + * Replace fake username in EventTilePreview with a proper loading state ([\#6702](https://github.com/matrix-org/matrix-react-sdk/pull/6702)). Fixes vector-im/element-web#15897 and vector-im/element-web#15897. Contributed by [skolmer](https://github.com/skolmer). + * Don't send prehistorical events to widgets during decryption at startup ([\#6695](https://github.com/matrix-org/matrix-react-sdk/pull/6695)). Fixes vector-im/element-web#18060 and vector-im/element-web#18060. + * When creating subspaces properly set restricted join rule ([\#6725](https://github.com/matrix-org/matrix-react-sdk/pull/6725)). Fixes vector-im/element-web#18797 and vector-im/element-web#18797. + * Fix the Image View not openning for some pinned messages ([\#6723](https://github.com/matrix-org/matrix-react-sdk/pull/6723)). Fixes vector-im/element-web#18422 and vector-im/element-web#18422. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Show autocomplete sections vertically ([\#6722](https://github.com/matrix-org/matrix-react-sdk/pull/6722)). Fixes vector-im/element-web#18860 and vector-im/element-web#18860. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Fix EmojiPicker filtering to lower case emojibase data strings ([\#6717](https://github.com/matrix-org/matrix-react-sdk/pull/6717)). Fixes vector-im/element-web#18686 and vector-im/element-web#18686. + * Clear currentRoomId when viewing home page, fixing document title ([\#6716](https://github.com/matrix-org/matrix-react-sdk/pull/6716)). Fixes vector-im/element-web#18668 and vector-im/element-web#18668. + * Fix membership updates to Spaces not applying in real-time ([\#6713](https://github.com/matrix-org/matrix-react-sdk/pull/6713)). Fixes vector-im/element-web#18737 and vector-im/element-web#18737. + * Don't show a double stacked invite modals when inviting to Spaces ([\#6698](https://github.com/matrix-org/matrix-react-sdk/pull/6698)). Fixes vector-im/element-web#18745 and vector-im/element-web#18745. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Remove non-functional DuckDuckGo Autocomplete Provider ([\#6712](https://github.com/matrix-org/matrix-react-sdk/pull/6712)). Fixes vector-im/element-web#18778 and vector-im/element-web#18778. + * Filter members on `MemberList` load ([\#6708](https://github.com/matrix-org/matrix-react-sdk/pull/6708)). Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Fix improper voice messages being produced in Firefox and sometimes other browsers. ([\#6696](https://github.com/matrix-org/matrix-react-sdk/pull/6696)). Fixes vector-im/element-web#18587 and vector-im/element-web#18587. + * Fix client forgetting which capabilities a widget was approved for ([\#6685](https://github.com/matrix-org/matrix-react-sdk/pull/6685)). Fixes vector-im/element-web#18786 and vector-im/element-web#18786. + * Fix left panel widgets not remembering collapsed state ([\#6687](https://github.com/matrix-org/matrix-react-sdk/pull/6687)). Fixes vector-im/element-web#17803 and vector-im/element-web#17803. + * Fix changelog link colour back to blue ([\#6692](https://github.com/matrix-org/matrix-react-sdk/pull/6692)). Fixes vector-im/element-web#18726 and vector-im/element-web#18726. + * Soften codeblock border color ([\#6564](https://github.com/matrix-org/matrix-react-sdk/pull/6564)). Fixes vector-im/element-web#18367 and vector-im/element-web#18367. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Pause ringing more aggressively ([\#6691](https://github.com/matrix-org/matrix-react-sdk/pull/6691)). Fixes vector-im/element-web#18588 and vector-im/element-web#18588. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Fix command autocomplete ([\#6680](https://github.com/matrix-org/matrix-react-sdk/pull/6680)). Fixes vector-im/element-web#18670 and vector-im/element-web#18670. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Don't re-sort the room-list based on profile/status changes ([\#6595](https://github.com/matrix-org/matrix-react-sdk/pull/6595)). Fixes vector-im/element-web#110 and vector-im/element-web#110. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Fix codeblock formatting with syntax highlighting on ([\#6681](https://github.com/matrix-org/matrix-react-sdk/pull/6681)). Fixes vector-im/element-web#18739 vector-im/element-web#18365 and vector-im/element-web#18739. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Add padding to the Add button in the notification settings ([\#6665](https://github.com/matrix-org/matrix-react-sdk/pull/6665)). Fixes vector-im/element-web#18706 and vector-im/element-web#18706. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + Changes in [3.29.0](https://github.com/vector-im/element-desktop/releases/tag/v3.29.0) (2021-08-31) =================================================================================================== From 71b20608a29f8050979e11a30fb0920d56f74c7e Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 7 Sep 2021 18:28:33 +0100 Subject: [PATCH 03/37] v3.30.0-rc.1 --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index e02d683af2..4822f61955 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "3.29.0", + "version": "3.30.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.js", + "main": "./lib/index.js", "matrix_src_main": "./src/index.js", "matrix_lib_main": "./lib/index.js", "matrix_lib_typings": "./lib/index.d.ts", @@ -207,5 +207,6 @@ "coverageReporters": [ "text" ] - } + }, + "typings": "./lib/index.d.ts" } From 97e107ebacc4a99899120aa7f1d38f75e2be282b Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 7 Sep 2021 18:49:31 +0100 Subject: [PATCH 04/37] Fix types in release mode again --- src/audio/PlaybackQueue.ts | 4 +++- src/stores/widgets/StopGapWidgetDriver.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/audio/PlaybackQueue.ts b/src/audio/PlaybackQueue.ts index a4ffa1aabf..611b88938a 100644 --- a/src/audio/PlaybackQueue.ts +++ b/src/audio/PlaybackQueue.ts @@ -14,7 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { MatrixClient, MatrixEvent, Room } from "matrix-js-sdk"; +import { MatrixClient } from "matrix-js-sdk/src/client"; +import { MatrixEvent } from "matrix-js-sdk/src/models/event"; +import { Room } from "matrix-js-sdk/src/models/room"; import { Playback, PlaybackState } from "./Playback"; import { UPDATE_EVENT } from "../stores/AsyncStore"; import { MatrixClientPeg } from "../MatrixClientPeg"; diff --git a/src/stores/widgets/StopGapWidgetDriver.ts b/src/stores/widgets/StopGapWidgetDriver.ts index 91a4cf6642..058a605380 100644 --- a/src/stores/widgets/StopGapWidgetDriver.ts +++ b/src/stores/widgets/StopGapWidgetDriver.ts @@ -44,7 +44,7 @@ import { containsEmoji } from "../../effects/utils"; import dis from "../../dispatcher/dispatcher"; import { tryTransformPermalinkToLocalHref } from "../../utils/permalinks/Permalinks"; import { IEvent, MatrixEvent } from "matrix-js-sdk/src/models/event"; -import { Room } from "matrix-js-sdk"; +import { Room } from "matrix-js-sdk/src/models/room"; // TODO: Purge this from the universe From 329bc8a89e409e342364ff2bc9f3dc52797b7732 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 9 Sep 2021 13:14:05 +0100 Subject: [PATCH 05/37] Move unsent event badge handling into RoomNotificationState --- src/components/views/rooms/RoomTile.tsx | 49 ++++--------------- .../notifications/RoomNotificationState.ts | 14 +++++- 2 files changed, 23 insertions(+), 40 deletions(-) diff --git a/src/components/views/rooms/RoomTile.tsx b/src/components/views/rooms/RoomTile.tsx index 4d6de10e1f..8ed2ca85e9 100644 --- a/src/components/views/rooms/RoomTile.tsx +++ b/src/components/views/rooms/RoomTile.tsx @@ -17,7 +17,6 @@ limitations under the License. import React, { createRef } from "react"; import { Room } from "matrix-js-sdk/src/models/room"; -import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import classNames from "classnames"; import { RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex"; import AccessibleButton, { ButtonEvent } from "../../views/elements/AccessibleButton"; @@ -51,8 +50,6 @@ import IconizedContextMenu, { } from "../context_menus/IconizedContextMenu"; import { CommunityPrototypeStore, IRoomProfile } from "../../../stores/CommunityPrototypeStore"; import { replaceableComponent } from "../../../utils/replaceableComponent"; -import { getUnsentMessages } from "../../structures/RoomStatusBar"; -import { StaticNotificationState } from "../../../stores/notifications/StaticNotificationState"; interface IProps { room: Room; @@ -68,7 +65,6 @@ interface IState { notificationsMenuPosition: PartialDOMRect; generalMenuPosition: PartialDOMRect; messagePreview?: string; - hasUnsentEvents: boolean; } const messagePreviewId = (roomId: string) => `mx_RoomTile_messagePreview_${roomId}`; @@ -95,7 +91,6 @@ export default class RoomTile extends React.PureComponent { selected: ActiveRoomObserver.activeRoomId === this.props.room.roomId, notificationsMenuPosition: null, generalMenuPosition: null, - hasUnsentEvents: this.countUnsentEvents() > 0, // generatePreview() will return nothing if the user has previews disabled messagePreview: "", @@ -106,10 +101,6 @@ export default class RoomTile extends React.PureComponent { this.roomProps = EchoChamber.forRoom(this.props.room); } - private countUnsentEvents(): number { - return getUnsentMessages(this.props.room).length; - } - private onRoomNameUpdate = (room) => { this.forceUpdate(); }; @@ -118,11 +109,6 @@ export default class RoomTile extends React.PureComponent { this.forceUpdate(); // notification state changed - update }; - private onLocalEchoUpdated = (ev: MatrixEvent, room: Room) => { - if (room?.roomId !== this.props.room.roomId) return; - this.setState({ hasUnsentEvents: this.countUnsentEvents() > 0 }); - }; - private onRoomPropertyUpdate = (property: CachedRoomKey) => { if (property === CachedRoomKey.NotificationVolume) this.onNotificationUpdate(); // else ignore - not important for this tile @@ -183,7 +169,6 @@ export default class RoomTile extends React.PureComponent { CommunityPrototypeStore.getUpdateEventName(this.props.room.roomId), this.onCommunityUpdate, ); - MatrixClientPeg.get().on("Room.localEchoUpdated", this.onLocalEchoUpdated); } public componentWillUnmount() { @@ -208,7 +193,6 @@ export default class RoomTile extends React.PureComponent { CommunityPrototypeStore.getUpdateEventName(this.props.room.roomId), this.onCommunityUpdate, ); - MatrixClientPeg.get()?.removeListener("Room.localEchoUpdated", this.onLocalEchoUpdated); } private onAction = (payload: ActionPayload) => { @@ -587,30 +571,17 @@ export default class RoomTile extends React.PureComponent { />; let badge: React.ReactNode; - if (!this.props.isMinimized) { + if (!this.props.isMinimized && this.notificationState) { // aria-hidden because we summarise the unread count/highlight status in a manual aria-label below - if (this.state.hasUnsentEvents) { - // hardcode the badge to a danger state when there's unsent messages - badge = ( - - ); - } else if (this.notificationState) { - badge = ( - - ); - } + badge = ( + + ); } let messagePreview = null; diff --git a/src/stores/notifications/RoomNotificationState.ts b/src/stores/notifications/RoomNotificationState.ts index 3fadbe7d7a..0a2e801620 100644 --- a/src/stores/notifications/RoomNotificationState.ts +++ b/src/stores/notifications/RoomNotificationState.ts @@ -24,6 +24,7 @@ import { Room } from "matrix-js-sdk/src/models/room"; import * as RoomNotifs from '../../RoomNotifs'; import * as Unread from '../../Unread'; import { NotificationState } from "./NotificationState"; +import { getUnsentMessages } from "../../components/structures/RoomStatusBar"; export class RoomNotificationState extends NotificationState implements IDestroyable { constructor(public readonly room: Room) { @@ -32,6 +33,7 @@ export class RoomNotificationState extends NotificationState implements IDestroy this.room.on("Room.timeline", this.handleRoomEventUpdate); this.room.on("Room.redaction", this.handleRoomEventUpdate); this.room.on("Room.myMembership", this.handleMembershipUpdate); + this.room.on("Room.localEchoUpdated", this.handleLocalEchoUpdated); MatrixClientPeg.get().on("Event.decrypted", this.handleRoomEventUpdate); MatrixClientPeg.get().on("accountData", this.handleAccountDataUpdate); this.updateNotificationState(); @@ -47,12 +49,17 @@ export class RoomNotificationState extends NotificationState implements IDestroy this.room.removeListener("Room.timeline", this.handleRoomEventUpdate); this.room.removeListener("Room.redaction", this.handleRoomEventUpdate); this.room.removeListener("Room.myMembership", this.handleMembershipUpdate); + this.room.removeListener("Room.localEchoUpdated", this.handleLocalEchoUpdated); if (MatrixClientPeg.get()) { MatrixClientPeg.get().removeListener("Event.decrypted", this.handleRoomEventUpdate); MatrixClientPeg.get().removeListener("accountData", this.handleAccountDataUpdate); } } + private handleLocalEchoUpdated = () => { + this.updateNotificationState(); + }; + private handleReadReceipt = (event: MatrixEvent, room: Room) => { if (!readReceiptChangeIsFor(event, MatrixClientPeg.get())) return; // not our own - ignore if (room.roomId !== this.room.roomId) return; // not for us - ignore @@ -79,7 +86,12 @@ export class RoomNotificationState extends NotificationState implements IDestroy private updateNotificationState() { const snapshot = this.snapshot(); - if (RoomNotifs.getRoomNotifsState(this.room.roomId) === RoomNotifs.MUTE) { + if (getUnsentMessages(this.room).length > 0) { + // When there are unsent messages we show a red `!` + this._color = NotificationColor.Red; + this._symbol = "!"; + this._count = 1; // not used, technically + } else if (RoomNotifs.getRoomNotifsState(this.room.roomId) === RoomNotifs.MUTE) { // When muted we suppress all notification states, even if we have context on them. this._color = NotificationColor.None; this._symbol = null; From d9a0a0b8581307a15deae8ac92925dcf421b594c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 8 Sep 2021 11:26:54 -0600 Subject: [PATCH 06/37] Add config option to turn on in-room event sending timing metrics This is intended to be hooked up to an external system. Due to the extra events and metadata concerns, this is only available if turned on from the config. See `sendTimePerformanceMetrics.ts` for event schemas. --- src/ContentMessages.tsx | 11 +++++ .../views/rooms/SendMessageComposer.tsx | 10 ++++ src/sendTimePerformanceMetrics.ts | 48 +++++++++++++++++++ src/settings/Settings.tsx | 4 ++ 4 files changed, 73 insertions(+) create mode 100644 src/sendTimePerformanceMetrics.ts diff --git a/src/ContentMessages.tsx b/src/ContentMessages.tsx index 14a0c1ed51..40f8e307a5 100644 --- a/src/ContentMessages.tsx +++ b/src/ContentMessages.tsx @@ -39,6 +39,8 @@ import { import { IUpload } from "./models/IUpload"; import { IAbortablePromise, IImageInfo } from "matrix-js-sdk/src/@types/partials"; import { BlurhashEncoder } from "./BlurhashEncoder"; +import SettingsStore from "./settings/SettingsStore"; +import { decorateStartSendingTime, sendRoundTripMetric } from "./sendTimePerformanceMetrics"; const MAX_WIDTH = 800; const MAX_HEIGHT = 600; @@ -539,6 +541,10 @@ export default class ContentMessages { msgtype: "", // set later }; + if (SettingsStore.getValue("Performance.addSendMessageTimingMetadata")) { + decorateStartSendingTime(content); + } + // if we have a mime type for the file, add it to the message metadata if (file.type) { content.info.mimetype = file.type; @@ -614,6 +620,11 @@ export default class ContentMessages { }).then(function() { if (upload.canceled) throw new UploadCanceledError(); const prom = matrixClient.sendMessage(roomId, content); + if (SettingsStore.getValue("Performance.addSendMessageTimingMetadata")) { + prom.then(resp => { + sendRoundTripMetric(matrixClient, roomId, resp.event_id); + }); + } CountlyAnalytics.instance.trackSendMessage(startTime, prom, roomId, false, false, content); return prom; }, function(err) { diff --git a/src/components/views/rooms/SendMessageComposer.tsx b/src/components/views/rooms/SendMessageComposer.tsx index aca397b6b2..bb5d537895 100644 --- a/src/components/views/rooms/SendMessageComposer.tsx +++ b/src/components/views/rooms/SendMessageComposer.tsx @@ -54,6 +54,7 @@ import { Room } from 'matrix-js-sdk/src/models/room'; import ErrorDialog from "../dialogs/ErrorDialog"; import QuestionDialog from "../dialogs/QuestionDialog"; import { ActionPayload } from "../../../dispatcher/payloads"; +import { decorateStartSendingTime, sendRoundTripMetric } from "../../../sendTimePerformanceMetrics"; function addReplyToMessageContent( content: IContent, @@ -418,6 +419,10 @@ export default class SendMessageComposer extends React.Component { // don't bother sending an empty message if (!content.body.trim()) return; + if (SettingsStore.getValue("Performance.addSendMessageTimingMetadata")) { + decorateStartSendingTime(content); + } + const prom = this.context.sendMessage(roomId, content); if (replyToEvent) { // Clear reply_to_event as we put the message into the queue @@ -433,6 +438,11 @@ export default class SendMessageComposer extends React.Component { dis.dispatch({ action: `effects.${effect.command}` }); } }); + if (SettingsStore.getValue("Performance.addSendMessageTimingMetadata")) { + prom.then(resp => { + sendRoundTripMetric(this.context, roomId, resp.event_id); + }); + } CountlyAnalytics.instance.trackSendMessage(startTime, prom, roomId, false, !!replyToEvent, content); } diff --git a/src/sendTimePerformanceMetrics.ts b/src/sendTimePerformanceMetrics.ts new file mode 100644 index 0000000000..ef461db939 --- /dev/null +++ b/src/sendTimePerformanceMetrics.ts @@ -0,0 +1,48 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { MatrixClient } from "matrix-js-sdk"; + +/** + * Decorates the given event content object with the "send start time". The + * object will be modified in-place. + * @param {object} content The event content. + */ +export function decorateStartSendingTime(content: object) { + content['io.element.performance_metrics'] = { + sendStartTs: Date.now(), + }; +} + +/** + * Called when an event decorated with `decorateStartSendingTime()` has been sent + * by the server (the client now knows the event ID). + * @param {MatrixClient} client The client to send as. + * @param {string} inRoomId The room ID where the original event was sent. + * @param {string} forEventId The event ID for the decorated event. + */ +export function sendRoundTripMetric(client: MatrixClient, inRoomId: string, forEventId: string) { + // noinspection JSIgnoredPromiseFromCall + client.sendEvent(inRoomId, 'io.element.performance_metric', { + // XXX: We stick all of this into `m.relates_to` so it doesn't end up encrypted. + "m.relates_to": { + rel_type: "io.element.metric", + event_id: forEventId, + responseTs: Date.now(), + kind: 'send_time', + } as any, // override types because we're actually allowed to add extra metadata to relates_to + }); +} diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index 40f57a0a1c..6dbefd4b8e 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -759,6 +759,10 @@ export const SETTINGS: {[setting: string]: ISetting} = { default: true, controller: new ReducedMotionController(), }, + "Performance.addSendMessageTimingMetadata": { + supportedLevels: [SettingLevel.CONFIG], + default: false, + }, "Widgets.pinned": { // deprecated supportedLevels: LEVELS_ROOM_OR_ACCOUNT, default: {}, From 0cae60ed2c5d4306c9cd174174c2a8073cbfc0a4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 8 Sep 2021 11:31:37 -0600 Subject: [PATCH 07/37] Move fields into consistent location for js-sdk to target --- src/sendTimePerformanceMetrics.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/sendTimePerformanceMetrics.ts b/src/sendTimePerformanceMetrics.ts index ef461db939..a8846d3cbf 100644 --- a/src/sendTimePerformanceMetrics.ts +++ b/src/sendTimePerformanceMetrics.ts @@ -37,12 +37,10 @@ export function decorateStartSendingTime(content: object) { export function sendRoundTripMetric(client: MatrixClient, inRoomId: string, forEventId: string) { // noinspection JSIgnoredPromiseFromCall client.sendEvent(inRoomId, 'io.element.performance_metric', { - // XXX: We stick all of this into `m.relates_to` so it doesn't end up encrypted. - "m.relates_to": { - rel_type: "io.element.metric", - event_id: forEventId, + "io.element.performance_metrics": { + forEventId: forEventId, responseTs: Date.now(), kind: 'send_time', - } as any, // override types because we're actually allowed to add extra metadata to relates_to + }, }); } From d886409c0c5026a5fe836d88d66b048e4fb50157 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 8 Sep 2021 11:35:25 -0600 Subject: [PATCH 08/37] Appease the linter --- src/sendTimePerformanceMetrics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sendTimePerformanceMetrics.ts b/src/sendTimePerformanceMetrics.ts index a8846d3cbf..ee5caa05a9 100644 --- a/src/sendTimePerformanceMetrics.ts +++ b/src/sendTimePerformanceMetrics.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { MatrixClient } from "matrix-js-sdk"; +import { MatrixClient } from "matrix-js-sdk/src"; /** * Decorates the given event content object with the "send start time". The From eba815afda03225957957283242cf9ca86d0c6cc Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 9 Sep 2021 15:58:19 +0100 Subject: [PATCH 09/37] Debounce read marker update on scroll Reverts https://github.com/matrix-org/matrix-react-sdk/pull/6751 in favour of debouncing the updates to read markers, because it seems allowing the scroll to be 1px away from the bottom was important for some browsers and meant they never got to the bottom. We can fix the problem instead by debouncing the update to read markers, because the scroll state gets reset back to the bottom when componentDidUpdate() runs which happens after the read marker code does a setState(). This should probably be debounced anyway since it doesn't need to be run that frequently. Fixes https://github.com/vector-im/element-web/issues/18961 Type: bugfix --- src/components/structures/ScrollPanel.tsx | 2 +- src/components/structures/TimelinePanel.tsx | 42 ++++++++++++++------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/components/structures/ScrollPanel.tsx b/src/components/structures/ScrollPanel.tsx index abc71bfcb2..193553361d 100644 --- a/src/components/structures/ScrollPanel.tsx +++ b/src/components/structures/ScrollPanel.tsx @@ -276,7 +276,7 @@ export default class ScrollPanel extends React.Component { // for scrollTop happen on certain browsers/platforms // when scrolled all the way down. E.g. Chrome 72 on debian. // so check difference < 1; - return Math.abs(sn.scrollHeight - (sn.scrollTop + sn.clientHeight)) < 1; + return Math.abs(sn.scrollHeight - (sn.scrollTop + sn.clientHeight)) <= 1; }; // returns the vertical height in the given direction that can be removed from diff --git a/src/components/structures/TimelinePanel.tsx b/src/components/structures/TimelinePanel.tsx index e5fa6967dc..0dfb5c414a 100644 --- a/src/components/structures/TimelinePanel.tsx +++ b/src/components/structures/TimelinePanel.tsx @@ -47,11 +47,14 @@ import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks"; import Spinner from "../views/elements/Spinner"; import EditorStateTransfer from '../../utils/EditorStateTransfer'; import ErrorDialog from '../views/dialogs/ErrorDialog'; +import { debounce } from 'lodash'; const PAGINATE_SIZE = 20; const INITIAL_SIZE = 20; const READ_RECEIPT_INTERVAL_MS = 500; +const READ_MARKER_DEBOUNCE_MS = 100; + const DEBUG = false; let debuglog = function(...s: any[]) {}; @@ -475,22 +478,35 @@ class TimelinePanel extends React.Component { } if (this.props.manageReadMarkers) { - const rmPosition = this.getReadMarkerPosition(); - // we hide the read marker when it first comes onto the screen, but if - // it goes back off the top of the screen (presumably because the user - // clicks on the 'jump to bottom' button), we need to re-enable it. - if (rmPosition < 0) { - this.setState({ readMarkerVisible: true }); - } - - // if read marker position goes between 0 and -1/1, - // (and user is active), switch timeout - const timeout = this.readMarkerTimeout(rmPosition); - // NO-OP when timeout already has set to the given value - this.readMarkerActivityTimer.changeTimeout(timeout); + this.doManageReadMarkers(); } }; + /* + * Debounced function to manage read markers because we don't need to + * do this on every tiny scroll update. It also sets state which causes + * a component update, which can in turn reset the scroll position, so + * it's important we allow the browser to scroll a bit before running this + * (hence trailing edge only and debounce rather than throttle because + * we really only need to update this once the user has finished scrolling, + * not periodically while they scroll). + */ + private doManageReadMarkers = debounce(() => { + const rmPosition = this.getReadMarkerPosition(); + // we hide the read marker when it first comes onto the screen, but if + // it goes back off the top of the screen (presumably because the user + // clicks on the 'jump to bottom' button), we need to re-enable it. + if (rmPosition < 0) { + this.setState({ readMarkerVisible: true }); + } + + // if read marker position goes between 0 and -1/1, + // (and user is active), switch timeout + const timeout = this.readMarkerTimeout(rmPosition); + // NO-OP when timeout already has set to the given value + this.readMarkerActivityTimer.changeTimeout(timeout); + }, READ_MARKER_DEBOUNCE_MS, { leading: false, trailing: true }); + private onAction = (payload: ActionPayload): void => { switch (payload.action) { case "ignore_state_changed": From da06c8a5d89d4ae05a8ac5d42a0f581fe4bc5486 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 9 Sep 2021 18:15:51 +0100 Subject: [PATCH 10/37] Update comment too Co-authored-by: Travis Ralston --- src/components/structures/ScrollPanel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/ScrollPanel.tsx b/src/components/structures/ScrollPanel.tsx index 193553361d..112f8d2c21 100644 --- a/src/components/structures/ScrollPanel.tsx +++ b/src/components/structures/ScrollPanel.tsx @@ -275,7 +275,7 @@ export default class ScrollPanel extends React.Component { // fractional values (both too big and too small) // for scrollTop happen on certain browsers/platforms // when scrolled all the way down. E.g. Chrome 72 on debian. - // so check difference < 1; + // so check difference <= 1; return Math.abs(sn.scrollHeight - (sn.scrollTop + sn.clientHeight)) <= 1; }; From 26aa9743eea6b617bed778fd7890e4f368bcf783 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Thu, 9 Sep 2021 18:28:58 +0100 Subject: [PATCH 11/37] Prepare changelog for v3.30.0-rc.2 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20812ae052..a660b17301 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +Changes in [3.30.0-rc.2](https://github.com/vector-im/element-desktop/releases/tag/v3.30.0-rc.2) (2021-09-09) +============================================================================================================= + +## ✨ Features + * [Release] Add config option to turn on in-room event sending timing metrics ([\#6773](https://github.com/matrix-org/matrix-react-sdk/pull/6773)). + +## 🐛 Bug Fixes + * Debounce read marker update on scroll ([\#6774](https://github.com/matrix-org/matrix-react-sdk/pull/6774)). + Changes in [3.30.0-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v3.30.0-rc.1) (2021-09-07) ============================================================================================================= From a5e2877862e8839e9291c1f9180b9df5887adb25 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Thu, 9 Sep 2021 18:28:58 +0100 Subject: [PATCH 12/37] v3.30.0-rc.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4822f61955..d1e6040cd5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "3.30.0-rc.1", + "version": "3.30.0-rc.2", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From bbe714257ee57207b05aa592a025edcf098a030b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 10 Sep 2021 09:15:54 +0100 Subject: [PATCH 13/37] Show unsent message warning on Space panel button --- .../views/rooms/NotificationBadge.tsx | 39 +++++++++++++++++-- .../views/spaces/SpaceTreeLevel.tsx | 1 + src/i18n/strings/en_EN.json | 1 + src/stores/notifications/NotificationColor.ts | 1 + .../notifications/RoomNotificationState.ts | 2 +- .../notifications/SpaceNotificationState.ts | 8 ++-- 6 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/components/views/rooms/NotificationBadge.tsx b/src/components/views/rooms/NotificationBadge.tsx index 8329de7391..a70ff93bd2 100644 --- a/src/components/views/rooms/NotificationBadge.tsx +++ b/src/components/views/rooms/NotificationBadge.tsx @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React from "react"; +import React, { MouseEvent } from "react"; import classNames from "classnames"; import { formatCount } from "../../../utils/FormattingUtils"; import SettingsStore from "../../../settings/SettingsStore"; @@ -22,6 +22,9 @@ import AccessibleButton from "../elements/AccessibleButton"; import { XOR } from "../../../@types/common"; import { NOTIFICATION_STATE_UPDATE, NotificationState } from "../../../stores/notifications/NotificationState"; import { replaceableComponent } from "../../../utils/replaceableComponent"; +import Tooltip from "../elements/Tooltip"; +import { _t } from "../../../languageHandler"; +import { NotificationColor } from "../../../stores/notifications/NotificationColor"; interface IProps { notification: NotificationState; @@ -39,6 +42,7 @@ interface IProps { } interface IClickableProps extends IProps, React.InputHTMLAttributes { + showUnsentTooltip?: boolean; /** * If specified will return an AccessibleButton instead of a div. */ @@ -47,6 +51,7 @@ interface IClickableProps extends IProps, React.InputHTMLAttributes { interface IState { showCounts: boolean; // whether or not to show counts. Independent of props.forceCount + showTooltip: boolean; } @replaceableComponent("views.rooms.NotificationBadge") @@ -59,6 +64,7 @@ export default class NotificationBadge extends React.PureComponent { + e.stopPropagation(); + this.setState({ + showTooltip: true, + }); + }; + + private onMouseLeave = () => { + this.setState({ + showTooltip: false, + }); + }; + public render(): React.ReactElement { /* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */ - const { notification, forceCount, roomId, onClick, ...props } = this.props; + const { notification, showUnsentTooltip, forceCount, roomId, onClick, ...props } = this.props; // Don't show a badge if we don't need to if (notification.isIdle) return null; @@ -124,9 +143,23 @@ export default class NotificationBadge extends React.PureComponent + ); + } + return ( - + { symbol } + { tooltip } ); } diff --git a/src/components/views/spaces/SpaceTreeLevel.tsx b/src/components/views/spaces/SpaceTreeLevel.tsx index dda58ae944..f9d901a298 100644 --- a/src/components/views/spaces/SpaceTreeLevel.tsx +++ b/src/components/views/spaces/SpaceTreeLevel.tsx @@ -93,6 +93,7 @@ export const SpaceButton: React.FC = ({ notification={notificationState} aria-label={ariaLabel} tabIndex={tabIndex} + showUnsentTooltip={true} /> ; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index deb854868f..ff5eb29f99 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1587,6 +1587,7 @@ "Your private messages are normally encrypted, but this room isn't. Usually this is due to an unsupported device or method being used, like email invites.": "Your private messages are normally encrypted, but this room isn't. Usually this is due to an unsupported device or method being used, like email invites.", "Enable encryption in settings.": "Enable encryption in settings.", "End-to-end encryption isn't enabled": "End-to-end encryption isn't enabled", + "Message didn't send. Click for info.": "Message didn't send. Click for info.", "Unpin": "Unpin", "View message": "View message", "%(duration)ss": "%(duration)ss", diff --git a/src/stores/notifications/NotificationColor.ts b/src/stores/notifications/NotificationColor.ts index b12f2b7c00..fadd5ac67e 100644 --- a/src/stores/notifications/NotificationColor.ts +++ b/src/stores/notifications/NotificationColor.ts @@ -21,4 +21,5 @@ export enum NotificationColor { Bold, // no badge, show as unread Grey, // unread notified messages Red, // unread pings + Unsent, // some messages failed to send } diff --git a/src/stores/notifications/RoomNotificationState.ts b/src/stores/notifications/RoomNotificationState.ts index 0a2e801620..d0479200bd 100644 --- a/src/stores/notifications/RoomNotificationState.ts +++ b/src/stores/notifications/RoomNotificationState.ts @@ -88,7 +88,7 @@ export class RoomNotificationState extends NotificationState implements IDestroy if (getUnsentMessages(this.room).length > 0) { // When there are unsent messages we show a red `!` - this._color = NotificationColor.Red; + this._color = NotificationColor.Unsent; this._symbol = "!"; this._count = 1; // not used, technically } else if (RoomNotifs.getRoomNotifsState(this.room.roomId) === RoomNotifs.MUTE) { diff --git a/src/stores/notifications/SpaceNotificationState.ts b/src/stores/notifications/SpaceNotificationState.ts index f8eb07251b..c414a01fc2 100644 --- a/src/stores/notifications/SpaceNotificationState.ts +++ b/src/stores/notifications/SpaceNotificationState.ts @@ -30,10 +30,6 @@ export class SpaceNotificationState extends NotificationState { super(); } - public get symbol(): string { - return null; // This notification state doesn't support symbols - } - public setRooms(rooms: Room[]) { const oldRooms = this.rooms; const diff = arrayDiff(oldRooms, rooms); @@ -54,7 +50,7 @@ export class SpaceNotificationState extends NotificationState { } public getFirstRoomWithNotifications() { - return this.rooms.find((room) => room.getUnreadNotificationCount() > 0).roomId; + return Object.values(this.states).find(state => state.color >= this.color)?.room.roomId; } public destroy() { @@ -79,6 +75,8 @@ export class SpaceNotificationState extends NotificationState { this._color = Math.max(this.color, state.color); } + this._symbol = this._color === NotificationColor.Unsent ? "!" : null; + // finally, publish an update if needed this.emitIfUpdated(snapshot); } From aff9be6120a0714532f6675b1aa7b5afc63cbebf Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 10 Sep 2021 10:58:13 +0100 Subject: [PATCH 14/37] Surface unsent messages on the sublist notification badge too --- src/components/views/rooms/NotificationBadge.tsx | 9 +++++---- src/components/views/rooms/RoomSublist.tsx | 1 + src/stores/notifications/ListNotificationState.ts | 9 +++++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/components/views/rooms/NotificationBadge.tsx b/src/components/views/rooms/NotificationBadge.tsx index a70ff93bd2..a97d51fc90 100644 --- a/src/components/views/rooms/NotificationBadge.tsx +++ b/src/components/views/rooms/NotificationBadge.tsx @@ -143,15 +143,16 @@ export default class NotificationBadge extends React.PureComponent - ); + label = _t("Message didn't send. Click for info."); + tooltip = ; } return ( { onClick={this.onBadgeClick} tabIndex={tabIndex} aria-label={ariaLabel} + showUnsentTooltip={true} /> ); diff --git a/src/stores/notifications/ListNotificationState.ts b/src/stores/notifications/ListNotificationState.ts index 6c67dbdd08..4168fe80b6 100644 --- a/src/stores/notifications/ListNotificationState.ts +++ b/src/stores/notifications/ListNotificationState.ts @@ -31,10 +31,6 @@ export class ListNotificationState extends NotificationState { super(); } - public get symbol(): string { - return null; // This notification state doesn't support symbols - } - public setRooms(rooms: Room[]) { // If we're only concerned about the tile count, don't bother setting up listeners. if (this.byTileCount) { @@ -82,6 +78,7 @@ export class ListNotificationState extends NotificationState { private calculateTotalState() { const snapshot = this.snapshot(); + this._symbol = null; if (this.byTileCount) { this._color = NotificationColor.Red; this._count = this.rooms.length; @@ -92,6 +89,10 @@ export class ListNotificationState extends NotificationState { this._count += state.count; this._color = Math.max(this.color, state.color); } + + if (this._color === NotificationColor.Unsent) { + this._symbol = "!"; + } } // finally, publish an update if needed From 9a8a45382744f26ed42e43873464ee4e0805e8b1 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 10 Sep 2021 11:09:46 +0100 Subject: [PATCH 15/37] tidy --- src/stores/notifications/ListNotificationState.ts | 9 ++++----- src/stores/notifications/SpaceNotificationState.ts | 7 ++++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/stores/notifications/ListNotificationState.ts b/src/stores/notifications/ListNotificationState.ts index 4168fe80b6..97ba2bd80b 100644 --- a/src/stores/notifications/ListNotificationState.ts +++ b/src/stores/notifications/ListNotificationState.ts @@ -31,6 +31,10 @@ export class ListNotificationState extends NotificationState { super(); } + public get symbol(): string { + return this._color === NotificationColor.Unsent ? "!" : null; + } + public setRooms(rooms: Room[]) { // If we're only concerned about the tile count, don't bother setting up listeners. if (this.byTileCount) { @@ -78,7 +82,6 @@ export class ListNotificationState extends NotificationState { private calculateTotalState() { const snapshot = this.snapshot(); - this._symbol = null; if (this.byTileCount) { this._color = NotificationColor.Red; this._count = this.rooms.length; @@ -89,10 +92,6 @@ export class ListNotificationState extends NotificationState { this._count += state.count; this._color = Math.max(this.color, state.color); } - - if (this._color === NotificationColor.Unsent) { - this._symbol = "!"; - } } // finally, publish an update if needed diff --git a/src/stores/notifications/SpaceNotificationState.ts b/src/stores/notifications/SpaceNotificationState.ts index c414a01fc2..137b2ca0f2 100644 --- a/src/stores/notifications/SpaceNotificationState.ts +++ b/src/stores/notifications/SpaceNotificationState.ts @@ -30,6 +30,10 @@ export class SpaceNotificationState extends NotificationState { super(); } + public get symbol(): string { + return this._color === NotificationColor.Unsent ? "!" : null; + } + public setRooms(rooms: Room[]) { const oldRooms = this.rooms; const diff = arrayDiff(oldRooms, rooms); @@ -75,10 +79,7 @@ export class SpaceNotificationState extends NotificationState { this._color = Math.max(this.color, state.color); } - this._symbol = this._color === NotificationColor.Unsent ? "!" : null; - // finally, publish an update if needed this.emitIfUpdated(snapshot); } } - From 6fcd930d0b49e565c506f556b12e0f5d5d04c79b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 10 Sep 2021 11:54:25 +0100 Subject: [PATCH 16/37] fix unrelated issues --- .../views/settings/tabs/room/SecurityRoomSettingsTab.tsx | 2 +- src/components/views/spaces/SpaceSettingsVisibilityTab.tsx | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx index b467dc7680..d1c5bc8448 100644 --- a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx @@ -425,7 +425,7 @@ export default class SecurityRoomSettingsTab extends React.Component state.getJoinRule()); const [guestAccessEnabled, setGuestAccessEnabled] = useLocalEcho( () => space.currentState.getStateEvents(EventType.RoomGuestAccess, "") ?.getContent()?.guest_access === GuestAccess.CanJoin, @@ -64,7 +66,7 @@ const SpaceSettingsVisibilityTab = ({ matrixClient: cli, space, closeSettingsFn const canonicalAliasEv = space.currentState.getStateEvents(EventType.RoomCanonicalAlias, ""); let advancedSection; - if (visibility === SpaceVisibility.Unlisted) { + if (joinRule === JoinRule.Public) { if (showAdvancedSection) { advancedSection = <> From d75820a491667bd63645192cdf1ccf4d69afa411 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 13 Sep 2021 13:49:24 +0100 Subject: [PATCH 17/37] Hide mute/unmute button in UserInfo for Spaces as it makes no sense --- src/components/views/right_panel/UserInfo.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/right_panel/UserInfo.tsx b/src/components/views/right_panel/UserInfo.tsx index f90643f1df..4446ee1415 100644 --- a/src/components/views/right_panel/UserInfo.tsx +++ b/src/components/views/right_panel/UserInfo.tsx @@ -826,7 +826,7 @@ const RoomAdminToolsContainer: React.FC = ({ if (canAffectUser && me.powerLevel >= banPowerLevel) { banButton = ; } - if (canAffectUser && me.powerLevel >= editPowerLevel) { + if (canAffectUser && me.powerLevel >= editPowerLevel && !room.isSpaceRoom()) { muteButton = ( Date: Mon, 13 Sep 2021 16:27:46 +0100 Subject: [PATCH 18/37] Fix broken edge case with public space creation with no alias --- .../views/spaces/SpaceCreateMenu.tsx | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/components/views/spaces/SpaceCreateMenu.tsx b/src/components/views/spaces/SpaceCreateMenu.tsx index 59c970c7d0..4afc44cfdf 100644 --- a/src/components/views/spaces/SpaceCreateMenu.tsx +++ b/src/components/views/spaces/SpaceCreateMenu.tsx @@ -97,9 +97,8 @@ const spaceNameValidator = withValidation({ ], }); -const nameToAlias = (name: string, domain: string): string => { - const localpart = name.trim().toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9_-]+/gi, ""); - return `#${localpart}:${domain}`; +const nameToLocalpart = (name: string): string => { + return name.trim().toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9_-]+/gi, ""); }; // XXX: Temporary for the Spaces release only @@ -176,8 +175,8 @@ export const SpaceCreateForm: React.FC = ({ value={name} onChange={ev => { const newName = ev.target.value; - if (!alias || alias === nameToAlias(name, domain)) { - setAlias(nameToAlias(newName, domain)); + if (!alias || alias === `#${nameToLocalpart(name)}:${domain}`) { + setAlias(`#${nameToLocalpart(newName)}:${domain}`); } setName(newName); }} @@ -194,7 +193,7 @@ export const SpaceCreateForm: React.FC = ({ onChange={setAlias} domain={domain} value={alias} - placeholder={name ? nameToAlias(name, domain) : _t("e.g. my-space")} + placeholder={name ? nameToLocalpart(name) : _t("e.g. my-space")} label={_t("Address")} disabled={busy} onKeyDown={onKeyDown} @@ -217,6 +216,7 @@ export const SpaceCreateForm: React.FC = ({ }; const SpaceCreateMenu = ({ onFinished }) => { + const cli = useContext(MatrixClientContext); const [visibility, setVisibility] = useState(null); const [busy, setBusy] = useState(false); @@ -233,14 +233,18 @@ const SpaceCreateMenu = ({ onFinished }) => { setBusy(true); // require & validate the space name field - if (!await spaceNameField.current.validate({ allowEmpty: false })) { + if (!(await spaceNameField.current.validate({ allowEmpty: false }))) { spaceNameField.current.focus(); spaceNameField.current.validate({ allowEmpty: false, focused: true }); setBusy(false); return; } - // validate the space name alias field but do not require it - if (visibility === Visibility.Public && !await spaceAliasField.current.validate({ allowEmpty: true })) { + + // validate the space alias field but do not require it + const aliasLocalpart = alias.substring(1, alias.length - cli.getDomain().length - 1); + if (visibility === Visibility.Public && aliasLocalpart && + (await spaceAliasField.current.validate({ allowEmpty: true })) === false + ) { spaceAliasField.current.focus(); spaceAliasField.current.validate({ allowEmpty: true, focused: true }); setBusy(false); @@ -248,7 +252,13 @@ const SpaceCreateMenu = ({ onFinished }) => { } try { - await createSpace(name, visibility === Visibility.Public, alias, topic, avatar); + await createSpace( + name, + visibility === Visibility.Public, + aliasLocalpart ? alias : undefined, + topic, + avatar, + ); onFinished(); } catch (e) { From 4a470e43410001c213c29b2f032b258e64861867 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 13 Sep 2021 17:15:52 +0100 Subject: [PATCH 19/37] Fix automatic field population in space create menu not validating --- src/components/views/spaces/SpaceCreateMenu.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/spaces/SpaceCreateMenu.tsx b/src/components/views/spaces/SpaceCreateMenu.tsx index 59c970c7d0..9e1f8a3b62 100644 --- a/src/components/views/spaces/SpaceCreateMenu.tsx +++ b/src/components/views/spaces/SpaceCreateMenu.tsx @@ -178,6 +178,7 @@ export const SpaceCreateForm: React.FC = ({ const newName = ev.target.value; if (!alias || alias === nameToAlias(name, domain)) { setAlias(nameToAlias(newName, domain)); + aliasFieldRef.current.validate({ allowEmpty: true }); } setName(newName); }} From e913f03a6773c320d409fae6ac09901632748acc Mon Sep 17 00:00:00 2001 From: Dariusz Niemczyk Date: Mon, 13 Sep 2021 22:11:43 +0200 Subject: [PATCH 20/37] Add missing types --- src/components/structures/ContextMenu.tsx | 14 ++++++++++++-- src/components/views/rooms/MessageComposer.tsx | 3 ++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx index 332b6cd318..d503e56a6d 100644 --- a/src/components/structures/ContextMenu.tsx +++ b/src/components/structures/ContextMenu.tsx @@ -404,17 +404,27 @@ export class ContextMenu extends React.PureComponent { } } +export type ToRightOf = { + left: number; + top: number; + chevronOffset: number; +}; + // Placement method for to position context menu to right of elementRect with chevronOffset -export const toRightOf = (elementRect: Pick, chevronOffset = 12) => { +export const toRightOf = (elementRect: Pick, chevronOffset = 12): ToRightOf => { const left = elementRect.right + window.pageXOffset + 3; let top = elementRect.top + (elementRect.height / 2) + window.pageYOffset; top -= chevronOffset + 8; // where 8 is half the height of the chevron return { left, top, chevronOffset }; }; +export type AboveLeftOf = IPosition & { + chevronFace: ChevronFace; +}; + // Placement method for to position context menu right-aligned and flowing to the left of elementRect, // and either above or below: wherever there is more space (maybe this should be aboveOrBelowLeftOf?) -export const aboveLeftOf = (elementRect: DOMRect, chevronFace = ChevronFace.None, vPadding = 0) => { +export const aboveLeftOf = (elementRect: DOMRect, chevronFace = ChevronFace.None, vPadding = 0): AboveLeftOf => { const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace }; const buttonRight = elementRect.right + window.pageXOffset; diff --git a/src/components/views/rooms/MessageComposer.tsx b/src/components/views/rooms/MessageComposer.tsx index dd6ce10825..506bf09a92 100644 --- a/src/components/views/rooms/MessageComposer.tsx +++ b/src/components/views/rooms/MessageComposer.tsx @@ -32,6 +32,7 @@ import { ContextMenu, useContextMenu, MenuItem, + AboveLeftOf, } from "../../structures/ContextMenu"; import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; import ReplyPreview from "./ReplyPreview"; @@ -511,7 +512,7 @@ export default class MessageComposer extends React.Component { null, ]; - let menuPosition; + let menuPosition: AboveLeftOf | undefined; if (this.ref.current) { const contentRect = this.ref.current.getBoundingClientRect(); menuPosition = aboveLeftOf(contentRect); From ceafa833929d0d1a3474b65a167766fcfa349b83 Mon Sep 17 00:00:00 2001 From: Dariusz Niemczyk Date: Mon, 13 Sep 2021 22:11:58 +0200 Subject: [PATCH 21/37] Fix invalid ContextualMenu positions --- src/components/structures/ContextMenu.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx index d503e56a6d..0c2c0e207f 100644 --- a/src/components/structures/ContextMenu.tsx +++ b/src/components/structures/ContextMenu.tsx @@ -322,10 +322,11 @@ export class ContextMenu extends React.PureComponent { const menuClasses = classNames({ 'mx_ContextualMenu': true, - 'mx_ContextualMenu_left': !hasChevron && position.left, - 'mx_ContextualMenu_right': !hasChevron && position.right, - 'mx_ContextualMenu_top': !hasChevron && position.top, - 'mx_ContextualMenu_bottom': !hasChevron && position.bottom, + // Defensively check for counter cases + 'mx_ContextualMenu_left': !hasChevron && position.left !== undefined && !position.right, + 'mx_ContextualMenu_right': !hasChevron && position.right !== undefined && !position.left, + 'mx_ContextualMenu_top': !hasChevron && position.top !== undefined && !position.bottom, + 'mx_ContextualMenu_bottom': !hasChevron && position.bottom !== undefined && !position.top, 'mx_ContextualMenu_withChevron_left': chevronFace === ChevronFace.Left, 'mx_ContextualMenu_withChevron_right': chevronFace === ChevronFace.Right, 'mx_ContextualMenu_withChevron_top': chevronFace === ChevronFace.Top, From 87c9551507a06803e5809d3930052e3693e4207e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 14 Sep 2021 12:49:18 +0100 Subject: [PATCH 22/37] Fix edge cases around joining new room which does not belong to active space --- src/stores/SpaceStore.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/stores/SpaceStore.tsx b/src/stores/SpaceStore.tsx index f49d51454b..eebc196f4c 100644 --- a/src/stores/SpaceStore.tsx +++ b/src/stores/SpaceStore.tsx @@ -629,11 +629,18 @@ export class SpaceStoreClass extends AsyncStoreWithClient { }; private onRoom = (room: Room, newMembership?: string, oldMembership?: string) => { - const membership = newMembership || room.getMyMembership(); + const roomMembership = room.getMyMembership(); + if (roomMembership === null) { + // room is still being baked in the js-sdk, we'll process it at Room.myMembership instead + return; + } + const membership = newMembership || roomMembership; if (!room.isSpaceRoom()) { // this.onRoomUpdate(room); - this.onRoomsUpdate(); + // this.onRoomsUpdate(); + // ideally we only need onRoomsUpdate here but it doesn't rebuild parentMap so always adds new rooms to Home + this.rebuild(); if (membership === "join") { // the user just joined a room, remove it from the suggested list if it was there From 527e1eb462b476c2849854e29e6c328df9f0c702 Mon Sep 17 00:00:00 2001 From: Dariusz Niemczyk Date: Tue, 14 Sep 2021 14:45:47 +0200 Subject: [PATCH 23/37] Fix autocomplete not having y-scroll After changing flex-order the children did not have a max-height which ended up in the child growing to outside of the screen instead of being properly constrained. Fix https://github.com/vector-im/element-web/issues/18997 --- res/css/views/rooms/_Autocomplete.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/rooms/_Autocomplete.scss b/res/css/views/rooms/_Autocomplete.scss index 8d2b338d9d..fcdab37f5a 100644 --- a/res/css/views/rooms/_Autocomplete.scss +++ b/res/css/views/rooms/_Autocomplete.scss @@ -7,7 +7,6 @@ background: $background; border-bottom: none; border-radius: 8px 8px 0 0; - max-height: 35vh; overflow: clip; display: flex; flex-direction: column; @@ -64,6 +63,7 @@ margin: 12px; height: 100%; overflow-y: scroll; + max-height: 35vh; } .mx_Autocomplete_Completion_container_truncate { From 60174c9836aa1c6a7da2b1a8625790ddbd7d5bfb Mon Sep 17 00:00:00 2001 From: Dariusz Niemczyk Date: Tue, 14 Sep 2021 14:51:17 +0200 Subject: [PATCH 24/37] Add a better comment describing the behavior --- src/components/structures/ContextMenu.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx index 0c2c0e207f..d65f8e3a10 100644 --- a/src/components/structures/ContextMenu.tsx +++ b/src/components/structures/ContextMenu.tsx @@ -322,7 +322,12 @@ export class ContextMenu extends React.PureComponent { const menuClasses = classNames({ 'mx_ContextualMenu': true, - // Defensively check for counter cases + /** + * In some cases we may get the number of 0, which still means that we're supposed to properly + * add the specific position class, but as it was falsy things didn't work as intended. + * In addition, defensively check for counter cases where we may get more than one value, + * even if we shouldn't. + */ 'mx_ContextualMenu_left': !hasChevron && position.left !== undefined && !position.right, 'mx_ContextualMenu_right': !hasChevron && position.right !== undefined && !position.left, 'mx_ContextualMenu_top': !hasChevron && position.top !== undefined && !position.bottom, From e3ec00bcdf8d08aacf721cbaf5090c4282921adb Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 14 Sep 2021 14:35:33 +0100 Subject: [PATCH 25/37] Fix space create menu eating first character of name in private space creation --- src/components/views/spaces/SpaceCreateMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/spaces/SpaceCreateMenu.tsx b/src/components/views/spaces/SpaceCreateMenu.tsx index 2028e66625..c09b26e45f 100644 --- a/src/components/views/spaces/SpaceCreateMenu.tsx +++ b/src/components/views/spaces/SpaceCreateMenu.tsx @@ -177,7 +177,7 @@ export const SpaceCreateForm: React.FC = ({ const newName = ev.target.value; if (!alias || alias === `#${nameToLocalpart(name)}:${domain}`) { setAlias(`#${nameToLocalpart(newName)}:${domain}`); - aliasFieldRef.current.validate({ allowEmpty: true }); + aliasFieldRef.current?.validate({ allowEmpty: true }); } setName(newName); }} From e37f6b96d714bc52ff89d5384c24f7fbd621a596 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 14 Sep 2021 14:36:11 +0100 Subject: [PATCH 26/37] Fix RoomTile subscribing to wrong event emitter for room name --- src/components/views/rooms/RoomTile.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomTile.tsx b/src/components/views/rooms/RoomTile.tsx index 8ed2ca85e9..970915d653 100644 --- a/src/components/views/rooms/RoomTile.tsx +++ b/src/components/views/rooms/RoomTile.tsx @@ -101,7 +101,7 @@ export default class RoomTile extends React.PureComponent { this.roomProps = EchoChamber.forRoom(this.props.room); } - private onRoomNameUpdate = (room) => { + private onRoomNameUpdate = (room: Room) => { this.forceUpdate(); }; @@ -164,7 +164,7 @@ export default class RoomTile extends React.PureComponent { ); this.notificationState.on(NOTIFICATION_STATE_UPDATE, this.onNotificationUpdate); this.roomProps.on(PROPERTY_UPDATED, this.onRoomPropertyUpdate); - this.roomProps.on("Room.name", this.onRoomNameUpdate); + this.props.room?.on("Room.name", this.onRoomNameUpdate); CommunityPrototypeStore.instance.on( CommunityPrototypeStore.getUpdateEventName(this.props.room.roomId), this.onCommunityUpdate, From 5048e41e8b64f9a5d315499565cbf90884f9e05b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 14 Sep 2021 14:41:51 +0100 Subject: [PATCH 27/37] Space Hierarchy react to known local rooms changing names --- src/components/structures/SpaceHierarchy.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/structures/SpaceHierarchy.tsx b/src/components/structures/SpaceHierarchy.tsx index a0d4d9c42a..09099032dc 100644 --- a/src/components/structures/SpaceHierarchy.tsx +++ b/src/components/structures/SpaceHierarchy.tsx @@ -57,6 +57,7 @@ import { Key } from "../../Keyboard"; import { IState, RovingTabIndexProvider, useRovingTabIndex } from "../../accessibility/RovingTabIndex"; import { getDisplayAliasForRoom } from "./RoomDirectory"; import MatrixClientContext from "../../contexts/MatrixClientContext"; +import { useEventEmitterState } from "../../hooks/useEventEmitter"; interface IProps { space: Room; @@ -87,7 +88,8 @@ const Tile: React.FC = ({ }) => { const cli = useContext(MatrixClientContext); const joinedRoom = cli.getRoom(room.room_id)?.getMyMembership() === "join" ? cli.getRoom(room.room_id) : null; - const name = joinedRoom?.name || room.name || room.canonical_alias || room.aliases?.[0] + const joinedRoomName = useEventEmitterState(joinedRoom, "Room.name", room => room?.name); + const name = joinedRoomName || room.name || room.canonical_alias || room.aliases?.[0] || (room.room_type === RoomType.Space ? _t("Unnamed Space") : _t("Unnamed Room")); const [showChildren, toggleShowChildren] = useStateToggle(true); From f59baf1efb1c40a95724ad20b858baae2a46d528 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 14 Sep 2021 14:41:55 +0100 Subject: [PATCH 28/37] Tidy some types --- src/hooks/useEventEmitter.ts | 12 ++++++++++-- src/hooks/useRoomState.ts | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/hooks/useEventEmitter.ts b/src/hooks/useEventEmitter.ts index 74b23f0198..693eebc0e3 100644 --- a/src/hooks/useEventEmitter.ts +++ b/src/hooks/useEventEmitter.ts @@ -20,7 +20,11 @@ import type { EventEmitter } from "events"; type Handler = (...args: any[]) => void; // Hook to wrap event emitter on and removeListener in hook lifecycle -export const useEventEmitter = (emitter: EventEmitter, eventName: string | symbol, handler: Handler) => { +export const useEventEmitter = ( + emitter: EventEmitter | undefined, + eventName: string | symbol, + handler: Handler, +) => { // Create a ref that stores handler const savedHandler = useRef(handler); @@ -51,7 +55,11 @@ export const useEventEmitter = (emitter: EventEmitter, eventName: string | symbo type Mapper = (...args: any[]) => T; -export const useEventEmitterState = (emitter: EventEmitter, eventName: string | symbol, fn: Mapper): T => { +export const useEventEmitterState = ( + emitter: EventEmitter | undefined, + eventName: string | symbol, + fn: Mapper, +): T => { const [value, setValue] = useState(fn()); const handler = useCallback((...args: any[]) => { setValue(fn(...args)); diff --git a/src/hooks/useRoomState.ts b/src/hooks/useRoomState.ts index e778acf8a9..89c94df10b 100644 --- a/src/hooks/useRoomState.ts +++ b/src/hooks/useRoomState.ts @@ -25,7 +25,7 @@ const defaultMapper: Mapper = (roomState: RoomState) => roomState; // Hook to simplify watching Matrix Room state export const useRoomState = ( - room: Room, + room?: Room, mapper: Mapper = defaultMapper as Mapper, ): T => { const [value, setValue] = useState(room ? mapper(room.currentState) : undefined); From 6672be91a186147dcf84cdd1722703c75d702797 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 14 Sep 2021 15:00:44 +0100 Subject: [PATCH 29/37] Simplify Space Panel layout --- res/css/structures/_SpacePanel.scss | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/res/css/structures/_SpacePanel.scss b/res/css/structures/_SpacePanel.scss index bbb1867f16..29c8c0c36d 100644 --- a/res/css/structures/_SpacePanel.scss +++ b/res/css/structures/_SpacePanel.scss @@ -139,7 +139,6 @@ $activeBorderColor: $secondary-content; &:not(.mx_SpaceButton_narrow) { .mx_SpaceButton_selectionWrapper { width: 100%; - padding-right: 16px; overflow: hidden; } } @@ -151,7 +150,6 @@ $activeBorderColor: $secondary-content; display: block; text-overflow: ellipsis; overflow: hidden; - padding-right: 8px; font-size: $font-14px; line-height: $font-18px; } @@ -225,8 +223,7 @@ $activeBorderColor: $secondary-content; margin-top: auto; margin-bottom: auto; display: none; - position: absolute; - right: 4px; + position: relative; &::before { top: 2px; @@ -245,8 +242,6 @@ $activeBorderColor: $secondary-content; } .mx_SpacePanel_badgeContainer { - position: absolute; - // Create a flexbox to make aligning dot badges easier display: flex; align-items: center; @@ -264,6 +259,7 @@ $activeBorderColor: $secondary-content; &.collapsed { .mx_SpaceButton { .mx_SpacePanel_badgeContainer { + position: absolute; right: 0; top: 0; @@ -293,19 +289,12 @@ $activeBorderColor: $secondary-content; } &:not(.collapsed) { - .mx_SpacePanel_badgeContainer { - position: absolute; - right: 4px; - } - .mx_SpaceButton:hover, .mx_SpaceButton:focus-within, .mx_SpaceButton_hasMenuOpen { &:not(.mx_SpaceButton_invite) { // Hide the badge container on hover because it'll be a menu button .mx_SpacePanel_badgeContainer { - width: 0; - height: 0; display: none; } From 8505f292b27e68ffae9132bb5a9f6598f00e54cc Mon Sep 17 00:00:00 2001 From: Dariusz Niemczyk Date: Mon, 13 Sep 2021 22:11:58 +0200 Subject: [PATCH 30/37] Fix invalid ContextualMenu positions --- src/components/structures/ContextMenu.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx index 332b6cd318..3c97b3d3ce 100644 --- a/src/components/structures/ContextMenu.tsx +++ b/src/components/structures/ContextMenu.tsx @@ -322,10 +322,11 @@ export class ContextMenu extends React.PureComponent { const menuClasses = classNames({ 'mx_ContextualMenu': true, - 'mx_ContextualMenu_left': !hasChevron && position.left, - 'mx_ContextualMenu_right': !hasChevron && position.right, - 'mx_ContextualMenu_top': !hasChevron && position.top, - 'mx_ContextualMenu_bottom': !hasChevron && position.bottom, + // Defensively check for counter cases + 'mx_ContextualMenu_left': !hasChevron && position.left !== undefined && !position.right, + 'mx_ContextualMenu_right': !hasChevron && position.right !== undefined && !position.left, + 'mx_ContextualMenu_top': !hasChevron && position.top !== undefined && !position.bottom, + 'mx_ContextualMenu_bottom': !hasChevron && position.bottom !== undefined && !position.top, 'mx_ContextualMenu_withChevron_left': chevronFace === ChevronFace.Left, 'mx_ContextualMenu_withChevron_right': chevronFace === ChevronFace.Right, 'mx_ContextualMenu_withChevron_top': chevronFace === ChevronFace.Top, From 769c9cd78086519d7dda4173652ce1f24199caf9 Mon Sep 17 00:00:00 2001 From: Dariusz Niemczyk Date: Tue, 14 Sep 2021 14:51:17 +0200 Subject: [PATCH 31/37] Add a better comment describing the behavior --- src/components/structures/ContextMenu.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx index 3c97b3d3ce..4bd528b893 100644 --- a/src/components/structures/ContextMenu.tsx +++ b/src/components/structures/ContextMenu.tsx @@ -322,7 +322,12 @@ export class ContextMenu extends React.PureComponent { const menuClasses = classNames({ 'mx_ContextualMenu': true, - // Defensively check for counter cases + /** + * In some cases we may get the number of 0, which still means that we're supposed to properly + * add the specific position class, but as it was falsy things didn't work as intended. + * In addition, defensively check for counter cases where we may get more than one value, + * even if we shouldn't. + */ 'mx_ContextualMenu_left': !hasChevron && position.left !== undefined && !position.right, 'mx_ContextualMenu_right': !hasChevron && position.right !== undefined && !position.left, 'mx_ContextualMenu_top': !hasChevron && position.top !== undefined && !position.bottom, From cb6368f885c9fab4afee22810240b38e814e19de Mon Sep 17 00:00:00 2001 From: Dariusz Niemczyk Date: Tue, 14 Sep 2021 14:45:47 +0200 Subject: [PATCH 32/37] Fix autocomplete not having y-scroll After changing flex-order the children did not have a max-height which ended up in the child growing to outside of the screen instead of being properly constrained. Fix https://github.com/vector-im/element-web/issues/18997 --- res/css/views/rooms/_Autocomplete.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/rooms/_Autocomplete.scss b/res/css/views/rooms/_Autocomplete.scss index 8d2b338d9d..fcdab37f5a 100644 --- a/res/css/views/rooms/_Autocomplete.scss +++ b/res/css/views/rooms/_Autocomplete.scss @@ -7,7 +7,6 @@ background: $background; border-bottom: none; border-radius: 8px 8px 0 0; - max-height: 35vh; overflow: clip; display: flex; flex-direction: column; @@ -64,6 +63,7 @@ margin: 12px; height: 100%; overflow-y: scroll; + max-height: 35vh; } .mx_Autocomplete_Completion_container_truncate { From 60f43f01715b35b5da0141ca15bdef61ab724eac Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 14 Sep 2021 15:12:25 +0100 Subject: [PATCH 33/37] Stop spinner on space preview if the join fails --- src/components/structures/SpaceRoomView.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/structures/SpaceRoomView.tsx b/src/components/structures/SpaceRoomView.tsx index 6bb0433448..3837d26564 100644 --- a/src/components/structures/SpaceRoomView.tsx +++ b/src/components/structures/SpaceRoomView.tsx @@ -78,6 +78,7 @@ import { CreateEventField, IGroupSummary } from "../views/dialogs/CreateSpaceFro import { useAsyncMemo } from "../../hooks/useAsyncMemo"; import Spinner from "../views/elements/Spinner"; import GroupAvatar from "../views/avatars/GroupAvatar"; +import { useDispatcher } from "../../hooks/useDispatcher"; interface IProps { space: Room; @@ -191,6 +192,11 @@ interface ISpacePreviewProps { const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }: ISpacePreviewProps) => { const cli = useContext(MatrixClientContext); const myMembership = useMyRoomMembership(space); + useDispatcher(defaultDispatcher, payload => { + if (payload.action === Action.JoinRoomError && payload.roomId === space.roomId) { + setBusy(false); // stop the spinner, join failed + } + }); const [busy, setBusy] = useState(false); From 919270ff0cfe739f65ec8551c592584a4b067b1a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 14 Sep 2021 15:50:51 +0100 Subject: [PATCH 34/37] Update src/stores/SpaceStore.tsx Co-authored-by: Travis Ralston --- src/stores/SpaceStore.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stores/SpaceStore.tsx b/src/stores/SpaceStore.tsx index eebc196f4c..cd0acc9d88 100644 --- a/src/stores/SpaceStore.tsx +++ b/src/stores/SpaceStore.tsx @@ -630,7 +630,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { private onRoom = (room: Room, newMembership?: string, oldMembership?: string) => { const roomMembership = room.getMyMembership(); - if (roomMembership === null) { + if (!roomMembership) { // room is still being baked in the js-sdk, we'll process it at Room.myMembership instead return; } From 4ea03850614a1534be7d8760105d7dab7b42088d Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 14 Sep 2021 15:54:30 +0100 Subject: [PATCH 35/37] Upgrade matrix-js-sdk to 12.5.0 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index d1e6040cd5..af0dd4ce81 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "katex": "^0.12.0", "linkifyjs": "^2.1.9", "lodash": "^4.17.20", - "matrix-js-sdk": "12.5.0-rc.1", + "matrix-js-sdk": "12.5.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 b307aa49df..4f2a6b7242 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5791,10 +5791,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@12.5.0-rc.1: - version "12.5.0-rc.1" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-12.5.0-rc.1.tgz#138155239b4be38ca706663ca0f2739aab41f1db" - integrity sha512-R+mNTwTWO4ppXvwtiZtMLB5rjNAR28j+tHAqItfx9yAtDskjzLZEDfjRtgm6+wl5t6us1WI4p1nR6IMb8+uESQ== +matrix-js-sdk@12.5.0: + version "12.5.0" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-12.5.0.tgz#3899f9d323c457d15a1fe436a2dfa07ae131cce2" + integrity sha512-HnEXoEhqpNp9/W9Ep7ZNZAubFlUssFyVpjgKfMOxxg+dYbBk5NWToHmAPQxlRUgrZ/rIMLVyMJROSCIthDbo2A== dependencies: "@babel/runtime" "^7.12.5" another-json "^0.2.0" From 2eeb3cecd94ac15b75662234d624864e62c0e37f Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 14 Sep 2021 15:56:22 +0100 Subject: [PATCH 36/37] Prepare changelog for v3.30.0 --- CHANGELOG.md | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a660b17301..fc368aed4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,63 @@ +Changes in [3.30.0](https://github.com/vector-im/element-desktop/releases/tag/v3.30.0) (2021-09-14) +=================================================================================================== + +## ✨ Features + * Add bubble highlight styling ([\#6582](https://github.com/matrix-org/matrix-react-sdk/pull/6582)). Fixes vector-im/element-web#18295 and vector-im/element-web#18295. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * [Release] Add config option to turn on in-room event sending timing metrics ([\#6773](https://github.com/matrix-org/matrix-react-sdk/pull/6773)). + * Create narrow mode for Composer ([\#6682](https://github.com/matrix-org/matrix-react-sdk/pull/6682)). Fixes vector-im/element-web#18533 and vector-im/element-web#18533. + * Prefer matrix.to alias links over room id in spaces & share ([\#6745](https://github.com/matrix-org/matrix-react-sdk/pull/6745)). Fixes vector-im/element-web#18796 and vector-im/element-web#18796. + * Stop automatic playback of voice messages if a non-voice message is encountered ([\#6728](https://github.com/matrix-org/matrix-react-sdk/pull/6728)). Fixes vector-im/element-web#18850 and vector-im/element-web#18850. + * Show call length during a call ([\#6700](https://github.com/matrix-org/matrix-react-sdk/pull/6700)). Fixes vector-im/element-web#18566 and vector-im/element-web#18566. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Serialize and retry mass-leave when leaving space ([\#6737](https://github.com/matrix-org/matrix-react-sdk/pull/6737)). Fixes vector-im/element-web#18789 and vector-im/element-web#18789. + * Improve form handling in and around space creation ([\#6739](https://github.com/matrix-org/matrix-react-sdk/pull/6739)). Fixes vector-im/element-web#18775 and vector-im/element-web#18775. + * Split autoplay GIFs and videos into different settings ([\#6726](https://github.com/matrix-org/matrix-react-sdk/pull/6726)). Fixes vector-im/element-web#5771 and vector-im/element-web#5771. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Add autoplay for voice messages ([\#6710](https://github.com/matrix-org/matrix-react-sdk/pull/6710)). Fixes vector-im/element-web#18804, vector-im/element-web#18715, vector-im/element-web#18714 vector-im/element-web#17961 and vector-im/element-web#18804. + * Allow to use basic html to format invite messages ([\#6703](https://github.com/matrix-org/matrix-react-sdk/pull/6703)). Fixes vector-im/element-web#15738 and vector-im/element-web#15738. Contributed by [skolmer](https://github.com/skolmer). + * Allow widgets, when eligible, to interact with more rooms as per MSC2762 ([\#6684](https://github.com/matrix-org/matrix-react-sdk/pull/6684)). + * Remove arbitrary limits from send/receive events for widgets ([\#6719](https://github.com/matrix-org/matrix-react-sdk/pull/6719)). Fixes vector-im/element-web#17994 and vector-im/element-web#17994. + * Reload suggested rooms if we see the state change down /sync ([\#6715](https://github.com/matrix-org/matrix-react-sdk/pull/6715)). Fixes vector-im/element-web#18761 and vector-im/element-web#18761. + * When creating private spaces, make the initial rooms restricted if supported ([\#6721](https://github.com/matrix-org/matrix-react-sdk/pull/6721)). Fixes vector-im/element-web#18722 and vector-im/element-web#18722. + * Threading exploration work ([\#6658](https://github.com/matrix-org/matrix-react-sdk/pull/6658)). Fixes vector-im/element-web#18532 and vector-im/element-web#18532. + * Default to `Don't leave any` when leaving a space ([\#6697](https://github.com/matrix-org/matrix-react-sdk/pull/6697)). Fixes vector-im/element-web#18592 and vector-im/element-web#18592. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Special case redaction event sending from widgets per MSC2762 ([\#6686](https://github.com/matrix-org/matrix-react-sdk/pull/6686)). Fixes vector-im/element-web#18573 and vector-im/element-web#18573. + * Add active speaker indicators ([\#6639](https://github.com/matrix-org/matrix-react-sdk/pull/6639)). Fixes vector-im/element-web#17627 and vector-im/element-web#17627. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Increase general app performance by optimizing layers ([\#6644](https://github.com/matrix-org/matrix-react-sdk/pull/6644)). Fixes vector-im/element-web#18730 and vector-im/element-web#18730. Contributed by [Palid](https://github.com/Palid). + +## 🐛 Bug Fixes + * Fix autocomplete not having y-scroll ([\#6802](https://github.com/matrix-org/matrix-react-sdk/pull/6802)). + * Fix emoji picker and stickerpicker not appearing correctly when opened ([\#6801](https://github.com/matrix-org/matrix-react-sdk/pull/6801)). + * Debounce read marker update on scroll ([\#6774](https://github.com/matrix-org/matrix-react-sdk/pull/6774)). + * Fix Space creation wizard go to my first room button behaviour ([\#6748](https://github.com/matrix-org/matrix-react-sdk/pull/6748)). Fixes vector-im/element-web#18764 and vector-im/element-web#18764. + * Fix scroll being stuck at bottom ([\#6751](https://github.com/matrix-org/matrix-react-sdk/pull/6751)). Fixes vector-im/element-web#18903 and vector-im/element-web#18903. + * Fix widgets not remembering identity verification when asked to. ([\#6742](https://github.com/matrix-org/matrix-react-sdk/pull/6742)). Fixes vector-im/element-web#15631 and vector-im/element-web#15631. + * Add missing pluralisation i18n strings for Spaces ([\#6738](https://github.com/matrix-org/matrix-react-sdk/pull/6738)). Fixes vector-im/element-web#18780 and vector-im/element-web#18780. + * Make ForgotPassword UX slightly more user friendly ([\#6636](https://github.com/matrix-org/matrix-react-sdk/pull/6636)). Fixes vector-im/element-web#11531 and vector-im/element-web#11531. Contributed by [Palid](https://github.com/Palid). + * Don't context switch room on SpaceStore ready as it can break permalinks ([\#6730](https://github.com/matrix-org/matrix-react-sdk/pull/6730)). Fixes vector-im/element-web#17974 and vector-im/element-web#17974. + * Fix explore rooms button not working during space creation wizard ([\#6729](https://github.com/matrix-org/matrix-react-sdk/pull/6729)). Fixes vector-im/element-web#18762 and vector-im/element-web#18762. + * Fix bug where one party's media would sometimes not be shown ([\#6731](https://github.com/matrix-org/matrix-react-sdk/pull/6731)). + * Only make the initial space rooms suggested by default ([\#6714](https://github.com/matrix-org/matrix-react-sdk/pull/6714)). Fixes vector-im/element-web#18760 and vector-im/element-web#18760. + * Replace fake username in EventTilePreview with a proper loading state ([\#6702](https://github.com/matrix-org/matrix-react-sdk/pull/6702)). Fixes vector-im/element-web#15897 and vector-im/element-web#15897. Contributed by [skolmer](https://github.com/skolmer). + * Don't send prehistorical events to widgets during decryption at startup ([\#6695](https://github.com/matrix-org/matrix-react-sdk/pull/6695)). Fixes vector-im/element-web#18060 and vector-im/element-web#18060. + * When creating subspaces properly set restricted join rule ([\#6725](https://github.com/matrix-org/matrix-react-sdk/pull/6725)). Fixes vector-im/element-web#18797 and vector-im/element-web#18797. + * Fix the Image View not openning for some pinned messages ([\#6723](https://github.com/matrix-org/matrix-react-sdk/pull/6723)). Fixes vector-im/element-web#18422 and vector-im/element-web#18422. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Show autocomplete sections vertically ([\#6722](https://github.com/matrix-org/matrix-react-sdk/pull/6722)). Fixes vector-im/element-web#18860 and vector-im/element-web#18860. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Fix EmojiPicker filtering to lower case emojibase data strings ([\#6717](https://github.com/matrix-org/matrix-react-sdk/pull/6717)). Fixes vector-im/element-web#18686 and vector-im/element-web#18686. + * Clear currentRoomId when viewing home page, fixing document title ([\#6716](https://github.com/matrix-org/matrix-react-sdk/pull/6716)). Fixes vector-im/element-web#18668 and vector-im/element-web#18668. + * Fix membership updates to Spaces not applying in real-time ([\#6713](https://github.com/matrix-org/matrix-react-sdk/pull/6713)). Fixes vector-im/element-web#18737 and vector-im/element-web#18737. + * Don't show a double stacked invite modals when inviting to Spaces ([\#6698](https://github.com/matrix-org/matrix-react-sdk/pull/6698)). Fixes vector-im/element-web#18745 and vector-im/element-web#18745. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Remove non-functional DuckDuckGo Autocomplete Provider ([\#6712](https://github.com/matrix-org/matrix-react-sdk/pull/6712)). Fixes vector-im/element-web#18778 and vector-im/element-web#18778. + * Filter members on `MemberList` load ([\#6708](https://github.com/matrix-org/matrix-react-sdk/pull/6708)). Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Fix improper voice messages being produced in Firefox and sometimes other browsers. ([\#6696](https://github.com/matrix-org/matrix-react-sdk/pull/6696)). Fixes vector-im/element-web#18587 and vector-im/element-web#18587. + * Fix client forgetting which capabilities a widget was approved for ([\#6685](https://github.com/matrix-org/matrix-react-sdk/pull/6685)). Fixes vector-im/element-web#18786 and vector-im/element-web#18786. + * Fix left panel widgets not remembering collapsed state ([\#6687](https://github.com/matrix-org/matrix-react-sdk/pull/6687)). Fixes vector-im/element-web#17803 and vector-im/element-web#17803. + * Fix changelog link colour back to blue ([\#6692](https://github.com/matrix-org/matrix-react-sdk/pull/6692)). Fixes vector-im/element-web#18726 and vector-im/element-web#18726. + * Soften codeblock border color ([\#6564](https://github.com/matrix-org/matrix-react-sdk/pull/6564)). Fixes vector-im/element-web#18367 and vector-im/element-web#18367. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Pause ringing more aggressively ([\#6691](https://github.com/matrix-org/matrix-react-sdk/pull/6691)). Fixes vector-im/element-web#18588 and vector-im/element-web#18588. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Fix command autocomplete ([\#6680](https://github.com/matrix-org/matrix-react-sdk/pull/6680)). Fixes vector-im/element-web#18670 and vector-im/element-web#18670. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Don't re-sort the room-list based on profile/status changes ([\#6595](https://github.com/matrix-org/matrix-react-sdk/pull/6595)). Fixes vector-im/element-web#110 and vector-im/element-web#110. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Fix codeblock formatting with syntax highlighting on ([\#6681](https://github.com/matrix-org/matrix-react-sdk/pull/6681)). Fixes vector-im/element-web#18739 vector-im/element-web#18365 and vector-im/element-web#18739. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Add padding to the Add button in the notification settings ([\#6665](https://github.com/matrix-org/matrix-react-sdk/pull/6665)). Fixes vector-im/element-web#18706 and vector-im/element-web#18706. Contributed by [SimonBrandner](https://github.com/SimonBrandner). + Changes in [3.30.0-rc.2](https://github.com/vector-im/element-desktop/releases/tag/v3.30.0-rc.2) (2021-09-09) ============================================================================================================= From c3089a109799a9d6251d5bec924b9f56603b62ed Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 14 Sep 2021 15:56:23 +0100 Subject: [PATCH 37/37] v3.30.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index af0dd4ce81..a24a509b24 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "3.30.0-rc.2", + "version": "3.30.0", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": {