From b777c83c908a9c86b6d99e966e566bebcabfae0a Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 4 May 2021 15:42:45 +0100 Subject: [PATCH 01/26] Upgrade matrix-js-sdk to 10.1.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 e54de8a96c..98141c6404 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,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": "10.1.0-rc.1", "matrix-widget-api": "^0.1.0-beta.13", "minimist": "^1.2.5", "opus-recorder": "^8.0.3", diff --git a/yarn.lock b/yarn.lock index acdca26e55..c1e04a0686 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5671,9 +5671,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 "10.0.0" - resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/c8f69c0b7937b9064938c134d708c4d064b71315" +matrix-js-sdk@10.1.0-rc.1: + version "10.1.0-rc.1" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-10.1.0-rc.1.tgz#67b04cd30cb3b3c8ee7a3a2ead1db567a99e35c8" + integrity sha512-jpCnSqvNAsVIHv/FRVx1xV11IKcQCd6zUy4cHLDfUH/6GxFDtW/Fk446A7XDIJnNvstqmWBghk4X65hdsfq5OQ== dependencies: "@babel/runtime" "^7.12.5" another-json "^0.2.0" From b5cb1534d3990f92ea399d126d83019c26dd2d94 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 4 May 2021 15:53:39 +0100 Subject: [PATCH 02/26] Prepare changelog for v3.20.0-rc.1 --- CHANGELOG.md | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d459b4e94a..fc6c0b7f76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,107 @@ +Changes in [3.20.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.20.0-rc.1) (2021-05-04) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.19.0...v3.20.0-rc.1) + + * Upgrade to JS SDK 10.1.0-rc.1 + * Translations update from Weblate + [\#5966](https://github.com/matrix-org/matrix-react-sdk/pull/5966) + * Fix more space panel layout and hover behaviour issues + [\#5965](https://github.com/matrix-org/matrix-react-sdk/pull/5965) + * Fix edge case with space panel alignment with subspaces on ff + [\#5964](https://github.com/matrix-org/matrix-react-sdk/pull/5964) + * Fix saving room pill part to history + [\#5951](https://github.com/matrix-org/matrix-react-sdk/pull/5951) + * Generate room preview even when minimized + [\#5948](https://github.com/matrix-org/matrix-react-sdk/pull/5948) + * Another change from recovery passphrase to Security Phrase + [\#5934](https://github.com/matrix-org/matrix-react-sdk/pull/5934) + * Sort rooms in the add existing to space dialog based on recency + [\#5943](https://github.com/matrix-org/matrix-react-sdk/pull/5943) + * Inhibit sending RR when context switching to a room + [\#5944](https://github.com/matrix-org/matrix-react-sdk/pull/5944) + * Prevent room list keyboard handling from landing focus on hidden nodes + [\#5950](https://github.com/matrix-org/matrix-react-sdk/pull/5950) + * Make the text filter search all spaces instead of just the selected one + [\#5942](https://github.com/matrix-org/matrix-react-sdk/pull/5942) + * Enable indent rule and fix indent + [\#5931](https://github.com/matrix-org/matrix-react-sdk/pull/5931) + * Prevent peeking members from reacting + [\#5946](https://github.com/matrix-org/matrix-react-sdk/pull/5946) + * Disallow inline display maths + [\#5939](https://github.com/matrix-org/matrix-react-sdk/pull/5939) + * Space creation prompt user to add existing rooms for "Just Me" spaces + [\#5923](https://github.com/matrix-org/matrix-react-sdk/pull/5923) + * Add test coverage collection script + [\#5937](https://github.com/matrix-org/matrix-react-sdk/pull/5937) + * Fix joining room using via servers regression + [\#5936](https://github.com/matrix-org/matrix-react-sdk/pull/5936) + * Revert "Fixes the two Todays problem in Redaction" + [\#5938](https://github.com/matrix-org/matrix-react-sdk/pull/5938) + * Handle encoded matrix URLs + [\#5903](https://github.com/matrix-org/matrix-react-sdk/pull/5903) + * Render ignored users setting regardless of if there are any + [\#5860](https://github.com/matrix-org/matrix-react-sdk/pull/5860) + * Fix inserting trailing colon after mention/pill + [\#5830](https://github.com/matrix-org/matrix-react-sdk/pull/5830) + * Fixes the two Todays problem in Redaction + [\#5917](https://github.com/matrix-org/matrix-react-sdk/pull/5917) + * Fix page up/down scrolling only half a page + [\#5920](https://github.com/matrix-org/matrix-react-sdk/pull/5920) + * Voice messages: Composer controls + [\#5935](https://github.com/matrix-org/matrix-react-sdk/pull/5935) + * Support MSC3086 asserted identity + [\#5886](https://github.com/matrix-org/matrix-react-sdk/pull/5886) + * Handle possible edge case with getting stuck in "unsent messages" bar + [\#5930](https://github.com/matrix-org/matrix-react-sdk/pull/5930) + * Fix suggested rooms not showing up regression from room list optimisation + [\#5932](https://github.com/matrix-org/matrix-react-sdk/pull/5932) + * Broadcast language change to ElectronPlatform + [\#5913](https://github.com/matrix-org/matrix-react-sdk/pull/5913) + * Fix VoIP PIP frame color + [\#5701](https://github.com/matrix-org/matrix-react-sdk/pull/5701) + * Convert some Flow-typed files to TypeScript + [\#5912](https://github.com/matrix-org/matrix-react-sdk/pull/5912) + * Initial SpaceStore tests work + [\#5906](https://github.com/matrix-org/matrix-react-sdk/pull/5906) + * Fix issues with space hierarchy in layout and with incompatible servers + [\#5926](https://github.com/matrix-org/matrix-react-sdk/pull/5926) + * Scale all mxc thumbs using device pixel ratio for hidpi + [\#5928](https://github.com/matrix-org/matrix-react-sdk/pull/5928) + * Fix add existing to space dialog no longer showing rooms for public spaces + [\#5918](https://github.com/matrix-org/matrix-react-sdk/pull/5918) + * Disable spaces context switching for when exploring a space + [\#5924](https://github.com/matrix-org/matrix-react-sdk/pull/5924) + * Autofocus search box in the add existing to space dialog + [\#5921](https://github.com/matrix-org/matrix-react-sdk/pull/5921) + * Use label element in add existing to space dialog for easier hit target + [\#5922](https://github.com/matrix-org/matrix-react-sdk/pull/5922) + * Dynamic max and min zoom in the new ImageView + [\#5916](https://github.com/matrix-org/matrix-react-sdk/pull/5916) + * Improve message error states + [\#5897](https://github.com/matrix-org/matrix-react-sdk/pull/5897) + * Check for null room in `VisibilityProvider` + [\#5914](https://github.com/matrix-org/matrix-react-sdk/pull/5914) + * Add unit tests for various collection-based utility functions + [\#5910](https://github.com/matrix-org/matrix-react-sdk/pull/5910) + * Spaces visual fixes + [\#5909](https://github.com/matrix-org/matrix-react-sdk/pull/5909) + * Remove reliance on DOM API to generated message preview + [\#5908](https://github.com/matrix-org/matrix-react-sdk/pull/5908) + * Expand upon voice message event & include overall waveform + [\#5888](https://github.com/matrix-org/matrix-react-sdk/pull/5888) + * Use floats for image background opacity + [\#5905](https://github.com/matrix-org/matrix-react-sdk/pull/5905) + * Show invites to spaces at the top of the space panel + [\#5902](https://github.com/matrix-org/matrix-react-sdk/pull/5902) + * Improve edge cases with spaces context switching + [\#5899](https://github.com/matrix-org/matrix-react-sdk/pull/5899) + * Fix spaces notification dots wrongly including upgraded (hidden) rooms + [\#5900](https://github.com/matrix-org/matrix-react-sdk/pull/5900) + * Iterate the spaces face pile design + [\#5898](https://github.com/matrix-org/matrix-react-sdk/pull/5898) + * Fix alignment issue with nested spaces being cut off wrong + [\#5890](https://github.com/matrix-org/matrix-react-sdk/pull/5890) + Changes in [3.19.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.19.0) (2021-04-26) ===================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.19.0-rc.1...v3.19.0) From efc8c8c84e46a267c3553d53b4d703b9f4aff6f3 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 4 May 2021 15:53:40 +0100 Subject: [PATCH 03/26] v3.20.0-rc.1 --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 98141c6404..f6471327cb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "3.19.0", + "version": "3.20.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", @@ -196,5 +196,6 @@ "coverageReporters": [ "text" ] - } + }, + "typings": "./lib/index.d.ts" } From a70be45b6e0f2ea1292f8a56067c59c81a88156f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 4 May 2021 18:06:43 +0100 Subject: [PATCH 04/26] Experiment switching the Home Space out for an All rooms space --- src/components/structures/RoomSearch.tsx | 22 +--- .../views/rooms/RoomListNumResults.tsx | 6 +- src/components/views/spaces/SpacePanel.tsx | 10 +- src/i18n/strings/en_EN.json | 7 +- src/stores/SpaceStore.tsx | 103 +++--------------- src/stores/room-list/RoomListStore.ts | 14 +-- src/stores/room-list/SpaceWatcher.ts | 28 +++-- .../room-list/filters/SpaceFilterCondition.ts | 8 +- 8 files changed, 49 insertions(+), 149 deletions(-) diff --git a/src/components/structures/RoomSearch.tsx b/src/components/structures/RoomSearch.tsx index 34682877e0..b3ceb1588f 100644 --- a/src/components/structures/RoomSearch.tsx +++ b/src/components/structures/RoomSearch.tsx @@ -17,7 +17,6 @@ limitations under the License. import * as React from "react"; import { createRef } from "react"; import classNames from "classnames"; -import { Room } from "matrix-js-sdk/src/models/room"; import defaultDispatcher from "../../dispatcher/dispatcher"; import { _t } from "../../languageHandler"; @@ -27,8 +26,8 @@ import { Action } from "../../dispatcher/actions"; import RoomListStore from "../../stores/room-list/RoomListStore"; import { NameFilterCondition } from "../../stores/room-list/filters/NameFilterCondition"; import { getKeyBindingsManager, RoomListAction } from "../../KeyBindingsManager"; -import {replaceableComponent} from "../../utils/replaceableComponent"; -import SpaceStore, {UPDATE_SELECTED_SPACE, UPDATE_TOP_LEVEL_SPACES} from "../../stores/SpaceStore"; +import { replaceableComponent } from "../../utils/replaceableComponent"; +import SpaceStore, { UPDATE_SELECTED_SPACE } from "../../stores/SpaceStore"; interface IProps { isMinimized: boolean; @@ -42,7 +41,6 @@ interface IProps { interface IState { query: string; focused: boolean; - inSpaces: boolean; } @replaceableComponent("structures.RoomSearch") @@ -57,13 +55,11 @@ export default class RoomSearch extends React.PureComponent { this.state = { query: "", focused: false, - inSpaces: false, }; this.dispatcherRef = defaultDispatcher.register(this.onAction); // clear filter when changing spaces, in future we may wish to maintain a filter per-space SpaceStore.instance.on(UPDATE_SELECTED_SPACE, this.clearInput); - SpaceStore.instance.on(UPDATE_TOP_LEVEL_SPACES, this.onSpaces); } public componentDidUpdate(prevProps: Readonly, prevState: Readonly): void { @@ -84,15 +80,8 @@ export default class RoomSearch extends React.PureComponent { public componentWillUnmount() { defaultDispatcher.unregister(this.dispatcherRef); SpaceStore.instance.off(UPDATE_SELECTED_SPACE, this.clearInput); - SpaceStore.instance.off(UPDATE_TOP_LEVEL_SPACES, this.onSpaces); } - private onSpaces = (spaces: Room[]) => { - this.setState({ - inSpaces: spaces.length > 0, - }); - }; - private onAction = (payload: ActionPayload) => { if (payload.action === 'view_room' && payload.clear_search) { this.clearInput(); @@ -164,11 +153,6 @@ export default class RoomSearch extends React.PureComponent { 'mx_RoomSearch_inputExpanded': this.state.query || this.state.focused, }); - let placeholder = _t("Filter"); - if (this.state.inSpaces) { - placeholder = _t("Filter all spaces"); - } - let icon = (
); @@ -182,7 +166,7 @@ export default class RoomSearch extends React.PureComponent { onBlur={this.onBlur} onChange={this.onChange} onKeyDown={this.onKeyDown} - placeholder={placeholder} + placeholder={_t("Filter")} autoComplete="off" /> ); diff --git a/src/components/views/rooms/RoomListNumResults.tsx b/src/components/views/rooms/RoomListNumResults.tsx index 01cbecf05d..4215e5644c 100644 --- a/src/components/views/rooms/RoomListNumResults.tsx +++ b/src/components/views/rooms/RoomListNumResults.tsx @@ -19,7 +19,6 @@ import React, {useState} from "react"; import { _t } from "../../../languageHandler"; import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore"; import {useEventEmitter} from "../../../hooks/useEventEmitter"; -import SpaceStore from "../../../stores/SpaceStore"; const RoomListNumResults: React.FC = () => { const [count, setCount] = useState(null); @@ -35,10 +34,7 @@ const RoomListNumResults: React.FC = () => { if (typeof count !== "number") return null; return
- { SpaceStore.instance.spacePanelSpaces.length - ? _t("%(count)s results in all spaces", { count }) - : _t("%(count)s results", { count }) - } + { _t("%(count)s results", { count }) }
; }; diff --git a/src/components/views/spaces/SpacePanel.tsx b/src/components/views/spaces/SpacePanel.tsx index 36ab423885..411b0f9b5e 100644 --- a/src/components/views/spaces/SpacePanel.tsx +++ b/src/components/views/spaces/SpacePanel.tsx @@ -26,13 +26,11 @@ import {SpaceItem} from "./SpaceTreeLevel"; import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; import {useEventEmitter} from "../../../hooks/useEventEmitter"; import SpaceStore, { - HOME_SPACE, UPDATE_INVITED_SPACES, UPDATE_SELECTED_SPACE, UPDATE_TOP_LEVEL_SPACES, } from "../../../stores/SpaceStore"; import AutoHideScrollbar from "../../structures/AutoHideScrollbar"; -import {SpaceNotificationState} from "../../../stores/notifications/SpaceNotificationState"; import NotificationBadge from "../rooms/NotificationBadge"; import { RovingAccessibleButton, @@ -40,13 +38,15 @@ import { RovingTabIndexProvider, } from "../../../accessibility/RovingTabIndex"; import {Key} from "../../../Keyboard"; +import {RoomNotificationStateStore} from "../../../stores/notifications/RoomNotificationStateStore"; +import {NotificationState} from "../../../stores/notifications/NotificationState"; interface IButtonProps { space?: Room; className?: string; selected?: boolean; tooltip?: string; - notificationState?: SpaceNotificationState; + notificationState?: NotificationState; isNarrow?: boolean; onClick(): void; } @@ -212,8 +212,8 @@ const SpacePanel = () => { className="mx_SpaceButton_home" onClick={() => SpaceStore.instance.setActiveSpace(null)} selected={!activeSpace} - tooltip={_t("Home")} - notificationState={SpaceStore.instance.getNotificationState(HOME_SPACE)} + tooltip={_t("All rooms")} + notificationState={RoomNotificationStateStore.instance.globalState} isNarrow={isPanelCollapsed} /> { invites.map(s => %(serverName)s": "Are you sure you want to remove %(serverName)s", "Remove server": "Remove server", @@ -2619,7 +2617,6 @@ "If you can't find the room you're looking for, ask for an invite or Create a new room.": "If you can't find the room you're looking for, ask for an invite or Create a new room.", "Explore rooms in %(communityName)s": "Explore rooms in %(communityName)s", "Filter": "Filter", - "Filter all spaces": "Filter all spaces", "Clear filter": "Clear filter", "Filter rooms and people": "Filter rooms and people", "You can't send any messages until you review and agree to our terms and conditions.": "You can't send any messages until you review and agree to our terms and conditions.", diff --git a/src/stores/SpaceStore.tsx b/src/stores/SpaceStore.tsx index 22307d9f2e..50c5ea56f7 100644 --- a/src/stores/SpaceStore.tsx +++ b/src/stores/SpaceStore.tsx @@ -31,28 +31,23 @@ import {RoomNotificationStateStore} from "./notifications/RoomNotificationStateS import {DefaultTagID} from "./room-list/models"; import {EnhancedMap, mapDiff} from "../utils/maps"; import {setHasDiff} from "../utils/sets"; -import {objectDiff} from "../utils/objects"; -import {arrayHasDiff} from "../utils/arrays"; import {ISpaceSummaryEvent, ISpaceSummaryRoom} from "../components/structures/SpaceRoomDirectory"; import RoomViewStore from "./RoomViewStore"; -type SpaceKey = string | symbol; - interface IState {} const ACTIVE_SPACE_LS_KEY = "mx_active_space"; -export const HOME_SPACE = Symbol("home-space"); export const SUGGESTED_ROOMS = Symbol("suggested-rooms"); export const UPDATE_TOP_LEVEL_SPACES = Symbol("top-level-spaces"); export const UPDATE_INVITED_SPACES = Symbol("invited-spaces"); export const UPDATE_SELECTED_SPACE = Symbol("selected-space"); -// Space Room ID/HOME_SPACE will be emitted when a Space's children change +// Space Room ID will be emitted when a Space's children change const MAX_SUGGESTED_ROOMS = 20; -const getSpaceContextKey = (space?: Room) => `mx_space_context_${space?.roomId || "home_space"}`; +const getSpaceContextKey = (space?: Room) => `mx_space_context_${space?.roomId || "ALL_ROOMS"}`; const partitionSpacesAndRooms = (arr: Room[]): [Room[], Room[]] => { // [spaces, rooms] return arr.reduce((result, room: Room) => { @@ -83,15 +78,13 @@ export class SpaceStoreClass extends AsyncStoreWithClient { // The spaces representing the roots of the various tree-like hierarchies private rootSpaces: Room[] = []; - // The list of rooms not present in any currently joined spaces - private orphanedRooms = new Set(); // Map from room ID to set of spaces which list it as a child private parentMap = new EnhancedMap>(); - // Map from space key to SpaceNotificationState instance representing that space - private notificationStateMap = new Map(); + // Map from spaceId to SpaceNotificationState instance representing that space + private notificationStateMap = new Map(); // Map from space key to Set of room IDs that should be shown as part of that space's filter - private spaceFilteredRooms = new Map>(); - // The space currently selected in the Space Panel - if null then `Home` is selected + private spaceFilteredRooms = new Map>(); + // The space currently selected in the Space Panel - if null then All Rooms is selected private _activeSpace?: Room = null; private _suggestedRooms: ISpaceSummaryRoom[] = []; private _invitedSpaces = new Set(); @@ -227,7 +220,10 @@ export class SpaceStoreClass extends AsyncStoreWithClient { } public getSpaceFilteredRoomIds = (space: Room | null): Set => { - return this.spaceFilteredRooms.get(space?.roomId || HOME_SPACE) || new Set(); + if (!space) { + return new Set(this.matrixClient.getVisibleRooms().map(r => r.roomId)); + } + return this.spaceFilteredRooms.get(space.roomId) || new Set(); }; private rebuild = throttle(() => { @@ -258,7 +254,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { }); }); - const [rootSpaces, orphanedRooms] = partitionSpacesAndRooms(Array.from(unseenChildren)); + const [rootSpaces] = partitionSpacesAndRooms(Array.from(unseenChildren)); // somewhat algorithm to handle full-cycles const detachedNodes = new Set(spaces); @@ -299,7 +295,6 @@ export class SpaceStoreClass extends AsyncStoreWithClient { // rootSpaces.push(space); // }); - this.orphanedRooms = new Set(orphanedRooms); this.rootSpaces = rootSpaces; this.parentMap = backrefs; @@ -320,25 +315,6 @@ export class SpaceStoreClass extends AsyncStoreWithClient { this.rebuild(); } - private showInHomeSpace = (room: Room) => { - if (room.isSpaceRoom()) return false; - return !this.parentMap.get(room.roomId)?.size // put all orphaned rooms in the Home Space - || DMRoomMap.shared().getUserIdForRoomId(room.roomId) // put all DMs in the Home Space - || RoomListStore.instance.getTagsForRoom(room).includes(DefaultTagID.Favourite) // show all favourites - }; - - // Update a given room due to its tag changing (e.g DM-ness or Fav-ness) - // This can only change whether it shows up in the HOME_SPACE or not - private onRoomUpdate = (room: Room) => { - if (this.showInHomeSpace(room)) { - this.spaceFilteredRooms.get(HOME_SPACE)?.add(room.roomId); - this.emit(HOME_SPACE); - } else if (!this.orphanedRooms.has(room.roomId)) { - this.spaceFilteredRooms.get(HOME_SPACE)?.delete(room.roomId); - this.emit(HOME_SPACE); - } - }; - private onSpaceMembersChange = (ev: MatrixEvent) => { // skip this update if we do not have a DM with this user if (DMRoomMap.shared().getDMRoomsForUserId(ev.getStateKey()).length < 1) return; @@ -352,16 +328,6 @@ export class SpaceStoreClass extends AsyncStoreWithClient { const oldFilteredRooms = this.spaceFilteredRooms; this.spaceFilteredRooms = new Map(); - // put all room invites in the Home Space - const invites = visibleRooms.filter(r => !r.isSpaceRoom() && r.getMyMembership() === "invite"); - this.spaceFilteredRooms.set(HOME_SPACE, new Set(invites.map(room => room.roomId))); - - visibleRooms.forEach(room => { - if (this.showInHomeSpace(room)) { - this.spaceFilteredRooms.get(HOME_SPACE).add(room.roomId); - } - }); - this.rootSpaces.forEach(s => { // traverse each space tree in DFS to build up the supersets as you go up, // reusing results from like subtrees. @@ -408,13 +374,8 @@ export class SpaceStoreClass extends AsyncStoreWithClient { // Update NotificationStates this.getNotificationState(s)?.setRooms(visibleRooms.filter(room => { if (roomIds.has(room.roomId)) { - // Don't aggregate notifications for DMs except in the Home Space - if (s !== HOME_SPACE) { - return !DMRoomMap.shared().getUserIdForRoomId(room.roomId) - || RoomListStore.instance.getTagsForRoom(room).includes(DefaultTagID.Favourite); - } - - return true; + return !DMRoomMap.shared().getUserIdForRoomId(room.roomId) + || RoomListStore.instance.getTagsForRoom(room).includes(DefaultTagID.Favourite); } return false; @@ -475,8 +436,6 @@ export class SpaceStoreClass extends AsyncStoreWithClient { // TODO confirm this after implementing parenting behaviour if (room.isSpaceRoom()) { this.onSpaceUpdate(); - } else { - this.onRoomUpdate(room); } this.emit(room.roomId); break; @@ -489,38 +448,8 @@ export class SpaceStoreClass extends AsyncStoreWithClient { } }; - private onRoomAccountData = (ev: MatrixEvent, room: Room, lastEvent?: MatrixEvent) => { - if (ev.getType() === EventType.Tag && !room.isSpaceRoom()) { - // If the room was in favourites and now isn't or the opposite then update its position in the trees - const oldTags = lastEvent?.getContent()?.tags || {}; - const newTags = ev.getContent()?.tags || {}; - if (!!oldTags[DefaultTagID.Favourite] !== !!newTags[DefaultTagID.Favourite]) { - this.onRoomUpdate(room); - } - } - } - - private onAccountData = (ev: MatrixEvent, lastEvent: MatrixEvent) => { - if (ev.getType() === EventType.Direct) { - const lastContent = lastEvent.getContent(); - const content = ev.getContent(); - - const diff = objectDiff>(lastContent, content); - // filter out keys which changed by reference only by checking whether the sets differ - const changed = diff.changed.filter(k => arrayHasDiff(lastContent[k], content[k])); - // DM tag changes, refresh relevant rooms - new Set([...diff.added, ...diff.removed, ...changed]).forEach(roomId => { - const room = this.matrixClient?.getRoom(roomId); - if (room) { - this.onRoomUpdate(room); - } - }); - } - }; - protected async reset() { this.rootSpaces = []; - this.orphanedRooms = new Set(); this.parentMap = new EnhancedMap(); this.notificationStateMap = new Map(); this.spaceFilteredRooms = new Map(); @@ -535,8 +464,6 @@ export class SpaceStoreClass extends AsyncStoreWithClient { this.matrixClient.removeListener("Room", this.onRoom); this.matrixClient.removeListener("Room.myMembership", this.onRoom); this.matrixClient.removeListener("RoomState.events", this.onRoomState); - this.matrixClient.removeListener("Room.accountData", this.onRoomAccountData); - this.matrixClient.removeListener("accountData", this.onAccountData); } await this.reset(); } @@ -546,8 +473,6 @@ export class SpaceStoreClass extends AsyncStoreWithClient { this.matrixClient.on("Room", this.onRoom); this.matrixClient.on("Room.myMembership", this.onRoom); this.matrixClient.on("RoomState.events", this.onRoomState); - this.matrixClient.on("Room.accountData", this.onRoomAccountData); - this.matrixClient.on("accountData", this.onAccountData); await this.onSpaceUpdate(); // trigger an initial update @@ -602,7 +527,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { } } - public getNotificationState(key: SpaceKey): SpaceNotificationState { + public getNotificationState(key: string): SpaceNotificationState { if (this.notificationStateMap.has(key)) { return this.notificationStateMap.get(key); } diff --git a/src/stores/room-list/RoomListStore.ts b/src/stores/room-list/RoomListStore.ts index 6e9216423a..caab46a0c2 100644 --- a/src/stores/room-list/RoomListStore.ts +++ b/src/stores/room-list/RoomListStore.ts @@ -601,11 +601,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient { let rooms = this.matrixClient.getVisibleRooms().filter(r => VisibilityProvider.instance.isRoomVisible(r)); - // if spaces are enabled only consider the prefilter conditions when there are no runtime conditions - // for the search all spaces feature - if (this.prefilterConditions.length > 0 - && (!SettingsStore.getValue("feature_spaces") || !this.filterConditions.length) - ) { + if (this.prefilterConditions.length > 0) { rooms = rooms.filter(r => { for (const filter of this.prefilterConditions) { if (!filter.isVisible(r)) { @@ -679,10 +675,6 @@ export class RoomListStoreClass extends AsyncStoreWithClient { if (this.algorithm) { this.algorithm.addFilterCondition(filter); } - // Runtime filters with spaces disable prefiltering for the search all spaces effect - if (SettingsStore.getValue("feature_spaces")) { - promise = this.recalculatePrefiltering(); - } } promise.then(() => this.updateFn.trigger()); } @@ -706,10 +698,6 @@ export class RoomListStoreClass extends AsyncStoreWithClient { if (this.algorithm) { this.algorithm.removeFilterCondition(filter); - // Runtime filters with spaces disable prefiltering for the search all spaces effect - if (SettingsStore.getValue("feature_spaces")) { - promise = this.recalculatePrefiltering(); - } } } idx = this.prefilterConditions.indexOf(filter); diff --git a/src/stores/room-list/SpaceWatcher.ts b/src/stores/room-list/SpaceWatcher.ts index 13e1d83901..0b1b78bc75 100644 --- a/src/stores/room-list/SpaceWatcher.ts +++ b/src/stores/room-list/SpaceWatcher.ts @@ -24,26 +24,34 @@ import SpaceStore, { UPDATE_SELECTED_SPACE } from "../SpaceStore"; * Watches for changes in spaces to manage the filter on the provided RoomListStore */ export class SpaceWatcher { - private filter = new SpaceFilterCondition(); + private filter: SpaceFilterCondition; private activeSpace: Room = SpaceStore.instance.activeSpace; constructor(private store: RoomListStoreClass) { - this.updateFilter(); // get the filter into a consistent state - store.addFilter(this.filter); SpaceStore.instance.on(UPDATE_SELECTED_SPACE, this.onSelectedSpaceUpdated); } - private onSelectedSpaceUpdated = (activeSpace: Room) => { + private onSelectedSpaceUpdated = (activeSpace?: Room) => { this.activeSpace = activeSpace; - this.updateFilter(); + + if (this.filter) { + if (activeSpace) { + this.updateFilter(); + } else { + this.store.removeFilter(this.filter); + this.filter = null; + } + } else if (activeSpace) { + this.filter = new SpaceFilterCondition(); + this.updateFilter(); + this.store.addFilter(this.filter); + } }; private updateFilter = () => { - if (this.activeSpace) { - SpaceStore.instance.traverseSpace(this.activeSpace.roomId, roomId => { - this.store.matrixClient?.getRoom(roomId)?.loadMembersIfNeeded(); - }); - } + SpaceStore.instance.traverseSpace(this.activeSpace.roomId, roomId => { + this.store.matrixClient?.getRoom(roomId)?.loadMembersIfNeeded(); + }); this.filter.updateSpace(this.activeSpace); }; } diff --git a/src/stores/room-list/filters/SpaceFilterCondition.ts b/src/stores/room-list/filters/SpaceFilterCondition.ts index 43bdcb3879..6a06bee0d8 100644 --- a/src/stores/room-list/filters/SpaceFilterCondition.ts +++ b/src/stores/room-list/filters/SpaceFilterCondition.ts @@ -19,7 +19,7 @@ import { Room } from "matrix-js-sdk/src/models/room"; import { FILTER_CHANGED, FilterKind, IFilterCondition } from "./IFilterCondition"; import { IDestroyable } from "../../../utils/IDestroyable"; -import SpaceStore, {HOME_SPACE} from "../../SpaceStore"; +import SpaceStore from "../../SpaceStore"; import { setHasDiff } from "../../../utils/sets"; /** @@ -55,10 +55,12 @@ export class SpaceFilterCondition extends EventEmitter implements IFilterConditi } }; - private getSpaceEventKey = (space: Room | null) => space ? space.roomId : HOME_SPACE; + private getSpaceEventKey = (space: Room) => space.roomId; public updateSpace(space: Room) { - SpaceStore.instance.off(this.getSpaceEventKey(this.space), this.onStoreUpdate); + if (this.space) { + SpaceStore.instance.off(this.getSpaceEventKey(this.space), this.onStoreUpdate); + } SpaceStore.instance.on(this.getSpaceEventKey(this.space = space), this.onStoreUpdate); this.onStoreUpdate(); // initial update from the change to the space } From 6e0c7611c35ecb9664da0c48c153b103d71751a9 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 6 May 2021 13:53:27 +0100 Subject: [PATCH 05/26] Extract blob-safe MIME types --- src/utils/DecryptFile.ts | 63 ++------------------------------ src/utils/blobs.ts | 78 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 60 deletions(-) create mode 100644 src/utils/blobs.ts diff --git a/src/utils/DecryptFile.ts b/src/utils/DecryptFile.ts index 93cedbc707..d073393170 100644 --- a/src/utils/DecryptFile.ts +++ b/src/utils/DecryptFile.ts @@ -17,63 +17,8 @@ limitations under the License. // Pull in the encryption lib so that we can decrypt attachments. import encrypt from 'browser-encrypt-attachment'; import {mediaFromContent} from "../customisations/Media"; -import {IEncryptedFile} from "../customisations/models/IMediaEventContent"; - -// WARNING: We have to be very careful about what mime-types we allow into blobs, -// as for performance reasons these are now rendered via URL.createObjectURL() -// rather than by converting into data: URIs. -// -// This means that the content is rendered using the origin of the script which -// called createObjectURL(), and so if the content contains any scripting then it -// will pose a XSS vulnerability when the browser renders it. This is particularly -// bad if the user right-clicks the URI and pastes it into a new window or tab, -// as the blob will then execute with access to Element's full JS environment(!) -// -// See https://github.com/matrix-org/matrix-react-sdk/pull/1820#issuecomment-385210647 -// for details. -// -// We mitigate this by only allowing mime-types into blobs which we know don't -// contain any scripting, and instantiate all others as application/octet-stream -// regardless of what mime-type the event claimed. Even if the payload itself -// is some malicious HTML, the fact we instantiate it with a media mimetype or -// application/octet-stream means the browser doesn't try to render it as such. -// -// One interesting edge case is image/svg+xml, which empirically *is* rendered -// correctly if the blob is set to the src attribute of an img tag (for thumbnails) -// *even if the mimetype is application/octet-stream*. However, empirically JS -// in the SVG isn't executed in this scenario, so we seem to be okay. -// -// Tested on Chrome 65 and Firefox 60 -// -// The list below is taken mainly from -// https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats -// N.B. Matrix doesn't currently specify which mimetypes are valid in given -// events, so we pick the ones which HTML5 browsers should be able to display -// -// For the record, mime-types which must NEVER enter this list below include: -// text/html, text/xhtml, image/svg, image/svg+xml, image/pdf, and similar. - -const ALLOWED_BLOB_MIMETYPES = [ - 'image/jpeg', - 'image/gif', - 'image/png', - - 'video/mp4', - 'video/webm', - 'video/ogg', - - 'audio/mp4', - 'audio/webm', - 'audio/aac', - 'audio/mpeg', - 'audio/ogg', - 'audio/wave', - 'audio/wav', - 'audio/x-wav', - 'audio/x-pn-wav', - 'audio/flac', - 'audio/x-flac', -]; +import { IEncryptedFile } from "../customisations/models/IMediaEventContent"; +import { getBlobSafeMimeType } from "./blobs"; /** * Decrypt a file attached to a matrix event. @@ -100,9 +45,7 @@ export function decryptFile(file: IEncryptedFile): Promise { // browser (e.g. by copying the URI into a new tab or window.) // See warning at top of file. let mimetype = file.mimetype ? file.mimetype.split(";")[0].trim() : ''; - if (!ALLOWED_BLOB_MIMETYPES.includes(mimetype)) { - mimetype = 'application/octet-stream'; - } + mimetype = getBlobSafeMimeType(mimetype); return new Blob([dataArray], {type: mimetype}); }); diff --git a/src/utils/blobs.ts b/src/utils/blobs.ts new file mode 100644 index 0000000000..4e073a3936 --- /dev/null +++ b/src/utils/blobs.ts @@ -0,0 +1,78 @@ +/* +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. +*/ + +// WARNING: We have to be very careful about what mime-types we allow into blobs, +// as for performance reasons these are now rendered via URL.createObjectURL() +// rather than by converting into data: URIs. +// +// This means that the content is rendered using the origin of the script which +// called createObjectURL(), and so if the content contains any scripting then it +// will pose a XSS vulnerability when the browser renders it. This is particularly +// bad if the user right-clicks the URI and pastes it into a new window or tab, +// as the blob will then execute with access to Element's full JS environment(!) +// +// See https://github.com/matrix-org/matrix-react-sdk/pull/1820#issuecomment-385210647 +// for details. +// +// We mitigate this by only allowing mime-types into blobs which we know don't +// contain any scripting, and instantiate all others as application/octet-stream +// regardless of what mime-type the event claimed. Even if the payload itself +// is some malicious HTML, the fact we instantiate it with a media mimetype or +// application/octet-stream means the browser doesn't try to render it as such. +// +// One interesting edge case is image/svg+xml, which empirically *is* rendered +// correctly if the blob is set to the src attribute of an img tag (for thumbnails) +// *even if the mimetype is application/octet-stream*. However, empirically JS +// in the SVG isn't executed in this scenario, so we seem to be okay. +// +// Tested on Chrome 65 and Firefox 60 +// +// The list below is taken mainly from +// https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats +// N.B. Matrix doesn't currently specify which mimetypes are valid in given +// events, so we pick the ones which HTML5 browsers should be able to display +// +// For the record, mime-types which must NEVER enter this list below include: +// text/html, text/xhtml, image/svg, image/svg+xml, image/pdf, and similar. + +const ALLOWED_BLOB_MIMETYPES = [ + 'image/jpeg', + 'image/gif', + 'image/png', + + 'video/mp4', + 'video/webm', + 'video/ogg', + + 'audio/mp4', + 'audio/webm', + 'audio/aac', + 'audio/mpeg', + 'audio/ogg', + 'audio/wave', + 'audio/wav', + 'audio/x-wav', + 'audio/x-pn-wav', + 'audio/flac', + 'audio/x-flac', +]; + +export function getBlobSafeMimeType(mimetype: string): string { + if (!ALLOWED_BLOB_MIMETYPES.includes(mimetype)) { + return 'application/octet-stream'; + } + return mimetype; +} From 437f13cf764cfcc289bddb758f6eff73f4c93649 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 6 May 2021 14:11:34 +0100 Subject: [PATCH 06/26] Convert UploadConfirmDialog to TSX --- ...nfirmDialog.js => UploadConfirmDialog.tsx} | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) rename src/components/views/dialogs/{UploadConfirmDialog.js => UploadConfirmDialog.tsx} (80%) diff --git a/src/components/views/dialogs/UploadConfirmDialog.js b/src/components/views/dialogs/UploadConfirmDialog.tsx similarity index 80% rename from src/components/views/dialogs/UploadConfirmDialog.js rename to src/components/views/dialogs/UploadConfirmDialog.tsx index 2ff16b9440..8fdfbfda12 100644 --- a/src/components/views/dialogs/UploadConfirmDialog.js +++ b/src/components/views/dialogs/UploadConfirmDialog.tsx @@ -1,5 +1,5 @@ /* -Copyright 2019 New Vector Ltd +Copyright 2019, 2021 The Matrix.org Foundation C.I.C. Copyright 2019 Michael Telatynski <7t3chguy@gmail.com> Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,20 +16,21 @@ limitations under the License. */ import React from 'react'; -import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import filesize from "filesize"; -import {replaceableComponent} from "../../../utils/replaceableComponent"; +import { replaceableComponent } from "../../../utils/replaceableComponent"; + +interface IProps { + file: File; + currentIndex: number; + totalFiles?: number; + onFinished: (uploadConfirmed: boolean, uploadAll?: boolean) => void; +} @replaceableComponent("views.dialogs.UploadConfirmDialog") -export default class UploadConfirmDialog extends React.Component { - static propTypes = { - file: PropTypes.object.isRequired, - currentIndex: PropTypes.number, - totalFiles: PropTypes.number, - onFinished: PropTypes.func.isRequired, - } +export default class UploadConfirmDialog extends React.Component { + private objectUrl: string; static defaultProps = { totalFiles: 1, @@ -38,22 +39,22 @@ export default class UploadConfirmDialog extends React.Component { constructor(props) { super(props); - this._objectUrl = URL.createObjectURL(props.file); + this.objectUrl = URL.createObjectURL(props.file); } componentWillUnmount() { - if (this._objectUrl) URL.revokeObjectURL(this._objectUrl); + if (this.objectUrl) URL.revokeObjectURL(this.objectUrl); } - _onCancelClick = () => { + private onCancelClick = () => { this.props.onFinished(false); } - _onUploadClick = () => { + private onUploadClick = () => { this.props.onFinished(true); } - _onUploadAllClick = () => { + private onUploadAllClick = () => { this.props.onFinished(true, true); } @@ -78,7 +79,7 @@ export default class UploadConfirmDialog extends React.Component { if (this.props.file.type.startsWith('image/')) { preview =
-
+
{this.props.file.name} ({filesize(this.props.file.size)})
; @@ -95,7 +96,7 @@ export default class UploadConfirmDialog extends React.Component { let uploadAllButton; if (this.props.currentIndex + 1 < this.props.totalFiles) { - uploadAllButton = ; } @@ -103,7 +104,7 @@ export default class UploadConfirmDialog extends React.Component { return ( @@ -113,7 +114,7 @@ export default class UploadConfirmDialog extends React.Component { {uploadAllButton} From dc50d27985a94a2e8f5290e4ac645461f0d272af Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 6 May 2021 14:39:44 +0100 Subject: [PATCH 07/26] Adjust MIME type of upload confirmation if needed This filters the MIME type of uploaded files to ensure we display safely. --- src/components/views/dialogs/UploadConfirmDialog.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/UploadConfirmDialog.tsx b/src/components/views/dialogs/UploadConfirmDialog.tsx index 8fdfbfda12..7f6bcd27d1 100644 --- a/src/components/views/dialogs/UploadConfirmDialog.tsx +++ b/src/components/views/dialogs/UploadConfirmDialog.tsx @@ -20,6 +20,7 @@ import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import filesize from "filesize"; import { replaceableComponent } from "../../../utils/replaceableComponent"; +import { getBlobSafeMimeType } from '../../../utils/blobs'; interface IProps { file: File; @@ -31,6 +32,7 @@ interface IProps { @replaceableComponent("views.dialogs.UploadConfirmDialog") export default class UploadConfirmDialog extends React.Component { private objectUrl: string; + private mimeType: string; static defaultProps = { totalFiles: 1, @@ -39,7 +41,13 @@ export default class UploadConfirmDialog extends React.Component { constructor(props) { super(props); - this.objectUrl = URL.createObjectURL(props.file); + // Create a fresh `Blob` for previewing (even though `File` already is + // one) so we can adjust the MIME type if needed. + this.mimeType = getBlobSafeMimeType(props.file.type); + const blob = new Blob([props.file], { type: + this.mimeType, + }); + this.objectUrl = URL.createObjectURL(blob); } componentWillUnmount() { @@ -76,7 +84,7 @@ export default class UploadConfirmDialog extends React.Component { } let preview; - if (this.props.file.type.startsWith('image/')) { + if (this.mimeType.startsWith('image/')) { preview =
From bb9803a94ec83bb375e4b0c7df9c1b9572d2ff93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 6 May 2021 16:40:33 +0200 Subject: [PATCH 08/26] Don't try to use the event's metadata to calc the scale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That has lead to https://github.com/vector-im/element-web/issues/17184 Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/ImageView.tsx b/src/components/views/elements/ImageView.tsx index 05d487a9eb..2b3ead3940 100644 --- a/src/components/views/elements/ImageView.tsx +++ b/src/components/views/elements/ImageView.tsx @@ -108,8 +108,6 @@ export default class ImageView extends React.Component { window.addEventListener("resize", this.calculateZoom); // After the image loads for the first time we want to calculate the zoom this.image.current.addEventListener("load", this.calculateZoom); - // Try to precalculate the zoom from width and height props - this.calculateZoom(); } componentWillUnmount() { @@ -122,8 +120,8 @@ export default class ImageView extends React.Component { const image = this.image.current; const imageWrapper = this.imageWrapper.current; - const width = this.props.width || image.naturalWidth; - const height = this.props.height || image.naturalHeight; + const width = image.naturalWidth; + const height = image.naturalHeight; const zoomX = imageWrapper.clientWidth / width; const zoomY = imageWrapper.clientHeight / height; From 7ad270928ab9b94a38463484b07458fe74fa3c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 6 May 2021 16:41:09 +0200 Subject: [PATCH 09/26] Simplifie code a bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/components/views/elements/ImageView.tsx b/src/components/views/elements/ImageView.tsx index 2b3ead3940..f736736acc 100644 --- a/src/components/views/elements/ImageView.tsx +++ b/src/components/views/elements/ImageView.tsx @@ -120,11 +120,8 @@ export default class ImageView extends React.Component { const image = this.image.current; const imageWrapper = this.imageWrapper.current; - const width = image.naturalWidth; - const height = image.naturalHeight; - - const zoomX = imageWrapper.clientWidth / width; - const zoomY = imageWrapper.clientHeight / height; + const zoomX = imageWrapper.clientWidth / image.naturalWidth; + const zoomY = imageWrapper.clientHeight / image.naturalHeight; // If the image is smaller in both dimensions set its the zoom to 1 to // display it in its original size From 5d7535738ab6001ab581d47621d75171df6da413 Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Thu, 6 May 2021 20:01:48 -0500 Subject: [PATCH 10/26] Show device ID in UserInfo when there is no device name Signed-off-by: Aaron Raimist --- src/components/views/right_panel/UserInfo.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/views/right_panel/UserInfo.tsx b/src/components/views/right_panel/UserInfo.tsx index be152d91bd..e50e71535d 100644 --- a/src/components/views/right_panel/UserInfo.tsx +++ b/src/components/views/right_panel/UserInfo.tsx @@ -187,9 +187,15 @@ function DeviceItem({userId, device}: {userId: string, device: IDevice}) { verifyDevice(cli.getUser(userId), device); }; - const deviceName = device.ambiguous ? - (device.getDisplayName() ? device.getDisplayName() : "") + " (" + device.deviceId + ")" : - device.getDisplayName(); + let deviceName; + if (device.getDisplayName() === null || device.getDisplayName().trim() === "") { + deviceName = device.deviceId; + } else { + deviceName = device.ambiguous ? + device.getDisplayName() + " (" + device.deviceId + ")" : + device.getDisplayName(); + } + let trustedLabel = null; if (userTrust.isVerified()) trustedLabel = isVerified ? _t("Trusted") : _t("Not trusted"); From 4079b03ae00d997eb363f4f3e0d20b7ad63594a2 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 7 May 2021 10:39:35 +0100 Subject: [PATCH 11/26] Bring back filter all spaces behaviour --- src/components/structures/RoomSearch.tsx | 20 +++++++++++++++++-- .../views/rooms/RoomListNumResults.tsx | 6 +++++- src/stores/room-list/RoomListStore.ts | 18 +++++++++++++++-- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/components/structures/RoomSearch.tsx b/src/components/structures/RoomSearch.tsx index b3ceb1588f..bda46aef07 100644 --- a/src/components/structures/RoomSearch.tsx +++ b/src/components/structures/RoomSearch.tsx @@ -17,6 +17,7 @@ limitations under the License. import * as React from "react"; import { createRef } from "react"; import classNames from "classnames"; +import { Room } from "matrix-js-sdk/src/models/room"; import defaultDispatcher from "../../dispatcher/dispatcher"; import { _t } from "../../languageHandler"; @@ -27,7 +28,7 @@ import RoomListStore from "../../stores/room-list/RoomListStore"; import { NameFilterCondition } from "../../stores/room-list/filters/NameFilterCondition"; import { getKeyBindingsManager, RoomListAction } from "../../KeyBindingsManager"; import { replaceableComponent } from "../../utils/replaceableComponent"; -import SpaceStore, { UPDATE_SELECTED_SPACE } from "../../stores/SpaceStore"; +import SpaceStore, { UPDATE_SELECTED_SPACE, UPDATE_TOP_LEVEL_SPACES } from "../../stores/SpaceStore"; interface IProps { isMinimized: boolean; @@ -41,6 +42,7 @@ interface IProps { interface IState { query: string; focused: boolean; + inSpaces: boolean; } @replaceableComponent("structures.RoomSearch") @@ -55,11 +57,13 @@ export default class RoomSearch extends React.PureComponent { this.state = { query: "", focused: false, + inSpaces: false, }; this.dispatcherRef = defaultDispatcher.register(this.onAction); // clear filter when changing spaces, in future we may wish to maintain a filter per-space SpaceStore.instance.on(UPDATE_SELECTED_SPACE, this.clearInput); + SpaceStore.instance.on(UPDATE_TOP_LEVEL_SPACES, this.onSpaces); } public componentDidUpdate(prevProps: Readonly, prevState: Readonly): void { @@ -80,8 +84,15 @@ export default class RoomSearch extends React.PureComponent { public componentWillUnmount() { defaultDispatcher.unregister(this.dispatcherRef); SpaceStore.instance.off(UPDATE_SELECTED_SPACE, this.clearInput); + SpaceStore.instance.off(UPDATE_TOP_LEVEL_SPACES, this.onSpaces); } + private onSpaces = (spaces: Room[]) => { + this.setState({ + inSpaces: spaces.length > 0, + }); + }; + private onAction = (payload: ActionPayload) => { if (payload.action === 'view_room' && payload.clear_search) { this.clearInput(); @@ -153,6 +164,11 @@ export default class RoomSearch extends React.PureComponent { 'mx_RoomSearch_inputExpanded': this.state.query || this.state.focused, }); + let placeholder = _t("Filter"); + if (this.state.inSpaces) { + placeholder = _t("Filter all spaces"); + } + let icon = (
); @@ -166,7 +182,7 @@ export default class RoomSearch extends React.PureComponent { onBlur={this.onBlur} onChange={this.onChange} onKeyDown={this.onKeyDown} - placeholder={_t("Filter")} + placeholder={placeholder} autoComplete="off" /> ); diff --git a/src/components/views/rooms/RoomListNumResults.tsx b/src/components/views/rooms/RoomListNumResults.tsx index 4215e5644c..01cbecf05d 100644 --- a/src/components/views/rooms/RoomListNumResults.tsx +++ b/src/components/views/rooms/RoomListNumResults.tsx @@ -19,6 +19,7 @@ import React, {useState} from "react"; import { _t } from "../../../languageHandler"; import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore"; import {useEventEmitter} from "../../../hooks/useEventEmitter"; +import SpaceStore from "../../../stores/SpaceStore"; const RoomListNumResults: React.FC = () => { const [count, setCount] = useState(null); @@ -34,7 +35,10 @@ const RoomListNumResults: React.FC = () => { if (typeof count !== "number") return null; return
- { _t("%(count)s results", { count }) } + { SpaceStore.instance.spacePanelSpaces.length + ? _t("%(count)s results in all spaces", { count }) + : _t("%(count)s results", { count }) + }
; }; diff --git a/src/stores/room-list/RoomListStore.ts b/src/stores/room-list/RoomListStore.ts index caab46a0c2..879ca45f3a 100644 --- a/src/stores/room-list/RoomListStore.ts +++ b/src/stores/room-list/RoomListStore.ts @@ -601,7 +601,11 @@ export class RoomListStoreClass extends AsyncStoreWithClient { let rooms = this.matrixClient.getVisibleRooms().filter(r => VisibilityProvider.instance.isRoomVisible(r)); - if (this.prefilterConditions.length > 0) { + // if spaces are enabled only consider the prefilter conditions when there are no runtime conditions + // for the search all spaces feature + if (this.prefilterConditions.length > 0 + && (!SettingsStore.getValue("feature_spaces") || !this.filterConditions.length) + ) { rooms = rooms.filter(r => { for (const filter of this.prefilterConditions) { if (!filter.isVisible(r)) { @@ -660,7 +664,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient { * and thus might not cause an update to the store immediately. * @param {IFilterCondition} filter The filter condition to add. */ - public addFilter(filter: IFilterCondition): void { + public async addFilter(filter: IFilterCondition): Promise { if (SettingsStore.getValue("advancedRoomListLogging")) { // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602 console.log("Adding filter condition:", filter); @@ -672,6 +676,12 @@ export class RoomListStoreClass extends AsyncStoreWithClient { promise = this.recalculatePrefiltering(); } else { this.filterConditions.push(filter); + // Runtime filters with spaces disable prefiltering for the search all spaces feature + if (SettingsStore.getValue("feature_spaces")) { + // this has to be awaited so that `setKnownRooms` is called in time for the `addFilterCondition` below + // this way the runtime filters are only evaluated on one dataset and not both. + await this.recalculatePrefiltering(); + } if (this.algorithm) { this.algorithm.addFilterCondition(filter); } @@ -699,6 +709,10 @@ export class RoomListStoreClass extends AsyncStoreWithClient { if (this.algorithm) { this.algorithm.removeFilterCondition(filter); } + // Runtime filters with spaces disable prefiltering for the search all spaces feature + if (SettingsStore.getValue("feature_spaces")) { + promise = this.recalculatePrefiltering(); + } } idx = this.prefilterConditions.indexOf(filter); if (idx >= 0) { From 57be07481103fd016b3e1e5912cba5f4fbbddd49 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 7 May 2021 10:48:03 +0100 Subject: [PATCH 12/26] i18n --- src/i18n/strings/en_EN.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index cb60545872..de06772583 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1554,6 +1554,8 @@ "Explore all public rooms": "Explore all public rooms", "Quick actions": "Quick actions", "Use the + to make a new room or explore existing ones below": "Use the + to make a new room or explore existing ones below", + "%(count)s results in all spaces|other": "%(count)s results in all spaces", + "%(count)s results in all spaces|one": "%(count)s result in all spaces", "%(count)s results|other": "%(count)s results", "%(count)s results|one": "%(count)s result", "This room": "This room", @@ -2619,6 +2621,7 @@ "If you can't find the room you're looking for, ask for an invite or Create a new room.": "If you can't find the room you're looking for, ask for an invite or Create a new room.", "Explore rooms in %(communityName)s": "Explore rooms in %(communityName)s", "Filter": "Filter", + "Filter all spaces": "Filter all spaces", "Clear filter": "Clear filter", "Filter rooms and people": "Filter rooms and people", "You can't send any messages until you review and agree to our terms and conditions.": "You can't send any messages until you review and agree to our terms and conditions.", From 9d9dce7a9135ee4c7510b7a0d7df1183bb84bf3d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 7 May 2021 10:48:55 +0100 Subject: [PATCH 13/26] update orphan room behaviour test to expect new home space behaviour --- test/stores/SpaceStore-test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/stores/SpaceStore-test.ts b/test/stores/SpaceStore-test.ts index aef788647d..ce2def24a1 100644 --- a/test/stores/SpaceStore-test.ts +++ b/test/stores/SpaceStore-test.ts @@ -361,8 +361,8 @@ describe("SpaceStore", () => { expect(store.getSpaceFilteredRoomIds(null).has(invite2)).toBeTruthy(); }); - it("home space does not contain rooms/low priority from rooms within spaces", () => { - expect(store.getSpaceFilteredRoomIds(null).has(room1)).toBeFalsy(); + it("home space does contain rooms/low priority even if they are also shown in a space", () => { + expect(store.getSpaceFilteredRoomIds(null).has(room1)).toBeTruthy(); }); it("space contains child rooms", () => { From f0e61e6286050b88c0f3eca903a6fb8cec3aa265 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 7 May 2021 11:08:18 +0100 Subject: [PATCH 14/26] short circuit automatic switch to related space behaviour and fix tests --- src/stores/SpaceStore.tsx | 2 +- test/stores/SpaceStore-test.ts | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/stores/SpaceStore.tsx b/src/stores/SpaceStore.tsx index 20af6b249b..b1b8199f93 100644 --- a/src/stores/SpaceStore.tsx +++ b/src/stores/SpaceStore.tsx @@ -535,7 +535,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { // Don't context switch when navigating to the space room // as it will cause you to end up in the wrong room this.setActiveSpace(room, false); - } else if (!this.getSpaceFilteredRoomIds(this.activeSpace).has(roomId)) { + } else if (this.activeSpace && !this.getSpaceFilteredRoomIds(this.activeSpace).has(roomId)) { this.switchToRelatedSpace(roomId); } diff --git a/test/stores/SpaceStore-test.ts b/test/stores/SpaceStore-test.ts index ce2def24a1..49fdd7308a 100644 --- a/test/stores/SpaceStore-test.ts +++ b/test/stores/SpaceStore-test.ts @@ -641,14 +641,14 @@ describe("SpaceStore", () => { it("switch to canonical parent space for room", async () => { viewRoom(room1); - await store.setActiveSpace(null, false); + await store.setActiveSpace(client.getRoom(space2), false); viewRoom(room2); expect(store.activeSpace).toBe(client.getRoom(space2)); }); it("switch to first containing space for room", async () => { viewRoom(room2); - await store.setActiveSpace(null, false); + await store.setActiveSpace(client.getRoom(space2), false); viewRoom(room1); expect(store.activeSpace).toBe(client.getRoom(space1)); }); @@ -659,6 +659,13 @@ describe("SpaceStore", () => { viewRoom(orphan1); expect(store.activeSpace).toBeNull(); }); + + it("when switching rooms in the all rooms home space don't switch to related space", async () => { + viewRoom(room2); + await store.setActiveSpace(null, false); + viewRoom(room1); + expect(store.activeSpace).toBeNull(); + }); }); describe("traverseSpace", () => { From 90fa738734165446ff05cd2a7faffa342f2d79e9 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 7 May 2021 11:22:10 +0100 Subject: [PATCH 15/26] Fix that one final pesky test --- test/stores/SpaceStore-test.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/stores/SpaceStore-test.ts b/test/stores/SpaceStore-test.ts index 49fdd7308a..20c48c29db 100644 --- a/test/stores/SpaceStore-test.ts +++ b/test/stores/SpaceStore-test.ts @@ -101,6 +101,7 @@ const invite1 = "!invite1:server"; const invite2 = "!invite2:server"; const room1 = "!room1:server"; const room2 = "!room2:server"; +const room3 = "!room3:server"; const space1 = "!space1:server"; const space2 = "!space2:server"; const space3 = "!space3:server"; @@ -614,8 +615,8 @@ describe("SpaceStore", () => { describe("space auto switching tests", () => { beforeEach(async () => { - [room1, room2, orphan1].forEach(mkRoom); - mkSpace(space1, [room1, room2]); + [room1, room2, room3, orphan1].forEach(mkRoom); + mkSpace(space1, [room1, room2, room3]); mkSpace(space2, [room1, room2]); client.getRoom(room2).currentState.getStateEvents.mockImplementation(mockStateEventImplementation([ @@ -649,7 +650,7 @@ describe("SpaceStore", () => { it("switch to first containing space for room", async () => { viewRoom(room2); await store.setActiveSpace(client.getRoom(space2), false); - viewRoom(room1); + viewRoom(room3); expect(store.activeSpace).toBe(client.getRoom(space1)); }); From 119c14c3f97b3721883dfcabdfe15728ce9a4947 Mon Sep 17 00:00:00 2001 From: Robin Townsend Date: Fri, 7 May 2021 12:49:37 -0400 Subject: [PATCH 16/26] Forbid redaction of encryption events Redacting m.room.encryption events will leave the room in a broken state, and so we shouldn't allow the user to do this. Signed-off-by: Robin Townsend --- src/components/views/context_menus/MessageContextMenu.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index 35efd12c9c..365f2ab1de 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -78,8 +78,10 @@ export default class MessageContextMenu extends React.Component { // We explicitly decline to show the redact option on ACL events as it has a potential // to obliterate the room - https://github.com/matrix-org/synapse/issues/4042 + // Similarly for encryption events, since redacting them "breaks everything" const canRedact = room.currentState.maySendRedactionForEvent(this.props.mxEvent, cli.credentials.userId) - && this.props.mxEvent.getType() !== EventType.RoomServerAcl; + && this.props.mxEvent.getType() !== EventType.RoomServerAcl + && this.props.mxEvent.getType() !== EventType.RoomEncryption; let canPin = room.currentState.mayClientSendStateEvent('m.room.pinned_events', cli); // HACK: Intentionally say we can't pin if the user doesn't want to use the functionality From fa307ee14c68da1f597ee530ccf603bff9bffcd4 Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Fri, 7 May 2021 18:41:47 -0500 Subject: [PATCH 17/26] Update src/components/views/right_panel/UserInfo.tsx Co-authored-by: Michael Telatynski <7t3chguy@googlemail.com> --- 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 e50e71535d..3c35a55395 100644 --- a/src/components/views/right_panel/UserInfo.tsx +++ b/src/components/views/right_panel/UserInfo.tsx @@ -188,7 +188,7 @@ function DeviceItem({userId, device}: {userId: string, device: IDevice}) { }; let deviceName; - if (device.getDisplayName() === null || device.getDisplayName().trim() === "") { + if (!device.getDisplayName()?.trim()) { deviceName = device.deviceId; } else { deviceName = device.ambiguous ? From 70b2f841d9e5727955444a26102c4fe6515f3204 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 9 May 2021 00:09:15 +0000 Subject: [PATCH 18/26] Bump hosted-git-info from 2.8.8 to 2.8.9 Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9. - [Release notes](https://github.com/npm/hosted-git-info/releases) - [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md) - [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9) Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8b4ac35d6a..297d3d8e9d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4226,9 +4226,9 @@ hoist-non-react-statics@^3.3.0: react-is "^16.7.0" hosted-git-info@^2.1.4: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== hosted-git-info@^3.0.6: version "3.0.7" From 9a5a3b30ca004516c28dd713d2587942215a0bbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 6 May 2021 16:40:33 +0200 Subject: [PATCH 19/26] Don't try to use the event's metadata to calc the scale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That has lead to https://github.com/vector-im/element-web/issues/17184 Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/ImageView.tsx b/src/components/views/elements/ImageView.tsx index fcacae2d39..e4cc0b6973 100644 --- a/src/components/views/elements/ImageView.tsx +++ b/src/components/views/elements/ImageView.tsx @@ -108,8 +108,6 @@ export default class ImageView extends React.Component { window.addEventListener("resize", this.calculateZoom); // After the image loads for the first time we want to calculate the zoom this.image.current.addEventListener("load", this.calculateZoom); - // Try to precalculate the zoom from width and height props - this.calculateZoom(); } componentWillUnmount() { @@ -120,8 +118,8 @@ export default class ImageView extends React.Component { const image = this.image.current; const imageWrapper = this.imageWrapper.current; - const width = this.props.width || image.naturalWidth; - const height = this.props.height || image.naturalHeight; + const width = image.naturalWidth; + const height = image.naturalHeight; const zoomX = imageWrapper.clientWidth / width; const zoomY = imageWrapper.clientHeight / height; From 3b97e522468e08dd805d1be6565e0faee2482de7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 6 May 2021 16:41:09 +0200 Subject: [PATCH 20/26] Simplifie code a bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/components/views/elements/ImageView.tsx b/src/components/views/elements/ImageView.tsx index e4cc0b6973..e65fe2cc14 100644 --- a/src/components/views/elements/ImageView.tsx +++ b/src/components/views/elements/ImageView.tsx @@ -118,11 +118,8 @@ export default class ImageView extends React.Component { const image = this.image.current; const imageWrapper = this.imageWrapper.current; - const width = image.naturalWidth; - const height = image.naturalHeight; - - const zoomX = imageWrapper.clientWidth / width; - const zoomY = imageWrapper.clientHeight / height; + const zoomX = imageWrapper.clientWidth / image.naturalWidth; + const zoomY = imageWrapper.clientHeight / image.naturalHeight; // If the image is smaller in both dimensions set its the zoom to 1 to // display it in its original size From a11c3a22c9cc0f29fed396cec1478323c841cf73 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 10 May 2021 14:55:31 +0100 Subject: [PATCH 21/26] Upgrade matrix-js-sdk to 10.1.0 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index f6471327cb..6c798d05f4 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "katex": "^0.12.0", "linkifyjs": "^2.1.9", "lodash": "^4.17.20", - "matrix-js-sdk": "10.1.0-rc.1", + "matrix-js-sdk": "10.1.0", "matrix-widget-api": "^0.1.0-beta.13", "minimist": "^1.2.5", "opus-recorder": "^8.0.3", diff --git a/yarn.lock b/yarn.lock index c1e04a0686..b11fcb0d72 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5671,10 +5671,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@10.1.0-rc.1: - version "10.1.0-rc.1" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-10.1.0-rc.1.tgz#67b04cd30cb3b3c8ee7a3a2ead1db567a99e35c8" - integrity sha512-jpCnSqvNAsVIHv/FRVx1xV11IKcQCd6zUy4cHLDfUH/6GxFDtW/Fk446A7XDIJnNvstqmWBghk4X65hdsfq5OQ== +matrix-js-sdk@10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-10.1.0.tgz#11a78e0330530f78498847c52d390d2a599b029b" + integrity sha512-VR1bwSKOf7jZa9+0UoAsYvyvLsNGBhT/BdxHMgQKuwx34GwZucp3Tqg/Ng2oTK+0b991xkEk4nRvJoCKK++Ulg== dependencies: "@babel/runtime" "^7.12.5" another-json "^0.2.0" From 7f4c525d62be2efe1fe4ef5b964d1588c5e51c04 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 10 May 2021 14:57:35 +0100 Subject: [PATCH 22/26] Switch back to release version of `sanitize-html` The limit depth option has been available in a released version for a while now. --- package.json | 2 +- yarn.lock | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index be195e2e9e..d31a6eb284 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "react-transition-group": "^4.4.1", "resize-observer-polyfill": "^1.5.1", "rfc4648": "^1.4.0", - "sanitize-html": "github:apostrophecms/sanitize-html#3c7f93f2058f696f5359e3e58d464161647226db", + "sanitize-html": "^2.3.2", "tar-js": "^0.3.0", "text-encoding-utf-8": "^1.0.2", "url": "^0.11.0", diff --git a/yarn.lock b/yarn.lock index 297d3d8e9d..c47ed5476c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6307,6 +6307,11 @@ parse-json@^5.0.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse-srcset@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-srcset/-/parse-srcset-1.0.2.tgz#f2bd221f6cc970a938d88556abc589caaaa2bde1" + integrity sha1-8r0iH2zJcKk42IVWq8WJyqqiveE= + parse5-htmlparser2-tree-adapter@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" @@ -7248,17 +7253,18 @@ sane@^4.0.3: minimist "^1.1.1" walker "~1.0.5" -"sanitize-html@github:apostrophecms/sanitize-html#3c7f93f2058f696f5359e3e58d464161647226db": - version "2.0.0-rc.3" - resolved "https://codeload.github.com/apostrophecms/sanitize-html/tar.gz/3c7f93f2058f696f5359e3e58d464161647226db" +sanitize-html@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-2.3.3.tgz#3db382c9a621cce4c46d90f10c64f1e9da9e8353" + integrity sha512-DCFXPt7Di0c6JUnlT90eIgrjs6TsJl/8HYU3KLdmrVclFN4O0heTcVbJiMa23OKVr6aR051XYtsgd8EWwEBwUA== dependencies: deepmerge "^4.2.2" escape-string-regexp "^4.0.0" - htmlparser2 "^4.1.0" + htmlparser2 "^6.0.0" is-plain-object "^5.0.0" klona "^2.0.3" + parse-srcset "^1.0.2" postcss "^8.0.2" - srcset "^3.0.0" saxes@^5.0.0: version "5.0.1" @@ -7515,11 +7521,6 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -srcset@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/srcset/-/srcset-3.0.0.tgz#8afd8b971362dfc129ae9c1a99b3897301ce6441" - integrity sha512-D59vF08Qzu/C4GAOXVgMTLfgryt5fyWo93FZyhEWANo0PokFz/iWdDe13mX3O5TRf6l8vMTqckAfR4zPiaH0yQ== - sshpk@^1.7.0: version "1.16.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" From a1572e9ea3e7fb0099a0dd8cebfc86de5ad77328 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 10 May 2021 15:02:07 +0100 Subject: [PATCH 23/26] Prepare changelog for v3.20.0 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc6c0b7f76..58d23e3413 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +Changes in [3.20.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.20.0) (2021-05-10) +===================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.20.0-rc.1...v3.20.0) + + * Upgrade to JS SDK 10.1.0 + * [Release] Don't use the event's metadata to calc the scale of an image + [\#6004](https://github.com/matrix-org/matrix-react-sdk/pull/6004) + Changes in [3.20.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.20.0-rc.1) (2021-05-04) =============================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.19.0...v3.20.0-rc.1) From f68013524cf3dbd99068486214a78e9afdce0406 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 10 May 2021 15:02:08 +0100 Subject: [PATCH 24/26] v3.20.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6c798d05f4..e8fac14290 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "3.20.0-rc.1", + "version": "3.20.0", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 82642f17fd8e36a81944c9a8a4a14addce80c02d Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 10 May 2021 15:22:30 +0100 Subject: [PATCH 25/26] Resetting package fields for development --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index cb9a8aa887..172681dff3 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "bin": { "reskindex": "scripts/reskindex.js" }, - "main": "./lib/index.js", + "main": "./src/index.js", "matrix_src_main": "./src/index.js", "matrix_lib_main": "./lib/index.js", "matrix_lib_typings": "./lib/index.d.ts", @@ -197,6 +197,5 @@ "coverageReporters": [ "text" ] - }, - "typings": "./lib/index.d.ts" + } } From 1b372b17e039db98a9dba34ba90e25e5433b1aec Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 10 May 2021 15:23:03 +0100 Subject: [PATCH 26/26] 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 172681dff3..342591081f 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "katex": "^0.12.0", "linkifyjs": "^2.1.9", "lodash": "^4.17.20", - "matrix-js-sdk": "10.1.0", + "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop", "matrix-widget-api": "^0.1.0-beta.13", "minimist": "^1.2.5", "opus-recorder": "^8.0.3", diff --git a/yarn.lock b/yarn.lock index c5477c30b0..0d9b2bdd3f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5676,10 +5676,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@10.1.0: +"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop": version "10.1.0" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-10.1.0.tgz#11a78e0330530f78498847c52d390d2a599b029b" - integrity sha512-VR1bwSKOf7jZa9+0UoAsYvyvLsNGBhT/BdxHMgQKuwx34GwZucp3Tqg/Ng2oTK+0b991xkEk4nRvJoCKK++Ulg== + resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/2d73805ca3d8c5a140fe05e574f826696de1656a" dependencies: "@babel/runtime" "^7.12.5" another-json "^0.2.0"