Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Commit

Permalink
Merge branch 'develop' of github.com:element-hq/matrix-react-sdk into…
Browse files Browse the repository at this point in the history
… t3chguy/dedup-icons-1
  • Loading branch information
t3chguy committed Oct 4, 2024
2 parents 622714c + 0a9b4ae commit 754868e
Show file tree
Hide file tree
Showing 26 changed files with 435 additions and 56 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
},
"dependencies": {
"@babel/runtime": "^7.12.5",
"@matrix-org/analytics-events": "^0.25.0",
"@matrix-org/analytics-events": "^0.26.0",
"@matrix-org/emojibase-bindings": "^1.1.2",
"@matrix-org/matrix-wysiwyg": "2.37.9",
"@matrix-org/react-sdk-module-api": "^2.4.0",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 15 additions & 6 deletions src/components/structures/MainSplit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ Please see LICENSE files in the repository root for full details.
import React, { ReactNode } from "react";
import { NumberSize, Resizable } from "re-resizable";
import { Direction } from "re-resizable/lib/resizer";
import { WebPanelResize } from "@matrix-org/analytics-events/types/typescript/WebPanelResize";

import ResizeNotifier from "../../utils/ResizeNotifier";
import { PosthogAnalytics } from "../../PosthogAnalytics.ts";

interface IProps {
resizeNotifier: ResizeNotifier;
Expand All @@ -26,14 +28,16 @@ interface IProps {
*/
sizeKey?: string;
/**
* The size to use for the panel component if one isn't persisted in storage. Defaults to 350.
* The size to use for the panel component if one isn't persisted in storage. Defaults to 320.
*/
defaultSize: number;

analyticsRoomType: WebPanelResize["roomType"];
}

export default class MainSplit extends React.Component<IProps> {
public static defaultProps = {
defaultSize: 350,
defaultSize: 320,
};

private onResizeStart = (): void => {
Expand All @@ -58,11 +62,16 @@ export default class MainSplit extends React.Component<IProps> {
elementRef: HTMLElement,
delta: NumberSize,
): void => {
const newSize = this.loadSidePanelSize().width + delta.width;
this.props.resizeNotifier.stopResizing();
window.localStorage.setItem(
this.sizeSettingStorageKey,
(this.loadSidePanelSize().width + delta.width).toString(),
);
window.localStorage.setItem(this.sizeSettingStorageKey, newSize.toString());

PosthogAnalytics.instance.trackEvent<WebPanelResize>({
eventName: "WebPanelResize",
panel: "right",
roomType: this.props.analyticsRoomType,
size: newSize,
});
};

private loadSidePanelSize(): { height: string | number; width: number } {
Expand Down
49 changes: 19 additions & 30 deletions src/components/structures/RoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/

import React, { ChangeEvent, createRef, ReactElement, ReactNode, RefObject, useContext } from "react";
import React, { ChangeEvent, ComponentProps, createRef, ReactElement, ReactNode, RefObject, useContext } from "react";
import classNames from "classnames";
import {
IRecommendedVersion,
Expand Down Expand Up @@ -54,7 +54,7 @@ import WidgetEchoStore from "../../stores/WidgetEchoStore";
import SettingsStore from "../../settings/SettingsStore";
import { Layout } from "../../settings/enums/Layout";
import AccessibleButton, { ButtonEvent } from "../views/elements/AccessibleButton";
import RoomContext, { TimelineRenderingType } from "../../contexts/RoomContext";
import RoomContext, { TimelineRenderingType, MainSplitContentType } from "../../contexts/RoomContext";
import { E2EStatus, shieldStatusForRoom } from "../../utils/ShieldUtils";
import { Action } from "../../dispatcher/actions";
import { IMatrixClientCreds } from "../../MatrixClientPeg";
Expand Down Expand Up @@ -152,13 +152,8 @@ interface IRoomProps {
onRegistered?(credentials: IMatrixClientCreds): void;
}

// This defines the content of the mainSplit.
// If the mainSplit does not contain the Timeline, the chat is shown in the right panel.
export enum MainSplitContentType {
Timeline,
MaximisedWidget,
Call,
}
export { MainSplitContentType };

export interface IRoomState {
room?: Room;
virtualRoom?: Room;
Expand Down Expand Up @@ -191,11 +186,6 @@ export interface IRoomState {
showApps: boolean;
isPeeking: boolean;
showRightPanel: boolean;
/**
* Whether the right panel shown is either of ThreadPanel or ThreadView.
* Always false when `showRightPanel` is false.
*/
threadRightPanel: boolean;
// error object, as from the matrix client/server API
// If we failed to load information about the room,
// store the error here.
Expand Down Expand Up @@ -234,7 +224,7 @@ export interface IRoomState {
e2eStatus?: E2EStatus;
rejecting?: boolean;
hasPinnedWidgets?: boolean;
mainSplitContentType?: MainSplitContentType;
mainSplitContentType: MainSplitContentType;
// whether or not a spaces context switch brought us here,
// if it did we don't want the room to be marked as read as soon as it is loaded.
wasContextSwitch?: boolean;
Expand Down Expand Up @@ -399,7 +389,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
showApps: false,
isPeeking: false,
showRightPanel: false,
threadRightPanel: false,
joining: false,
showTopUnreadMessagesBar: false,
statusBarVisible: false,
Expand Down Expand Up @@ -626,11 +615,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
mainSplitContentType: room ? this.getMainSplitContentType(room) : undefined,
initialEventId: undefined, // default to clearing this, will get set later in the method if needed
showRightPanel: roomId ? this.context.rightPanelStore.isOpenForRoom(roomId) : false,
threadRightPanel: roomId
? [RightPanelPhases.ThreadView, RightPanelPhases.ThreadPanel].includes(
this.context.rightPanelStore.currentCardForRoom(roomId).phase!,
)
: false,
activeCall: roomId ? CallStore.instance.getActiveCall(roomId) : null,
promptAskToJoin: this.context.roomViewStore.promptAskToJoin(),
viewRoomOpts: this.context.roomViewStore.getViewRoomOpts(),
Expand Down Expand Up @@ -1033,11 +1017,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
const { roomId } = this.state;
this.setState({
showRightPanel: roomId ? this.context.rightPanelStore.isOpenForRoom(roomId) : false,
threadRightPanel: roomId
? [RightPanelPhases.ThreadView, RightPanelPhases.ThreadPanel].includes(
this.context.rightPanelStore.currentCardForRoom(roomId).phase!,
)
: false,
});
};

Expand Down Expand Up @@ -2531,6 +2510,17 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
}
const mainSplitContentClasses = classNames("mx_RoomView_body", mainSplitContentClassName);

let sizeKey: string | undefined;
let defaultSize: number | undefined;
let analyticsRoomType: ComponentProps<typeof MainSplit>["analyticsRoomType"] = "other_room";
if (this.state.mainSplitContentType !== MainSplitContentType.Timeline) {
// Override defaults for video rooms where more space is needed for the chat timeline
sizeKey = "wide";
defaultSize = 420;
analyticsRoomType =
this.state.mainSplitContentType === MainSplitContentType.Call ? "video_room" : "maximised_widget";
}

return (
<RoomContext.Provider value={this.state}>
<div className={mainClasses} ref={this.roomView} onKeyDown={this.onReactKeyDown}>
Expand All @@ -2541,10 +2531,9 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
<MainSplit
panel={rightPanel}
resizeNotifier={this.props.resizeNotifier}
// Override defaults when a thread is being shown to allow persisting a separate
// right panel width for thread panels as they tend to want to be wider.
sizeKey={this.state.threadRightPanel ? "thread" : undefined}
defaultSize={this.state.threadRightPanel ? 500 : undefined}
sizeKey={sizeKey}
defaultSize={defaultSize}
analyticsRoomType={analyticsRoomType}
>
<div
className={mainSplitContentClasses}
Expand Down
2 changes: 1 addition & 1 deletion src/components/structures/SpaceRoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
return (
<main className="mx_SpaceRoomView">
<ErrorBoundary>
<MainSplit panel={rightPanel} resizeNotifier={this.props.resizeNotifier}>
<MainSplit panel={rightPanel} resizeNotifier={this.props.resizeNotifier} analyticsRoomType="space">
{this.renderBody()}
</MainSplit>
</ErrorBoundary>
Expand Down
7 changes: 6 additions & 1 deletion src/components/structures/UserView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,12 @@ export default class UserView extends React.Component<IProps, IState> {
/>
);
return (
<MainSplit panel={panel} resizeNotifier={this.props.resizeNotifier}>
<MainSplit
panel={panel}
resizeNotifier={this.props.resizeNotifier}
defaultSize={420}
analyticsRoomType="user_profile"
>
<UserOnboardingPage />
</MainSplit>
);
Expand Down
10 changes: 9 additions & 1 deletion src/contexts/RoomContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ export enum TimelineRenderingType {
Pinned = "Pinned",
}

// This defines the content of the mainSplit.
// If the mainSplit does not contain the Timeline, the chat is shown in the right panel.
export enum MainSplitContentType {
Timeline,
MaximisedWidget,
Call,
}

const RoomContext = createContext<
IRoomState & {
threadId?: string;
Expand All @@ -35,7 +43,6 @@ const RoomContext = createContext<
showApps: false,
isPeeking: false,
showRightPanel: true,
threadRightPanel: false,
joining: false,
showTopUnreadMessagesBar: false,
statusBarVisible: false,
Expand All @@ -59,6 +66,7 @@ const RoomContext = createContext<
matrixClientIsReady: false,
showUrlPreview: false,
timelineRenderingType: TimelineRenderingType.Room,
mainSplitContentType: MainSplitContentType.Timeline,
threadId: undefined,
liveTimeline: undefined,
narrow: false,
Expand Down
54 changes: 49 additions & 5 deletions test/components/structures/MainSplit-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ Please see LICENSE files in the repository root for full details.
*/

import React from "react";
import { render } from "@testing-library/react";
import { fireEvent, render } from "@testing-library/react";

import MainSplit from "../../../src/components/structures/MainSplit";
import ResizeNotifier from "../../../src/utils/ResizeNotifier";
import { PosthogAnalytics } from "../../../src/PosthogAnalytics.ts";

describe("<MainSplit/>", () => {
const resizeNotifier = new ResizeNotifier();
Expand All @@ -21,18 +22,33 @@ describe("<MainSplit/>", () => {
);
const panel = <div>Right panel</div>;

beforeEach(() => {
localStorage.clear();
});

it("renders", () => {
const { asFragment, container } = render(
<MainSplit resizeNotifier={resizeNotifier} children={children} panel={panel} />,
<MainSplit
resizeNotifier={resizeNotifier}
children={children}
panel={panel}
analyticsRoomType="other_room"
/>,
);
expect(asFragment()).toMatchSnapshot();
// Assert it matches the default width of 350
expect(container.querySelector<HTMLElement>(".mx_RightPanel_ResizeWrapper")!.style.width).toBe("350px");
// Assert it matches the default width of 320
expect(container.querySelector<HTMLElement>(".mx_RightPanel_ResizeWrapper")!.style.width).toBe("320px");
});

it("respects defaultSize prop", () => {
const { asFragment, container } = render(
<MainSplit resizeNotifier={resizeNotifier} children={children} panel={panel} defaultSize={500} />,
<MainSplit
resizeNotifier={resizeNotifier}
children={children}
panel={panel}
defaultSize={500}
analyticsRoomType="other_room"
/>,
);
expect(asFragment()).toMatchSnapshot();
// Assert it matches the default width of 350
Expand All @@ -48,8 +64,36 @@ describe("<MainSplit/>", () => {
panel={panel}
sizeKey="thread"
defaultSize={400}
analyticsRoomType="other_room"
/>,
);
expect(container.querySelector<HTMLElement>(".mx_RightPanel_ResizeWrapper")!.style.width).toBe("333px");
});

it("should report to analytics on resize stop", () => {
const { container } = render(
<MainSplit
resizeNotifier={resizeNotifier}
children={children}
panel={panel}
sizeKey="thread"
defaultSize={400}
analyticsRoomType="other_room"
/>,
);

const spy = jest.spyOn(PosthogAnalytics.instance, "trackEvent");

const handle = container.querySelector(".mx_ResizeHandle--horizontal")!;
fireEvent.mouseDown(handle);
fireEvent.mouseMove(handle, { clientX: 0 });
fireEvent.mouseUp(handle);

expect(spy).toHaveBeenCalledWith({
eventName: "WebPanelResize",
panel: "right",
roomType: "other_room",
size: 400,
});
});
});
6 changes: 6 additions & 0 deletions test/components/structures/RoomView-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,12 @@ describe("RoomView", () => {
expect(stores.rightPanelStore.isOpen).toEqual(true);
expect(stores.rightPanelStore.currentCard.phase).toEqual(RightPanelPhases.Timeline);
});

it("should render joined video room view", async () => {
jest.spyOn(room, "getMyMembership").mockReturnValue(KnownMembership.Join);
const { asFragment } = await mountRoomView();
expect(asFragment()).toMatchSnapshot();
});
});

describe("for a local room", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ exports[`<MainSplit/> renders 1`] = `
</div>
<div
class="mx_RightPanel_ResizeWrapper"
style="position: relative; user-select: auto; width: 350px; height: 100%; max-width: 50%; min-width: 264px; box-sizing: border-box; flex-shrink: 0;"
style="position: relative; user-select: auto; width: 320px; height: 100%; max-width: 50%; min-width: 264px; box-sizing: border-box; flex-shrink: 0;"
>
<div>
Right panel
Expand Down
Loading

0 comments on commit 754868e

Please sign in to comment.