From 6a5ea970e940bb53671103fe222f0d2220db114b Mon Sep 17 00:00:00 2001
From: Panagiotis <27917356+panoschal@users.noreply.github.com>
Date: Sat, 13 Mar 2021 15:20:42 +0200
Subject: [PATCH 01/28] fix: make call area smaller on small screens
so that it doesn't need a scrollbar
---
res/css/views/voip/_CallView.scss | 3 +++
1 file changed, 3 insertions(+)
diff --git a/res/css/views/voip/_CallView.scss b/res/css/views/voip/_CallView.scss
index 7eb329594a..4ade5d90f8 100644
--- a/res/css/views/voip/_CallView.scss
+++ b/res/css/views/voip/_CallView.scss
@@ -30,6 +30,9 @@ limitations under the License.
.mx_CallView_voice {
height: 360px;
+ @media only screen and (max-height: 768px) {
+ height: 300px;
+ }
}
}
From 879dd6eaeac1c91c66ed9329e382c830ad92cd21 Mon Sep 17 00:00:00 2001
From: Panagiotis <27917356+panoschal@users.noreply.github.com>
Date: Sat, 13 Mar 2021 15:24:26 +0200
Subject: [PATCH 02/28] fix: make status bar area not show when it is undefined
e.g. when user is in call, and there are search results
---
src/components/structures/RoomView.tsx | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx
index 706cd5ded8..2fdb193389 100644
--- a/src/components/structures/RoomView.tsx
+++ b/src/components/structures/RoomView.tsx
@@ -1841,6 +1841,17 @@ export default class RoomView extends React.Component {
/>;
}
+ const statusBarAreaClass = classNames("mx_RoomView_statusArea", {
+ "mx_RoomView_statusArea_expanded": isStatusAreaExpanded,
+ });
+
+ const statusBarArea = statusBar &&
+
const roomVersionRecommendation = this.state.upgradeRecommendation;
const showRoomUpgradeBar = (
roomVersionRecommendation &&
@@ -2052,10 +2063,6 @@ export default class RoomView extends React.Component {
/>);
}
- const statusBarAreaClass = classNames("mx_RoomView_statusArea", {
- "mx_RoomView_statusArea_expanded": isStatusAreaExpanded,
- });
-
const showRightPanel = this.state.room && this.state.showRightPanel;
const rightPanel = showRightPanel
?
@@ -2104,12 +2111,7 @@ export default class RoomView extends React.Component {
{messagePanel}
{searchResultsPanel}
-
+ {statusBarArea}
{previewBar}
{messageComposer}
From 4d2ecc98b0c4d0d9e5a357e930203b6c917ccb8c Mon Sep 17 00:00:00 2001
From: Panagiotis <27917356+panoschal@users.noreply.github.com>
Date: Sat, 13 Mar 2021 19:11:57 +0200
Subject: [PATCH 03/28] fix: decrease the size of CallView on smaller screens
so that when the user opens the search box, it does not disappear, and AuxPanel does not need an awkward scrollbar
---
res/css/views/voip/_CallView.scss | 2 +-
src/components/views/voip/CallView.tsx | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/res/css/views/voip/_CallView.scss b/res/css/views/voip/_CallView.scss
index 4ade5d90f8..7f01aecbcd 100644
--- a/res/css/views/voip/_CallView.scss
+++ b/res/css/views/voip/_CallView.scss
@@ -31,7 +31,7 @@ limitations under the License.
.mx_CallView_voice {
height: 360px;
@media only screen and (max-height: 768px) {
- height: 300px;
+ height: 220px;
}
}
}
diff --git a/src/components/views/voip/CallView.tsx b/src/components/views/voip/CallView.tsx
index 9bdc8fb11d..762a2bb941 100644
--- a/src/components/views/voip/CallView.tsx
+++ b/src/components/views/voip/CallView.tsx
@@ -538,7 +538,8 @@ export default class CallView extends React.Component {
{callControls}
;
} else {
- const avatarSize = this.props.pipMode ? 76 : 160;
+ const normalAvatarSize = window.innerHeight <= 768 ? 120 : 160;
+ const avatarSize = this.props.pipMode ? 76 : normalAvatarSize;
const classes = classNames({
mx_CallView_voice: true,
mx_CallView_voice_hold: isOnHold,
From e5794a4c80a3c9fe8f4e02e2f25a18220e5d4a8e Mon Sep 17 00:00:00 2001
From: Panagiotis <27917356+panoschal@users.noreply.github.com>
Date: Sat, 13 Mar 2021 19:52:59 +0200
Subject: [PATCH 04/28] linter
---
res/css/views/voip/_CallView.scss | 1 +
1 file changed, 1 insertion(+)
diff --git a/res/css/views/voip/_CallView.scss b/res/css/views/voip/_CallView.scss
index 7f01aecbcd..c7e2456a16 100644
--- a/res/css/views/voip/_CallView.scss
+++ b/res/css/views/voip/_CallView.scss
@@ -30,6 +30,7 @@ limitations under the License.
.mx_CallView_voice {
height: 360px;
+
@media only screen and (max-height: 768px) {
height: 220px;
}
From e9efc9571297c8bfc381825a19190dfd0043bb71 Mon Sep 17 00:00:00 2001
From: Panagiotis <27917356+panoschal@users.noreply.github.com>
Date: Sat, 24 Jul 2021 16:10:51 +0300
Subject: [PATCH 05/28] lint
---
src/components/structures/RoomView.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx
index 5e39c6af79..76158e6392 100644
--- a/src/components/structures/RoomView.tsx
+++ b/src/components/structures/RoomView.tsx
@@ -1856,8 +1856,8 @@ export default class RoomView extends React.Component {
{statusBar}
-
-
+ ;
+
const roomVersionRecommendation = this.state.upgradeRecommendation;
const showRoomUpgradeBar = (
roomVersionRecommendation &&
From 153eb05561fd4a36b402dd05d45c00dd4d7b6603 Mon Sep 17 00:00:00 2001
From: Panagiotis <27917356+panoschal@users.noreply.github.com>
Date: Sat, 24 Jul 2021 19:00:47 +0300
Subject: [PATCH 06/28] lint
---
src/components/structures/RoomView.tsx | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx
index 76158e6392..2c934ecfb6 100644
--- a/src/components/structures/RoomView.tsx
+++ b/src/components/structures/RoomView.tsx
@@ -1854,7 +1854,7 @@ export default class RoomView extends React.Component {
const statusBarArea = statusBar &&
- {statusBar}
+ { statusBar }
;
@@ -2101,9 +2101,9 @@ export default class RoomView extends React.Component {
{ messagePanel }
{ searchResultsPanel }
- {statusBarArea}
- {previewBar}
- {messageComposer}
+ { statusBarArea }
+ { previewBar }
+ { messageComposer }
From 1c7a89b2e4b36b4e23d8c358ccf6db6cb1ee5580 Mon Sep 17 00:00:00 2001
From: Panagiotis <27917356+panoschal@users.noreply.github.com>
Date: Sun, 8 Aug 2021 21:00:15 +0300
Subject: [PATCH 07/28] add comment - explain conditional statusBar
---
src/components/structures/RoomView.tsx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx
index 69d4cfc590..781fb94ddc 100644
--- a/src/components/structures/RoomView.tsx
+++ b/src/components/structures/RoomView.tsx
@@ -1852,6 +1852,8 @@ export default class RoomView extends React.Component {
"mx_RoomView_statusArea_expanded": isStatusAreaExpanded,
});
+ // if statusBar does not exist then statusBarArea is blank and takes up unnecessary space on the screen
+ // show statusBarArea only if statusBar is present
const statusBarArea = statusBar &&
From 072fdf1cb8c4895b1914fa44e054c06933a62dea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=A0imon=20Brandner?=
Date: Sat, 28 Aug 2021 15:06:48 +0200
Subject: [PATCH 08/28] Use disptacher so that
https://github.com/matrix-org/matrix-react-sdk/pull/6691 has effect
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Šimon Brandner
---
src/components/structures/CallEventGrouper.ts | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/components/structures/CallEventGrouper.ts b/src/components/structures/CallEventGrouper.ts
index b48bb32efe..16f8d6c68d 100644
--- a/src/components/structures/CallEventGrouper.ts
+++ b/src/components/structures/CallEventGrouper.ts
@@ -108,24 +108,34 @@ export default class CallEventGrouper extends EventEmitter {
return [...this.events][0].getContent().call_id;
}
+ private get roomId(): string {
+ return [...this.events][0]?.getRoomId();
+ }
+
private onSilencedCallsChanged = () => {
const newState = CallHandler.sharedInstance().isCallSilenced(this.callId);
this.emit(CallEventGrouperEvent.SilencedChanged, newState);
};
public answerCall = () => {
- this.call?.answer();
+ defaultDispatcher.dispatch({
+ action: 'answer',
+ room_id: this.roomId,
+ });
};
public rejectCall = () => {
- this.call?.reject();
+ defaultDispatcher.dispatch({
+ action: 'reject',
+ room_id: this.roomId,
+ });
};
public callBack = () => {
defaultDispatcher.dispatch({
action: 'place_call',
type: this.isVoice ? CallType.Voice : CallType.Video,
- room_id: [...this.events][0]?.getRoomId(),
+ room_id: this.roomId,
});
};
From 367049bd086342207197bb519930c7915d9ccff7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=A0imon=20Brandner?=
Date: Thu, 2 Sep 2021 17:52:00 +0200
Subject: [PATCH 09/28] Improve typing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Šimon Brandner
---
src/components/structures/CallEventGrouper.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/components/structures/CallEventGrouper.ts b/src/components/structures/CallEventGrouper.ts
index 16f8d6c68d..a19392b8fc 100644
--- a/src/components/structures/CallEventGrouper.ts
+++ b/src/components/structures/CallEventGrouper.ts
@@ -104,11 +104,11 @@ export default class CallEventGrouper extends EventEmitter {
return ![...this.events].some((event) => event.sender?.userId === MatrixClientPeg.get().getUserId());
}
- private get callId(): string {
- return [...this.events][0].getContent().call_id;
+ private get callId(): string | undefined {
+ return [...this.events][0]?.getContent()?.call_id;
}
- private get roomId(): string {
+ private get roomId(): string | undefined {
return [...this.events][0]?.getRoomId();
}
From 40f9302ec952904ebcc5ac9017e8ec32951dc838 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 3 Sep 2021 14:24:02 +0100
Subject: [PATCH 10/28] Space panel fix aria-expanded being set to false on
nodes without children
---
src/components/views/spaces/SpaceTreeLevel.tsx | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/components/views/spaces/SpaceTreeLevel.tsx b/src/components/views/spaces/SpaceTreeLevel.tsx
index 399c137e97..3561fd19bf 100644
--- a/src/components/views/spaces/SpaceTreeLevel.tsx
+++ b/src/components/views/spaces/SpaceTreeLevel.tsx
@@ -270,8 +270,10 @@ export class SpaceItem extends React.PureComponent {
? StaticNotificationState.forSymbol("!", NotificationColor.Red)
: SpaceStore.instance.getNotificationState(space.roomId);
+ const hasChildren = this.state.childSpaces?.length;
+
let childItems;
- if (this.state.childSpaces?.length && !collapsed) {
+ if (hasChildren && !collapsed) {
childItems = {
/>;
}
- const toggleCollapseButton = this.state.childSpaces?.length ?
+ const toggleCollapseButton = hasChildren ?
{
/> : null;
return (
-
+
Date: Fri, 3 Sep 2021 15:10:51 +0100
Subject: [PATCH 11/28] Fix keyboard dnd messing with roving tabindex
---
src/components/views/spaces/SpacePanel.tsx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/components/views/spaces/SpacePanel.tsx b/src/components/views/spaces/SpacePanel.tsx
index d2e09c0d69..d3e41f8e58 100644
--- a/src/components/views/spaces/SpacePanel.tsx
+++ b/src/components/views/spaces/SpacePanel.tsx
@@ -223,6 +223,8 @@ const SpacePanel = () => {
}, []);
const onKeyDown = (ev: React.KeyboardEvent) => {
+ if (ev.defaultPrevented) return;
+
let handled = true;
switch (ev.key) {
From 898de13ca717cda3138628b184ecd41844693d62 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Mon, 6 Sep 2021 08:54:08 +0100
Subject: [PATCH 12/28] Consolidate roving tab index controls in the space
panel buttons with dnd
---
src/components/views/spaces/SpacePanel.tsx | 6 ++---
.../views/spaces/SpaceTreeLevel.tsx | 22 ++++++++++++++-----
2 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/src/components/views/spaces/SpacePanel.tsx b/src/components/views/spaces/SpacePanel.tsx
index d3e41f8e58..d223f5b6a6 100644
--- a/src/components/views/spaces/SpacePanel.tsx
+++ b/src/components/views/spaces/SpacePanel.tsx
@@ -195,12 +195,10 @@ const InnerSpacePanel = React.memo(({ children, isPanelCo
{ (provided, snapshot) => (
, "title"> {
+interface IButtonProps extends Omit, "title"> {
space?: Room;
className?: string;
selected?: boolean;
@@ -68,7 +70,9 @@ export const SpaceButton: React.FC = ({
ContextMenuComponent,
...props
}) => {
- const [menuDisplayed, handle, openMenu, closeMenu] = useContextMenu();
+ const [menuDisplayed, ref, openMenu, closeMenu] = useContextMenu();
+ const [onFocus, isActive, handle] = useRovingTabIndex(ref);
+ const tabIndex = isActive ? 0 : -1;
let avatar = ;
if (space) {
@@ -88,6 +92,7 @@ export const SpaceButton: React.FC = ({
forceCount={false}
notification={notificationState}
aria-label={ariaLabel}
+ tabIndex={tabIndex}
/>
;
}
@@ -102,7 +107,7 @@ export const SpaceButton: React.FC
= ({
}
return (
- = ({
onContextMenu={openMenu}
forceHide={!isNarrow || menuDisplayed}
inputRef={handle}
+ tabIndex={tabIndex}
+ onFocus={onFocus}
>
{ children }
@@ -130,7 +137,7 @@ export const SpaceButton: React.FC = ({
{ contextMenu }
-
+
);
};
@@ -142,6 +149,7 @@ interface IItemProps extends InputHTMLAttributes {
onExpand?: Function;
parents?: Set;
innerRef?: LegacyRef;
+ dragHandleProps?: DraggableProvidedDragHandleProps;
}
interface IItemState {
@@ -290,6 +298,9 @@ export class SpaceItem extends React.PureComponent {
aria-label={collapsed ? _t("Expand") : _t("Collapse")}
/> : null;
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ const { tabIndex, ...dragHandleProps } = this.props.dragHandleProps || {};
+
return (
{
role="treeitem"
>
Date: Mon, 6 Sep 2021 14:34:06 +0100
Subject: [PATCH 13/28] Respect m.space.parent relations if they hold valid
permissions
---
src/stores/SpaceStore.tsx | 31 +++++++++++++++----
test/stores/SpaceStore-test.ts | 54 +++++++++++++++++++++++++++++++++-
2 files changed, 78 insertions(+), 7 deletions(-)
diff --git a/src/stores/SpaceStore.tsx b/src/stores/SpaceStore.tsx
index ff99b38fe3..edbe8327c7 100644
--- a/src/stores/SpaceStore.tsx
+++ b/src/stores/SpaceStore.tsx
@@ -366,16 +366,18 @@ export class SpaceStoreClass extends AsyncStoreWithClient {
}
public getParents(roomId: string, canonicalOnly = false): Room[] {
+ const userId = this.matrixClient?.getUserId();
const room = this.matrixClient?.getRoom(roomId);
return room?.currentState.getStateEvents(EventType.SpaceParent)
- .filter(ev => {
+ .map(ev => {
const content = ev.getContent();
- if (!content?.via?.length) return false;
- // TODO apply permissions check to verify that the parent mapping is valid
- if (canonicalOnly && !content?.canonical) return false;
- return true;
+ if (!Array.isArray(content?.via)) return;
+ const parent = this.matrixClient.getRoom(ev.getStateKey());
+ if (canonicalOnly && !content?.canonical) return;
+ if (parent.currentState.maySendStateEvent(EventType.SpaceChild, userId)) {
+ return parent;
+ }
})
- .map(ev => this.matrixClient.getRoom(ev.getStateKey()))
.filter(Boolean) || [];
}
@@ -530,6 +532,14 @@ export class SpaceStoreClass extends AsyncStoreWithClient {
});
}
+ const hiddenChildren = new EnhancedMap>();
+ visibleRooms.forEach(room => {
+ if (room.getMyMembership() !== "join") return;
+ this.getParents(room.roomId).forEach(parent => {
+ hiddenChildren.getOrCreate(parent.roomId, new Set()).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.
@@ -559,6 +569,9 @@ export class SpaceStoreClass extends AsyncStoreWithClient {
roomIds.add(roomId);
});
});
+ hiddenChildren.get(spaceId)?.forEach(roomId => {
+ roomIds.add(roomId);
+ });
this.spaceFilteredRooms.set(spaceId, roomIds);
return roomIds;
};
@@ -690,6 +703,12 @@ export class SpaceStoreClass extends AsyncStoreWithClient {
}
this.emit(room.roomId);
break;
+
+ case EventType.RoomPowerLevels:
+ if (room.isSpaceRoom()) {
+ this.onRoomsUpdate();
+ }
+ break;
}
};
diff --git a/test/stores/SpaceStore-test.ts b/test/stores/SpaceStore-test.ts
index 7cfd97b234..698bd01370 100644
--- a/test/stores/SpaceStore-test.ts
+++ b/test/stores/SpaceStore-test.ts
@@ -276,10 +276,12 @@ describe("SpaceStore", () => {
describe("test fixture 1", () => {
beforeEach(async () => {
- [fav1, fav2, fav3, dm1, dm2, dm3, orphan1, orphan2, invite1, invite2, room1].forEach(mkRoom);
+ [fav1, fav2, fav3, dm1, dm2, dm3, orphan1, orphan2, invite1, invite2, room1, room2, room3]
+ .forEach(mkRoom);
mkSpace(space1, [fav1, room1]);
mkSpace(space2, [fav1, fav2, fav3, room1]);
mkSpace(space3, [invite2]);
+ // client.getRoom.mockImplementation(roomId => rooms.find(room => room.roomId === roomId));
[fav1, fav2, fav3].forEach(roomId => {
client.getRoom(roomId).tags = {
@@ -329,6 +331,48 @@ describe("SpaceStore", () => {
]);
// dmPartner3 is not in any common spaces with you
+ // room 2 claims to be a child of space2 and is so via a valid m.space.parent
+ const cliRoom2 = client.getRoom(room2);
+ cliRoom2.currentState.getStateEvents.mockImplementation(testUtils.mockStateEventImplementation([
+ mkEvent({
+ event: true,
+ type: EventType.SpaceParent,
+ room: room2,
+ user: client.getUserId(),
+ skey: space2,
+ content: { via: [], canonical: true },
+ ts: Date.now(),
+ }),
+ ]));
+ const cliSpace2 = client.getRoom(space2);
+ cliSpace2.currentState.maySendStateEvent.mockImplementation((evType: string, userId: string) => {
+ if (evType === EventType.SpaceChild) {
+ return userId === client.getUserId();
+ }
+ return true;
+ });
+
+ // room 3 claims to be a child of space3 but is not due to invalid m.space.parent (permissions)
+ const cliRoom3 = client.getRoom(room3);
+ cliRoom3.currentState.getStateEvents.mockImplementation(testUtils.mockStateEventImplementation([
+ mkEvent({
+ event: true,
+ type: EventType.SpaceParent,
+ room: room3,
+ user: client.getUserId(),
+ skey: space3,
+ content: { via: [], canonical: true },
+ ts: Date.now(),
+ }),
+ ]));
+ const cliSpace3 = client.getRoom(space3);
+ cliSpace3.currentState.maySendStateEvent.mockImplementation((evType: string, userId: string) => {
+ if (evType === EventType.SpaceChild) {
+ return false;
+ }
+ return true;
+ });
+
await run();
});
@@ -445,6 +489,14 @@ describe("SpaceStore", () => {
expect(store.getNotificationState(space2).rooms.map(r => r.roomId).includes(room1)).toBeTruthy();
expect(store.getNotificationState(space3).rooms.map(r => r.roomId).includes(room1)).toBeFalsy();
});
+
+ it("honours m.space.parent if sender has permission in parent space", () => {
+ expect(store.getSpaceFilteredRoomIds(client.getRoom(space2)).has(room2)).toBeTruthy();
+ });
+
+ it("does not honour m.space.parent if sender does not have permission in parent space", () => {
+ expect(store.getSpaceFilteredRoomIds(client.getRoom(space3)).has(room3)).toBeFalsy();
+ });
});
});
From 68836b9c680128a99588d28fbd30ca1a845fb141 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Mon, 6 Sep 2021 14:59:30 +0100
Subject: [PATCH 14/28] hide no-op m.room.encryption events and better word
param changes
---
src/components/views/messages/EncryptionEvent.tsx | 15 ++++++++++++---
src/i18n/strings/en_EN.json | 1 +
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/components/views/messages/EncryptionEvent.tsx b/src/components/views/messages/EncryptionEvent.tsx
index 0f716ed010..88b96e0c5e 100644
--- a/src/components/views/messages/EncryptionEvent.tsx
+++ b/src/components/views/messages/EncryptionEvent.tsx
@@ -22,20 +22,27 @@ import { MatrixClientPeg } from '../../../MatrixClientPeg';
import EventTileBubble from "./EventTileBubble";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import DMRoomMap from "../../../utils/DMRoomMap";
+import { objectHasDiff } from "../../../utils/objects";
interface IProps {
mxEvent: MatrixEvent;
}
+const ALGORITHM = "m.megolm.v1.aes-sha2";
+
const EncryptionEvent = forwardRef(({ mxEvent }, ref) => {
const cli = useContext(MatrixClientContext);
const roomId = mxEvent.getRoomId();
const isRoomEncrypted = MatrixClientPeg.get().isRoomEncrypted(roomId);
- if (mxEvent.getContent().algorithm === 'm.megolm.v1.aes-sha2' && isRoomEncrypted) {
+ if (!objectHasDiff(mxEvent.getPrevContent(), mxEvent.getContent())) return null; // nop
+
+ if (mxEvent.getContent().algorithm === ALGORITHM && isRoomEncrypted) {
let subtitle: string;
const dmPartner = DMRoomMap.shared().getUserIdForRoomId(roomId);
- if (dmPartner) {
+ if (mxEvent.getPrevContent().algorithm === ALGORITHM) {
+ subtitle = _t("Some encryption parameters have been changed.");
+ } else if (dmPartner) {
const displayName = cli?.getRoom(roomId)?.getMember(dmPartner)?.rawDisplayName || dmPartner;
subtitle = _t("Messages here are end-to-end encrypted. " +
"Verify %(displayName)s in their profile - tap on their avatar.", { displayName });
@@ -49,7 +56,9 @@ const EncryptionEvent = forwardRef(({ mxEvent }, ref) =>
title={_t("Encryption enabled")}
subtitle={subtitle}
/>;
- } else if (isRoomEncrypted) {
+ }
+
+ if (isRoomEncrypted) {
return
Date: Tue, 7 Sep 2021 12:01:18 +0100
Subject: [PATCH 15/28] add comment
---
src/components/views/messages/EncryptionEvent.tsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/components/views/messages/EncryptionEvent.tsx b/src/components/views/messages/EncryptionEvent.tsx
index 88b96e0c5e..80b60f1fe7 100644
--- a/src/components/views/messages/EncryptionEvent.tsx
+++ b/src/components/views/messages/EncryptionEvent.tsx
@@ -35,6 +35,7 @@ const EncryptionEvent = forwardRef(({ mxEvent }, ref) =>
const roomId = mxEvent.getRoomId();
const isRoomEncrypted = MatrixClientPeg.get().isRoomEncrypted(roomId);
+ // if no change happened then skip rendering this, a shallow check is enough as events are parsed JSON
if (!objectHasDiff(mxEvent.getPrevContent(), mxEvent.getContent())) return null; // nop
if (mxEvent.getContent().algorithm === ALGORITHM && isRoomEncrypted) {
From f4f4686270bfee51d4d96320b606b6c6f219977a Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Tue, 7 Sep 2021 12:07:18 +0100
Subject: [PATCH 16/28] tidy up code
---
src/stores/SpaceStore.tsx | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/stores/SpaceStore.tsx b/src/stores/SpaceStore.tsx
index edbe8327c7..ebc60b2f2c 100644
--- a/src/stores/SpaceStore.tsx
+++ b/src/stores/SpaceStore.tsx
@@ -371,12 +371,16 @@ export class SpaceStoreClass extends AsyncStoreWithClient {
return room?.currentState.getStateEvents(EventType.SpaceParent)
.map(ev => {
const content = ev.getContent();
- if (!Array.isArray(content?.via)) return;
- const parent = this.matrixClient.getRoom(ev.getStateKey());
- if (canonicalOnly && !content?.canonical) return;
- if (parent.currentState.maySendStateEvent(EventType.SpaceChild, userId)) {
- return parent;
+ if (Array.isArray(content?.via) && (!canonicalOnly || content?.canonical)) {
+ const parent = this.matrixClient.getRoom(ev.getStateKey());
+ // only respect the relationship if the sender has sufficient permissions in the parent to set
+ // child relations, as per MSC1772.
+ // https://github.com/matrix-org/matrix-doc/blob/main/proposals/1772-groups-as-rooms.md#relationship-between-rooms-and-spaces
+ if (parent?.currentState.maySendStateEvent(EventType.SpaceChild, userId)) {
+ return parent;
+ }
}
+ // else implicit undefined which causes this element to be filtered out
})
.filter(Boolean) || [];
}
From e1fdf7c69db9185bddede693f550a092271128ec Mon Sep 17 00:00:00 2001
From: David Baker
Date: Tue, 7 Sep 2021 18:01:13 +0100
Subject: [PATCH 17/28] Update changelog generator
---
package.json | 2 +-
yarn.lock | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package.json b/package.json
index 6245b2c34e..9798503e9e 100644
--- a/package.json
+++ b/package.json
@@ -151,7 +151,7 @@
"@typescript-eslint/eslint-plugin": "^4.17.0",
"@typescript-eslint/parser": "^4.17.0",
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.1",
- "allchange": "^1.0.2",
+ "allchange": "^1.0.3",
"babel-jest": "^26.6.3",
"chokidar": "^3.5.1",
"concurrently": "^5.3.0",
diff --git a/yarn.lock b/yarn.lock
index f70f0e75c1..e0b4a403b8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2036,10 +2036,10 @@ ajv@^8.0.1:
require-from-string "^2.0.2"
uri-js "^4.2.2"
-allchange@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/allchange/-/allchange-1.0.2.tgz#86b9190e12b7ede4f230ae763cbd504c48fd907b"
- integrity sha512-qJv1t2yvBThkes8g/dPMt8CGu+04U+q5QjCJn2Ngp92edZU8DJBfKGyGXo7w1iV48LVuQKQDfMsdIWhP7zHdlQ==
+allchange@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/allchange/-/allchange-1.0.3.tgz#f8814ddfbcfe39a01bf4570778ee7e6d9ff0ebb3"
+ integrity sha512-UZkfz5SkNEMFQFLr8vZcXHaph2EbJxmkVNF5Nt6D9RIa5pmAar7oAMfNdda714jg7IQijvaFty5PYazXLgd5WA==
dependencies:
"@actions/core" "^1.4.0"
"@actions/github" "^5.0.0"
From 9533f7c04cd438371225b6657371bd5d781f73e1 Mon Sep 17 00:00:00 2001
From: David Baker
Date: Tue, 7 Sep 2021 18:49:31 +0100
Subject: [PATCH 18/28] 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 8bd1f384b94d37ad150874ca64e2f3f962a2ae23 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 8 Sep 2021 10:16:20 +0100
Subject: [PATCH 19/28] Improve tooltips on space quick actions and explore
button
---
src/components/structures/LeftPanel.tsx | 4 +++-
src/components/views/rooms/RoomList.tsx | 12 ++++++++----
src/i18n/strings/en_EN.json | 1 +
3 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/src/components/structures/LeftPanel.tsx b/src/components/structures/LeftPanel.tsx
index d955271249..9a2ebd45e2 100644
--- a/src/components/structures/LeftPanel.tsx
+++ b/src/components/structures/LeftPanel.tsx
@@ -399,7 +399,9 @@ export default class LeftPanel extends React.Component {
mx_LeftPanel_exploreButton_space: !!this.state.activeSpace,
})}
onClick={this.onExplore}
- title={_t("Explore rooms")}
+ title={this.state.activeSpace
+ ? _t("Explore %(spaceName)s", { spaceName: this.state.activeSpace.name })
+ : _t("Explore rooms")}
/>
);
diff --git a/src/components/views/rooms/RoomList.tsx b/src/components/views/rooms/RoomList.tsx
index 4988ea6691..541d0e1d9d 100644
--- a/src/components/views/rooms/RoomList.tsx
+++ b/src/components/views/rooms/RoomList.tsx
@@ -48,6 +48,7 @@ import SpaceStore, { ISuggestedRoom, SUGGESTED_ROOMS } from "../../../stores/Spa
import { showAddExistingRooms, showCreateNewRoom, showSpaceInvite } from "../../../utils/space";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import RoomAvatar from "../avatars/RoomAvatar";
+import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
interface IProps {
onKeyDown: (ev: React.KeyboardEvent) => void;
@@ -522,20 +523,23 @@ export default class RoomList extends React.PureComponent {
} else if (
this.props.activeSpace?.canInvite(userId) || this.props.activeSpace?.getMyMembership() === "join"
) {
+ const spaceName = this.props.activeSpace.name;
explorePrompt =
{ _t("Quick actions") }
- { this.props.activeSpace.canInvite(userId) &&
{ _t("Invite people") }
- }
- { this.props.activeSpace.getMyMembership() === "join" &&
}
+ { this.props.activeSpace.getMyMembership() === "join" &&
{ _t("Explore rooms") }
- }
+ }
;
} else if (Object.values(this.state.sublists).some(list => list.length > 0)) {
const unfilteredLists = RoomListStore.instance.unfilteredLists;
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 7d754a618a..b2f09686bb 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -1643,6 +1643,7 @@
"Start a new chat": "Start a new chat",
"Explore all public rooms": "Explore all public rooms",
"Quick actions": "Quick actions",
+ "Explore %(spaceName)s": "Explore %(spaceName)s",
"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",
From 0caca49ec023a0bcff0ad3408b389a433d876674 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 8 Sep 2021 10:26:23 +0100
Subject: [PATCH 20/28] Fix regressed tab view buttons in space update toast
---
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 ff99b38fe3..b63b71cfcf 100644
--- a/src/stores/SpaceStore.tsx
+++ b/src/stores/SpaceStore.tsx
@@ -257,7 +257,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient {
"go to that room's Security & Privacy settings.") }
{ /* Reuses classes from TabbedView for simplicity, non-interactive */ }
-
+
{ _t("General") }
From 47fd11050fe0634e3cc2872a527622dcceec4826 Mon Sep 17 00:00:00 2001
From: David Baker
Date: Wed, 8 Sep 2021 11:43:46 +0100
Subject: [PATCH 21/28] Switch type check to GitHub Actions
and add (working) type check for release mode js-sdk types
---
.github/workflows/lint.yaml | 25 +++++++++++++++++++++++++
scripts/ci/js-sdk-to-release.js | 17 +++++++++++++++++
scripts/ci/js-sdk-to-release.sh | 21 ---------------------
3 files changed, 42 insertions(+), 21 deletions(-)
create mode 100644 .github/workflows/lint.yaml
create mode 100755 scripts/ci/js-sdk-to-release.js
delete mode 100755 scripts/ci/js-sdk-to-release.sh
diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml
new file mode 100644
index 0000000000..e7f12ab65d
--- /dev/null
+++ b/.github/workflows/lint.yaml
@@ -0,0 +1,25 @@
+name: Lint
+on:
+ pull_request:
+ branches: [develop]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: c-hive/gha-yarn-cache@v2
+ - name: Install Deps
+ run: "./scripts/ci/install-deps.sh --ignore-scripts"
+ - name: Typecheck
+ run: "yarn run lint:types"
+ - name: Switch js-sdk to release mode
+ run: |
+ scripts/ci/js-sdk-to-release.js
+ pushd node_modules/matrix-js-sdk
+ yarn install
+ yarn run build:compile
+ yarn run build:types
+ popd
+ - name: Typecheck (release mode)
+ run: "yarn run lint:types"
+
diff --git a/scripts/ci/js-sdk-to-release.js b/scripts/ci/js-sdk-to-release.js
new file mode 100755
index 0000000000..e1fecfde03
--- /dev/null
+++ b/scripts/ci/js-sdk-to-release.js
@@ -0,0 +1,17 @@
+#!/usr/bin/env node
+
+const fsProm = require('fs/promises');
+
+const PKGJSON = 'node_modules/matrix-js-sdk/package.json';
+
+async function main() {
+ const pkgJson = JSON.parse(await fsProm.readFile(PKGJSON, 'utf8'));
+ for (const field of ['main', 'typings']) {
+ if (pkgJson["matrix_lib_"+field] !== undefined) {
+ pkgJson[field] = pkgJson["matrix_lib_"+field];
+ }
+ }
+ await fsProm.writeFile(PKGJSON, JSON.stringify(pkgJson, null, 2));
+}
+
+main();
diff --git a/scripts/ci/js-sdk-to-release.sh b/scripts/ci/js-sdk-to-release.sh
deleted file mode 100755
index a03165bd82..0000000000
--- a/scripts/ci/js-sdk-to-release.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-
-# This changes the js-sdk into 'release mode', that is:
-# * The entry point for the library is the babel-compiled lib/index.js rather than src/index.ts
-# * There's a 'typings' entry referencing the types output by tsc
-# We do this so we can test that each PR still builds / type checks correctly when built
-# against the released js-sdk, because if you do things like `import { User } from 'matrix-js-sdk';`
-# rather than `import { User } from 'matrix-js-sdk/src/models/user';` it will work fine with the
-# js-sdk in development mode but then break at release time.
-# We can't use the last release of the js-sdk though: it might not be up to date enough.
-
-cd node_modules/matrix-js-sdk
-for i in main typings
-do
- lib_value=$(jq -r ".matrix_lib_$i" package.json)
- if [ "$lib_value" != "null" ]; then
- jq ".$i = .matrix_lib_$i" package.json > package.json.new && mv package.json.new package.json
- fi
-done
-yarn run build:compile
-yarn run build:types
From f3abb13dc9619a32eee8308cc7eb9e4c0a51bd13 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 8 Sep 2021 12:34:44 +0100
Subject: [PATCH 22/28] Convert crypto/verification/* to Typescript
---
.../views/right_panel/EncryptionPanel.tsx | 2 +-
.../views/right_panel/VerificationPanel.tsx | 38 ++++++-------------
.../verification/VerificationShowSas.tsx | 4 +-
3 files changed, 15 insertions(+), 29 deletions(-)
diff --git a/src/components/views/right_panel/EncryptionPanel.tsx b/src/components/views/right_panel/EncryptionPanel.tsx
index b1c8d427bf..8beb089b38 100644
--- a/src/components/views/right_panel/EncryptionPanel.tsx
+++ b/src/components/views/right_panel/EncryptionPanel.tsx
@@ -57,7 +57,7 @@ const EncryptionPanel: React.FC = (props: IProps) => {
// state to show a spinner immediately after clicking "start verification",
// before we have a request
const [isRequesting, setRequesting] = useState(false);
- const [phase, setPhase] = useState(request && request.phase);
+ const [phase, setPhase] = useState(request?.phase);
useEffect(() => {
setRequest(verificationRequest);
if (verificationRequest) {
diff --git a/src/components/views/right_panel/VerificationPanel.tsx b/src/components/views/right_panel/VerificationPanel.tsx
index 395bdc21e0..a29bdea90b 100644
--- a/src/components/views/right_panel/VerificationPanel.tsx
+++ b/src/components/views/right_panel/VerificationPanel.tsx
@@ -29,43 +29,27 @@ import VerificationQRCode from "../elements/crypto/VerificationQRCode";
import { _t } from "../../../languageHandler";
import SdkConfig from "../../../SdkConfig";
import E2EIcon from "../rooms/E2EIcon";
-import {
- PHASE_READY,
- PHASE_DONE,
- PHASE_STARTED,
- PHASE_CANCELLED,
-} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
+import { Phase } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
import Spinner from "../elements/Spinner";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import AccessibleButton from "../elements/AccessibleButton";
import VerificationShowSas from "../verification/VerificationShowSas";
-// XXX: Should be defined in matrix-js-sdk
-enum VerificationPhase {
- PHASE_UNSENT,
- PHASE_REQUESTED,
- PHASE_READY,
- PHASE_DONE,
- PHASE_STARTED,
- PHASE_CANCELLED,
-}
-
interface IProps {
layout: string;
request: VerificationRequest;
member: RoomMember | User;
- phase: VerificationPhase;
+ phase: Phase;
onClose: () => void;
isRoomEncrypted: boolean;
inDialog: boolean;
- key: number;
}
interface IState {
- sasEvent?: SAS;
+ sasEvent?: SAS["sasEvent"];
emojiButtonClicked?: boolean;
reciprocateButtonClicked?: boolean;
- reciprocateQREvent?: ReciprocateQRCode;
+ reciprocateQREvent?: ReciprocateQRCode["reciprocateQREvent"];
}
@replaceableComponent("views.right_panel.VerificationPanel")
@@ -321,9 +305,9 @@ export default class VerificationPanel extends React.PureComponent {
const { request } = this.props;
- const { sasEvent, reciprocateQREvent } = request.verifier;
+ const sasEvent = (request.verifier as SAS).sasEvent;
+ const reciprocateQREvent = (request.verifier as ReciprocateQRCode).reciprocateQREvent;
request.verifier.off('show_sas', this.updateVerifierState);
request.verifier.off('show_reciprocate_qr', this.updateVerifierState);
this.setState({ sasEvent, reciprocateQREvent });
@@ -402,7 +387,8 @@ export default class VerificationPanel extends React.PureComponent void;
onCancel: () => void;
- sas: SAS.sas;
+ sas: IGeneratedSas;
isSelf?: boolean;
inDialog?: boolean; // whether this component is being shown in a dialog and to use DialogButtons
}
From 467fb55e8ecaecf6083e49538464d1a8b81041cc Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 8 Sep 2021 12:53:13 +0100
Subject: [PATCH 23/28] improve typing & comment
---
src/components/views/messages/EncryptionEvent.tsx | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/components/views/messages/EncryptionEvent.tsx b/src/components/views/messages/EncryptionEvent.tsx
index 80b60f1fe7..8f352610e0 100644
--- a/src/components/views/messages/EncryptionEvent.tsx
+++ b/src/components/views/messages/EncryptionEvent.tsx
@@ -16,6 +16,7 @@ limitations under the License.
import React, { forwardRef, useContext } from 'react';
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
+import { IRoomEncryption } from "matrix-js-sdk/src/crypto/RoomList";
import { _t } from '../../../languageHandler';
import { MatrixClientPeg } from '../../../MatrixClientPeg';
@@ -35,13 +36,16 @@ const EncryptionEvent = forwardRef(({ mxEvent }, ref) =>
const roomId = mxEvent.getRoomId();
const isRoomEncrypted = MatrixClientPeg.get().isRoomEncrypted(roomId);
- // if no change happened then skip rendering this, a shallow check is enough as events are parsed JSON
- if (!objectHasDiff(mxEvent.getPrevContent(), mxEvent.getContent())) return null; // nop
+ const prevContent = mxEvent.getPrevContent() as IRoomEncryption;
+ const content = mxEvent.getContent();
- if (mxEvent.getContent().algorithm === ALGORITHM && isRoomEncrypted) {
+ // if no change happened then skip rendering this, a shallow check is enough as all known fields are top-level.
+ if (!objectHasDiff(prevContent, content)) return null; // nop
+
+ if (content.algorithm === ALGORITHM && isRoomEncrypted) {
let subtitle: string;
const dmPartner = DMRoomMap.shared().getUserIdForRoomId(roomId);
- if (mxEvent.getPrevContent().algorithm === ALGORITHM) {
+ if (prevContent.algorithm === ALGORITHM) {
subtitle = _t("Some encryption parameters have been changed.");
} else if (dmPartner) {
const displayName = cli?.getRoom(roomId)?.getMember(dmPartner)?.rawDisplayName || dmPartner;
From 83912daced7bafdea313436ac1270229c1585065 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 8 Sep 2021 13:16:31 +0100
Subject: [PATCH 24/28] Improve the upgrade for restricted user experience
---
.../views/dialogs/RoomSettingsDialog.tsx | 5 +-
.../tabs/room/SecurityRoomSettingsTab.tsx | 18 ++++++-
src/utils/RoomUpgrade.ts | 51 ++++++++++++-------
3 files changed, 52 insertions(+), 22 deletions(-)
diff --git a/src/components/views/dialogs/RoomSettingsDialog.tsx b/src/components/views/dialogs/RoomSettingsDialog.tsx
index a426dce5c7..a73f0a595b 100644
--- a/src/components/views/dialogs/RoomSettingsDialog.tsx
+++ b/src/components/views/dialogs/RoomSettingsDialog.tsx
@@ -79,7 +79,10 @@ export default class RoomSettingsDialog extends React.Component {
ROOM_SECURITY_TAB,
_td("Security & Privacy"),
"mx_RoomSettingsDialog_securityIcon",
- ,
+ this.props.onFinished(true)}
+ />,
));
tabs.push(new Tab(
ROOM_ROLES_TAB,
diff --git a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx
index 081b1a8698..5cb76ebc25 100644
--- a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx
+++ b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx
@@ -39,9 +39,12 @@ import { arrayHasDiff } from "../../../../../utils/arrays";
import SettingsFlag from '../../../elements/SettingsFlag';
import createRoom, { IOpts } from '../../../../../createRoom';
import CreateRoomDialog from '../../../dialogs/CreateRoomDialog';
+import dis from "../../../../../dispatcher/dispatcher";
+import { ROOM_SECURITY_TAB } from "../../../dialogs/RoomSettingsDialog";
interface IProps {
roomId: string;
+ closeSettingsFn: () => void;
}
interface IState {
@@ -220,9 +223,20 @@ export default class SecurityRoomSettingsTab extends React.Component {
+ onFinished: async (resp) => {
if (!resp?.continue) return;
- upgradeRoom(room, targetVersion, resp.invite);
+ const roomId = await upgradeRoom(room, targetVersion, resp.invite, true, true, true);
+ this.props.closeSettingsFn();
+ // switch to the new room in the background
+ dis.dispatch({
+ action: "view_room",
+ room_id: roomId,
+ });
+ // open new settings on this tab
+ dis.dispatch({
+ action: "open_room_settings",
+ initial_tab_id: ROOM_SECURITY_TAB,
+ });
},
});
return;
diff --git a/src/utils/RoomUpgrade.ts b/src/utils/RoomUpgrade.ts
index e632ec6345..4dd2a880a0 100644
--- a/src/utils/RoomUpgrade.ts
+++ b/src/utils/RoomUpgrade.ts
@@ -22,6 +22,7 @@ import Modal from "../Modal";
import { _t } from "../languageHandler";
import ErrorDialog from "../components/views/dialogs/ErrorDialog";
import SpaceStore from "../stores/SpaceStore";
+import Spinner from "../components/views/elements/Spinner";
export async function upgradeRoom(
room: Room,
@@ -29,8 +30,10 @@ export async function upgradeRoom(
inviteUsers = false,
handleError = true,
updateSpaces = true,
+ awaitRoom = false,
): Promise {
const cli = room.client;
+ const modal = Modal.createDialog(Spinner, null, "mx_Dialog_spinner");
let newRoomId: string;
try {
@@ -46,27 +49,36 @@ export async function upgradeRoom(
throw e;
}
- // We have to wait for the js-sdk to give us the room back so
- // we can more effectively abuse the MultiInviter behaviour
- // which heavily relies on the Room object being available.
- if (inviteUsers) {
- const checkForUpgradeFn = async (newRoom: Room): Promise => {
- // The upgradePromise should be done by the time we await it here.
- if (newRoom.roomId !== newRoomId) return;
-
- const toInvite = [
- ...room.getMembersWithMembership("join"),
- ...room.getMembersWithMembership("invite"),
- ].map(m => m.userId).filter(m => m !== cli.getUserId());
-
- if (toInvite.length > 0) {
- // Errors are handled internally to this function
- await inviteUsersToRoom(newRoomId, toInvite);
+ if (awaitRoom || inviteUsers) {
+ await new Promise(resolve => {
+ // already have the room
+ if (room.client.getRoom(newRoomId)) {
+ resolve();
+ return;
}
- cli.removeListener('Room', checkForUpgradeFn);
- };
- cli.on('Room', checkForUpgradeFn);
+ // We have to wait for the js-sdk to give us the room back so
+ // we can more effectively abuse the MultiInviter behaviour
+ // which heavily relies on the Room object being available.
+ const checkForRoomFn = (newRoom: Room) => {
+ if (newRoom.roomId !== newRoomId) return;
+ resolve();
+ cli.off("Room", checkForRoomFn);
+ };
+ cli.on("Room", checkForRoomFn);
+ });
+ }
+
+ if (inviteUsers) {
+ const toInvite = [
+ ...room.getMembersWithMembership("join"),
+ ...room.getMembersWithMembership("invite"),
+ ].map(m => m.userId).filter(m => m !== cli.getUserId());
+
+ if (toInvite.length > 0) {
+ // Errors are handled internally to this function
+ await inviteUsersToRoom(newRoomId, toInvite);
+ }
}
if (updateSpaces) {
@@ -89,5 +101,6 @@ export async function upgradeRoom(
}
}
+ modal.close();
return newRoomId;
}
From d4bac4752d0eabf8304f6bb310505ad06406233d Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 8 Sep 2021 13:34:26 +0100
Subject: [PATCH 25/28] Make space members and user info behave more expectedly
---
src/components/structures/RightPanel.tsx | 2 +-
.../views/context_menus/SpaceContextMenu.tsx | 2 +-
src/components/views/right_panel/UserInfo.tsx | 13 ++++++++-----
src/i18n/strings/en_EN.json | 2 +-
4 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/src/components/structures/RightPanel.tsx b/src/components/structures/RightPanel.tsx
index 67634c63d2..5b12e542bd 100644
--- a/src/components/structures/RightPanel.tsx
+++ b/src/components/structures/RightPanel.tsx
@@ -269,7 +269,7 @@ export default class RightPanel extends React.Component {
case RightPanelPhases.EncryptionPanel:
panel = {
defaultDispatcher.dispatch({
action: Action.SetRightPanelPhase,
phase: RightPanelPhases.SpaceMemberList,
- refireParams: { space: space },
+ refireParams: { space },
});
onFinished();
};
diff --git a/src/components/views/right_panel/UserInfo.tsx b/src/components/views/right_panel/UserInfo.tsx
index d15f349d62..f90643f1df 100644
--- a/src/components/views/right_panel/UserInfo.tsx
+++ b/src/components/views/right_panel/UserInfo.tsx
@@ -1278,7 +1278,9 @@ const BasicUserInfo: React.FC<{
// hide the Roles section for DMs as it doesn't make sense there
if (!DMRoomMap.shared().getUserIdForRoomId((member as RoomMember).roomId)) {
memberDetails =
-
{ _t("Role") }
+
{ _t("Role in ", {}, {
+ RoomName: () => { room.name },
+ }) }
= ({
// We have no previousPhase for when viewing a UserInfo from a Group or without a Room at this time
if (room && phase === RightPanelPhases.EncryptionPanel) {
previousPhase = RightPanelPhases.RoomMemberInfo;
- refireParams = { member: member };
+ refireParams = { member };
+ } else if (room?.isSpaceRoom() && SpaceStore.spacesEnabled) {
+ previousPhase = previousPhase = RightPanelPhases.SpaceMemberList;
+ refireParams = { space: room };
} else if (room) {
- previousPhase = previousPhase = SpaceStore.spacesEnabled && room.isSpaceRoom()
- ? RightPanelPhases.SpaceMemberList
- : RightPanelPhases.RoomMemberList;
+ previousPhase = RightPanelPhases.RoomMemberList;
}
const onEncryptionPanelClose = () => {
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 7d754a618a..10152193a3 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -1866,7 +1866,7 @@
"Deactivating this user will log them out and prevent them from logging back in. Additionally, they will leave all the rooms they are in. This action cannot be reversed. Are you sure you want to deactivate this user?": "Deactivating this user will log them out and prevent them from logging back in. Additionally, they will leave all the rooms they are in. This action cannot be reversed. Are you sure you want to deactivate this user?",
"Deactivate user": "Deactivate user",
"Failed to deactivate user": "Failed to deactivate user",
- "Role": "Role",
+ "Role in ": "Role in ",
"This client does not support end-to-end encryption.": "This client does not support end-to-end encryption.",
"Edit devices": "Edit devices",
"Security": "Security",
From 17e0a4b3d772cdf96043fac3029d13c19bc9d1d7 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 8 Sep 2021 17:14:51 +0100
Subject: [PATCH 26/28] iterate PR based on feedback
---
src/utils/RoomUpgrade.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/utils/RoomUpgrade.ts b/src/utils/RoomUpgrade.ts
index 4dd2a880a0..366f49d892 100644
--- a/src/utils/RoomUpgrade.ts
+++ b/src/utils/RoomUpgrade.ts
@@ -33,7 +33,7 @@ export async function upgradeRoom(
awaitRoom = false,
): Promise {
const cli = room.client;
- const modal = Modal.createDialog(Spinner, null, "mx_Dialog_spinner");
+ const spinnerModal = Modal.createDialog(Spinner, null, "mx_Dialog_spinner");
let newRoomId: string;
try {
@@ -101,6 +101,6 @@ export async function upgradeRoom(
}
}
- modal.close();
+ spinnerModal.close();
return newRoomId;
}
From 8f221a484940b610d3f8ace353d20925872fb948 Mon Sep 17 00:00:00 2001
From: David Baker
Date: Wed, 8 Sep 2021 18:37:13 +0100
Subject: [PATCH 27/28] Rename type checking script
'cos it's type chekcing, not linting
---
.github/workflows/{lint.yaml => typecheck.yaml} | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
rename .github/workflows/{lint.yaml => typecheck.yaml} (97%)
diff --git a/.github/workflows/lint.yaml b/.github/workflows/typecheck.yaml
similarity index 97%
rename from .github/workflows/lint.yaml
rename to .github/workflows/typecheck.yaml
index e7f12ab65d..bbbf7185d7 100644
--- a/.github/workflows/lint.yaml
+++ b/.github/workflows/typecheck.yaml
@@ -1,4 +1,4 @@
-name: Lint
+name: Type Check
on:
pull_request:
branches: [develop]
From b67883b4f19abe2aa2c59d3c8baf36443c826670 Mon Sep 17 00:00:00 2001
From: David Baker
Date: Thu, 9 Sep 2021 09:41:11 +0100
Subject: [PATCH 28/28] Remove unnecessary pushd
type: task
---
.github/workflows/typecheck.yaml | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/.github/workflows/typecheck.yaml b/.github/workflows/typecheck.yaml
index bbbf7185d7..2e08418cf6 100644
--- a/.github/workflows/typecheck.yaml
+++ b/.github/workflows/typecheck.yaml
@@ -15,11 +15,10 @@ jobs:
- name: Switch js-sdk to release mode
run: |
scripts/ci/js-sdk-to-release.js
- pushd node_modules/matrix-js-sdk
+ cd node_modules/matrix-js-sdk
yarn install
yarn run build:compile
yarn run build:types
- popd
- name: Typecheck (release mode)
run: "yarn run lint:types"