diff --git a/package.json b/package.json index 2df1926c8a..f658bf04b6 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/playwright/snapshots/crypto/crypto.spec.ts/RoomSummaryCard-with-verified-e2ee-linux.png b/playwright/snapshots/crypto/crypto.spec.ts/RoomSummaryCard-with-verified-e2ee-linux.png index a8813b601d..3e68415017 100644 Binary files a/playwright/snapshots/crypto/crypto.spec.ts/RoomSummaryCard-with-verified-e2ee-linux.png and b/playwright/snapshots/crypto/crypto.spec.ts/RoomSummaryCard-with-verified-e2ee-linux.png differ diff --git a/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-empty-linux.png b/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-empty-linux.png index 38285305f6..16c694de95 100644 Binary files a/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-empty-linux.png and b/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-empty-linux.png differ diff --git a/playwright/snapshots/polls/polls.spec.ts/ThreadView-with-a-poll-on-bubble-layout-linux.png b/playwright/snapshots/polls/polls.spec.ts/ThreadView-with-a-poll-on-bubble-layout-linux.png index d35ec837b1..9a38579e21 100644 Binary files a/playwright/snapshots/polls/polls.spec.ts/ThreadView-with-a-poll-on-bubble-layout-linux.png and b/playwright/snapshots/polls/polls.spec.ts/ThreadView-with-a-poll-on-bubble-layout-linux.png differ diff --git a/playwright/snapshots/polls/polls.spec.ts/ThreadView-with-a-poll-on-group-layout-linux.png b/playwright/snapshots/polls/polls.spec.ts/ThreadView-with-a-poll-on-group-layout-linux.png index 0dfeb20b6a..f5bc02ef1e 100644 Binary files a/playwright/snapshots/polls/polls.spec.ts/ThreadView-with-a-poll-on-group-layout-linux.png and b/playwright/snapshots/polls/polls.spec.ts/ThreadView-with-a-poll-on-group-layout-linux.png differ diff --git a/playwright/snapshots/right-panel/file-panel.spec.ts/empty-linux.png b/playwright/snapshots/right-panel/file-panel.spec.ts/empty-linux.png index 178acd1828..9edd65a633 100644 Binary files a/playwright/snapshots/right-panel/file-panel.spec.ts/empty-linux.png and b/playwright/snapshots/right-panel/file-panel.spec.ts/empty-linux.png differ diff --git a/playwright/snapshots/right-panel/file-panel.spec.ts/file-tiles-list-linux.png b/playwright/snapshots/right-panel/file-panel.spec.ts/file-tiles-list-linux.png index c5bf1e7d6a..0593b44155 100644 Binary files a/playwright/snapshots/right-panel/file-panel.spec.ts/file-tiles-list-linux.png and b/playwright/snapshots/right-panel/file-panel.spec.ts/file-tiles-list-linux.png differ diff --git a/playwright/snapshots/right-panel/notification-panel.spec.ts/empty-linux.png b/playwright/snapshots/right-panel/notification-panel.spec.ts/empty-linux.png index b80b57fe4b..26481bfe5d 100644 Binary files a/playwright/snapshots/right-panel/notification-panel.spec.ts/empty-linux.png and b/playwright/snapshots/right-panel/notification-panel.spec.ts/empty-linux.png differ diff --git a/playwright/snapshots/right-panel/right-panel.spec.ts/with-name-and-address-linux.png b/playwright/snapshots/right-panel/right-panel.spec.ts/with-name-and-address-linux.png index 68f31135c5..4e3c67393b 100644 Binary files a/playwright/snapshots/right-panel/right-panel.spec.ts/with-name-and-address-linux.png and b/playwright/snapshots/right-panel/right-panel.spec.ts/with-name-and-address-linux.png differ diff --git a/playwright/snapshots/threads/threads.spec.ts/Reply-to-the-location-on-ThreadView-linux.png b/playwright/snapshots/threads/threads.spec.ts/Reply-to-the-location-on-ThreadView-linux.png index 32950f4dde..4652833628 100644 Binary files a/playwright/snapshots/threads/threads.spec.ts/Reply-to-the-location-on-ThreadView-linux.png and b/playwright/snapshots/threads/threads.spec.ts/Reply-to-the-location-on-ThreadView-linux.png differ diff --git a/playwright/snapshots/timeline/timeline.spec.ts/highlighted-search-results-linux.png b/playwright/snapshots/timeline/timeline.spec.ts/highlighted-search-results-linux.png index 347c7a5477..008ebc82e3 100644 Binary files a/playwright/snapshots/timeline/timeline.spec.ts/highlighted-search-results-linux.png and b/playwright/snapshots/timeline/timeline.spec.ts/highlighted-search-results-linux.png differ diff --git a/playwright/snapshots/timeline/timeline.spec.ts/search-aux-panel-linux.png b/playwright/snapshots/timeline/timeline.spec.ts/search-aux-panel-linux.png index fe96a9e6be..b50f176222 100644 Binary files a/playwright/snapshots/timeline/timeline.spec.ts/search-aux-panel-linux.png and b/playwright/snapshots/timeline/timeline.spec.ts/search-aux-panel-linux.png differ diff --git a/playwright/snapshots/timeline/timeline.spec.ts/search-results-with-TextualEvent-linux.png b/playwright/snapshots/timeline/timeline.spec.ts/search-results-with-TextualEvent-linux.png index c1d762d512..cf489b1836 100644 Binary files a/playwright/snapshots/timeline/timeline.spec.ts/search-results-with-TextualEvent-linux.png and b/playwright/snapshots/timeline/timeline.spec.ts/search-results-with-TextualEvent-linux.png differ diff --git a/playwright/snapshots/user-view/user-view.spec.ts/user-info-linux.png b/playwright/snapshots/user-view/user-view.spec.ts/user-info-linux.png index 6e4df5c776..0612fe1ba7 100644 Binary files a/playwright/snapshots/user-view/user-view.spec.ts/user-info-linux.png and b/playwright/snapshots/user-view/user-view.spec.ts/user-info-linux.png differ diff --git a/src/components/structures/MainSplit.tsx b/src/components/structures/MainSplit.tsx index 282ec69e18..54aa220354 100644 --- a/src/components/structures/MainSplit.tsx +++ b/src/components/structures/MainSplit.tsx @@ -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; @@ -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 { public static defaultProps = { - defaultSize: 350, + defaultSize: 320, }; private onResizeStart = (): void => { @@ -58,11 +62,16 @@ export default class MainSplit extends React.Component { 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({ + eventName: "WebPanelResize", + panel: "right", + roomType: this.props.analyticsRoomType, + size: newSize, + }); }; private loadSidePanelSize(): { height: string | number; width: number } { diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index ba30a3445d..958c93bebc 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -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, @@ -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"; @@ -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; @@ -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. @@ -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; @@ -399,7 +389,6 @@ export class RoomView extends React.Component { showApps: false, isPeeking: false, showRightPanel: false, - threadRightPanel: false, joining: false, showTopUnreadMessagesBar: false, statusBarVisible: false, @@ -626,11 +615,6 @@ export class RoomView extends React.Component { 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(), @@ -1033,11 +1017,6 @@ export class RoomView extends React.Component { 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, }); }; @@ -2531,6 +2510,17 @@ export class RoomView extends React.Component { } const mainSplitContentClasses = classNames("mx_RoomView_body", mainSplitContentClassName); + let sizeKey: string | undefined; + let defaultSize: number | undefined; + let analyticsRoomType: ComponentProps["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 (
@@ -2541,10 +2531,9 @@ export class RoomView extends React.Component {
{ return (
- + {this.renderBody()} diff --git a/src/components/structures/UserView.tsx b/src/components/structures/UserView.tsx index 4647c24b26..635115877e 100644 --- a/src/components/structures/UserView.tsx +++ b/src/components/structures/UserView.tsx @@ -87,7 +87,12 @@ export default class UserView extends React.Component { /> ); return ( - + ); diff --git a/src/contexts/RoomContext.ts b/src/contexts/RoomContext.ts index 8fb94a245d..acd4bfa6f4 100644 --- a/src/contexts/RoomContext.ts +++ b/src/contexts/RoomContext.ts @@ -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; @@ -35,7 +43,6 @@ const RoomContext = createContext< showApps: false, isPeeking: false, showRightPanel: true, - threadRightPanel: false, joining: false, showTopUnreadMessagesBar: false, statusBarVisible: false, @@ -59,6 +66,7 @@ const RoomContext = createContext< matrixClientIsReady: false, showUrlPreview: false, timelineRenderingType: TimelineRenderingType.Room, + mainSplitContentType: MainSplitContentType.Timeline, threadId: undefined, liveTimeline: undefined, narrow: false, diff --git a/test/components/structures/MainSplit-test.tsx b/test/components/structures/MainSplit-test.tsx index 28152fefa2..6dbc733075 100644 --- a/test/components/structures/MainSplit-test.tsx +++ b/test/components/structures/MainSplit-test.tsx @@ -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("", () => { const resizeNotifier = new ResizeNotifier(); @@ -21,18 +22,33 @@ describe("", () => { ); const panel =
Right panel
; + beforeEach(() => { + localStorage.clear(); + }); + it("renders", () => { const { asFragment, container } = render( - , + , ); expect(asFragment()).toMatchSnapshot(); - // Assert it matches the default width of 350 - expect(container.querySelector(".mx_RightPanel_ResizeWrapper")!.style.width).toBe("350px"); + // Assert it matches the default width of 320 + expect(container.querySelector(".mx_RightPanel_ResizeWrapper")!.style.width).toBe("320px"); }); it("respects defaultSize prop", () => { const { asFragment, container } = render( - , + , ); expect(asFragment()).toMatchSnapshot(); // Assert it matches the default width of 350 @@ -48,8 +64,36 @@ describe("", () => { panel={panel} sizeKey="thread" defaultSize={400} + analyticsRoomType="other_room" />, ); expect(container.querySelector(".mx_RightPanel_ResizeWrapper")!.style.width).toBe("333px"); }); + + it("should report to analytics on resize stop", () => { + const { container } = render( + , + ); + + 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, + }); + }); }); diff --git a/test/components/structures/RoomView-test.tsx b/test/components/structures/RoomView-test.tsx index e1dad1cb9d..1e11272c56 100644 --- a/test/components/structures/RoomView-test.tsx +++ b/test/components/structures/RoomView-test.tsx @@ -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", () => { diff --git a/test/components/structures/__snapshots__/MainSplit-test.tsx.snap b/test/components/structures/__snapshots__/MainSplit-test.tsx.snap index d6cd201594..94f5b23604 100644 --- a/test/components/structures/__snapshots__/MainSplit-test.tsx.snap +++ b/test/components/structures/__snapshots__/MainSplit-test.tsx.snap @@ -14,7 +14,7 @@ exports[` renders 1`] = `
Right panel diff --git a/test/components/structures/__snapshots__/RoomView-test.tsx.snap b/test/components/structures/__snapshots__/RoomView-test.tsx.snap index 25740fbd0b..f6a79b6cd7 100644 --- a/test/components/structures/__snapshots__/RoomView-test.tsx.snap +++ b/test/components/structures/__snapshots__/RoomView-test.tsx.snap @@ -1125,3 +1125,322 @@ exports[`RoomView should show error view if failed to look up room alias 1`] = `
`; + +exports[`RoomView video rooms should render joined video room view 1`] = ` + +
+