Move ResizerNotifier into SDKContext (#30939)

* Move ResizerNotifier into SDKContext

so we don't have to pass it into RoomView

* Fix test

* Unused import

* Add tests

* Remove a bunch of resizeNotifier props

* Remove more resizeNotifier props

* Add resizenotifier to test

* Add more sdkcontext wrappers in tests

* More sdkcontext wrappers

* Even more sdkcontext wrappers

* Add test to make sonarcloud happy

* Context isn't always there unlike props

* Test actual resizing too

* Remove commented line
This commit is contained in:
David Baker
2025-10-06 10:23:06 +01:00
committed by GitHub
parent 87fdf96192
commit c08775588d
32 changed files with 490 additions and 443 deletions

View File

@@ -27,7 +27,6 @@ import EventIndexPeg from "../../indexing/EventIndexPeg";
import { _t } from "../../languageHandler";
import SearchWarning, { WarningKind } from "../views/elements/SearchWarning";
import BaseCard from "../views/right_panel/BaseCard";
import type ResizeNotifier from "../../utils/ResizeNotifier";
import TimelinePanel from "./TimelinePanel";
import Spinner from "../views/elements/Spinner";
import { Layout } from "../../settings/enums/Layout";
@@ -39,7 +38,6 @@ import { ScopedRoomContextProvider } from "../../contexts/ScopedRoomContext.tsx"
interface IProps {
roomId: string;
onClose: () => void;
resizeNotifier: ResizeNotifier;
}
interface IState {
@@ -294,7 +292,6 @@ class FilePanel extends React.Component<IProps, IState> {
timelineSet={this.state.timelineSet}
showUrlPreview={false}
onPaginationRequest={this.onPaginationRequest}
resizeNotifier={this.props.resizeNotifier}
empty={emptyState}
layout={Layout.Group}
/>

View File

@@ -30,7 +30,6 @@ import SettingsStore from "../../settings/SettingsStore";
import { SettingLevel } from "../../settings/SettingLevel";
import ResizeHandle from "../views/elements/ResizeHandle";
import { CollapseDistributor, Resizer } from "../../resizer";
import type ResizeNotifier from "../../utils/ResizeNotifier";
import PlatformPeg from "../../PlatformPeg";
import { DefaultTagID } from "../../stores/room-list/models";
import { hideToast as hideServerLimitToast, showToast as showServerLimitToast } from "../../toasts/ServerLimitToast";
@@ -67,6 +66,7 @@ import { monitorSyncedPushRules } from "../../utils/pushRules/monitorSyncedPushR
import { type ConfigOptions } from "../../SdkConfig";
import { MatrixClientContextProvider } from "./MatrixClientContextProvider";
import { Landmark, LandmarkNavigation } from "../../accessibility/LandmarkNavigation";
import { SDKContext } from "../../contexts/SDKContext.ts";
// We need to fetch each pinned message individually (if we don't already have it)
// so each pinned message may trigger a request. Limit the number per room for sanity.
@@ -86,7 +86,6 @@ interface IProps {
// transitioned to PWLU)
onRegistered: (credentials: IMatrixClientCreds) => Promise<MatrixClient>;
hideToSRUsers: boolean;
resizeNotifier: ResizeNotifier;
// eslint-disable-next-line camelcase
page_type?: string;
autoJoin?: boolean;
@@ -134,8 +133,11 @@ class LoggedInView extends React.Component<IProps, IState> {
protected timezoneProfileUpdateRef?: string[];
protected resizer?: Resizer<ICollapseConfig, CollapseItem>;
public constructor(props: IProps) {
super(props);
public static contextType = SDKContext;
declare public context: React.ContextType<typeof SDKContext>;
public constructor(props: IProps, context: React.ContextType<typeof SDKContext>) {
super(props, context);
this.state = {
syncErrorData: undefined,
@@ -281,15 +283,15 @@ class LoggedInView extends React.Component<IProps, IState> {
},
onResized: (size) => {
panelSize = size;
this.props.resizeNotifier.notifyLeftHandleResized();
this.context.resizeNotifier.notifyLeftHandleResized();
},
onResizeStart: () => {
this.props.resizeNotifier.startResizing();
this.context.resizeNotifier.startResizing();
},
onResizeStop: () => {
// Always save the lhs size for the new room list.
if (useNewRoomList || !panelCollapsed) window.localStorage.setItem("mx_lhs_size", "" + panelSize);
this.props.resizeNotifier.stopResizing();
this.context.resizeNotifier.stopResizing();
},
isItemCollapsed: (domNode) => {
// New rooms list does not support collapsing.
@@ -681,7 +683,6 @@ class LoggedInView extends React.Component<IProps, IState> {
threepidInvite={this.props.threepidInvite}
oobData={this.props.roomOobData}
key={this.props.currentRoomId || "roomview"}
resizeNotifier={this.props.resizeNotifier}
justCreatedOpts={this.props.roomJustCreatedOpts}
forceTimeline={this.props.forceTimeline}
/>
@@ -695,7 +696,7 @@ class LoggedInView extends React.Component<IProps, IState> {
case PageTypes.UserView:
if (!!this.props.currentUserId) {
pageElement = (
<UserView userId={this.props.currentUserId} resizeNotifier={this.props.resizeNotifier} />
<UserView userId={this.props.currentUserId} resizeNotifier={this.context.resizeNotifier} />
);
}
break;
@@ -748,7 +749,7 @@ class LoggedInView extends React.Component<IProps, IState> {
<LeftPanel
pageType={this.props.page_type as PageTypes}
isMinimized={shouldUseMinimizedUI || false}
resizeNotifier={this.props.resizeNotifier}
resizeNotifier={this.context.resizeNotifier}
/>
</div>
</div>

View File

@@ -12,11 +12,10 @@ import { type NumberSize, Resizable } from "re-resizable";
import { type Direction } from "re-resizable/lib/resizer";
import { type WebPanelResize } from "@matrix-org/analytics-events/types/typescript/WebPanelResize";
import type ResizeNotifier from "../../utils/ResizeNotifier";
import { PosthogAnalytics } from "../../PosthogAnalytics.ts";
import { SDKContext } from "../../contexts/SDKContext.ts";
interface IProps {
resizeNotifier: ResizeNotifier;
collapsedRhs?: boolean;
panel?: JSX.Element;
children: ReactNode;
@@ -36,16 +35,23 @@ interface IProps {
}
export default class MainSplit extends React.Component<IProps> {
public static contextType = SDKContext;
declare public context: React.ContextType<typeof SDKContext>;
public static defaultProps = {
defaultSize: 320,
};
public constructor(props: IProps, context: React.ContextType<typeof SDKContext>) {
super(props, context);
}
private onResizeStart = (): void => {
this.props.resizeNotifier.startResizing();
this.context.resizeNotifier.startResizing();
};
private onResize = (): void => {
this.props.resizeNotifier.notifyRightHandleResized();
this.context.resizeNotifier.notifyRightHandleResized();
};
private get sizeSettingStorageKey(): string {
@@ -63,7 +69,7 @@ export default class MainSplit extends React.Component<IProps> {
delta: NumberSize,
): void => {
const newSize = this.loadSidePanelSize().width + delta.width;
this.props.resizeNotifier.stopResizing();
this.context.resizeNotifier.stopResizing();
window.localStorage.setItem(this.sizeSettingStorageKey, newSize.toString());
PosthogAnalytics.instance.trackEvent<WebPanelResize>({

View File

@@ -49,7 +49,6 @@ import { _t, _td } from "../../languageHandler";
import SettingsStore from "../../settings/SettingsStore";
import ThemeController from "../../settings/controllers/ThemeController";
import { startAnyRegistrationFlow } from "../../Registration";
import ResizeNotifier from "../../utils/ResizeNotifier";
import AutoDiscoveryUtils from "../../utils/AutoDiscoveryUtils";
import { calculateRoomVia, makeRoomPermalink } from "../../utils/permalinks/Permalinks";
import ThemeWatcher, { ThemeWatcherEvent } from "../../settings/watchers/ThemeWatcher";
@@ -199,7 +198,6 @@ interface IState {
// and disable it when there are no dialogs
hideToSRUsers: boolean;
syncError: Error | null;
resizeNotifier: ResizeNotifier;
serverConfig?: ValidatedServerConfig;
ready: boolean;
threepidInvite?: IThreepidInvite;
@@ -254,7 +252,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
isMobileRegistration: false,
syncError: null, // If the current syncing status is ERROR, the error object, otherwise null.
resizeNotifier: new ResizeNotifier(),
ready: false,
};
@@ -459,7 +456,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
UIStore.instance.on(UI_EVENTS.Resize, this.handleResize);
// For PersistentElement
this.state.resizeNotifier.on("middlePanelResized", this.dispatchTimelineResize);
this.stores.resizeNotifier.on("middlePanelResized", this.dispatchTimelineResize);
RoomNotificationStateStore.instance.on(UPDATE_STATUS_INDICATOR, this.onUpdateStatusIndicator);
@@ -511,7 +508,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
this.themeWatcher?.stop();
this.fontWatcher?.stop();
UIStore.destroy();
this.state.resizeNotifier.removeListener("middlePanelResized", this.dispatchTimelineResize);
this.stores.resizeNotifier.removeListener("middlePanelResized", this.dispatchTimelineResize);
window.removeEventListener("resize", this.onWindowResized);
}
@@ -828,7 +825,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
collapseLhs: true,
},
() => {
this.state.resizeNotifier.notifyLeftHandleResized();
this.stores.resizeNotifier.notifyLeftHandleResized();
},
);
break;
@@ -838,7 +835,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
collapseLhs: false,
},
() => {
this.state.resizeNotifier.notifyLeftHandleResized();
this.stores.resizeNotifier.notifyLeftHandleResized();
},
);
break;
@@ -1957,7 +1954,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}
this.prevWindowWidth = width;
this.state.resizeNotifier.notifyWindowResized();
this.stores.resizeNotifier.notifyWindowResized();
};
private dispatchTimelineResize(): void {

View File

@@ -39,7 +39,6 @@ import ScrollPanel, { type IScrollState } from "./ScrollPanel";
import DateSeparator from "../views/messages/DateSeparator";
import TimelineSeparator, { SeparatorKind } from "../views/messages/TimelineSeparator";
import ErrorBoundary from "../views/elements/ErrorBoundary";
import type ResizeNotifier from "../../utils/ResizeNotifier";
import Spinner from "../views/elements/Spinner";
import { type RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
import type EditorStateTransfer from "../../utils/EditorStateTransfer";
@@ -167,7 +166,6 @@ interface IProps {
// which layout to use
layout?: Layout;
resizeNotifier?: ResizeNotifier;
permalinkCreator?: RoomPermalinkCreator;
editState?: EditorStateTransfer;
@@ -1064,7 +1062,6 @@ export default class MessagePanel extends React.Component<IProps, IState> {
onUnfillRequest={this.props.onUnfillRequest}
style={style}
stickyBottom={this.props.stickyBottom}
resizeNotifier={this.props.resizeNotifier}
fixedChildren={ircResizer}
>
{topSpinner}

View File

@@ -224,9 +224,7 @@ export default class RightPanel extends React.Component<Props, IState> {
break;
case RightPanelPhases.FilePanel:
if (!!roomId) {
card = (
<FilePanel roomId={roomId} resizeNotifier={this.props.resizeNotifier} onClose={this.onClose} />
);
card = <FilePanel roomId={roomId} onClose={this.onClose} />;
}
break;

View File

@@ -21,7 +21,6 @@ import { _t } from "../../languageHandler";
import { haveRendererForEvent } from "../../events/EventTileFactory";
import SearchResultTile from "../views/rooms/SearchResultTile";
import { searchPagination, SearchScope } from "../../Searching";
import type ResizeNotifier from "../../utils/ResizeNotifier";
import MatrixClientContext from "../../contexts/MatrixClientContext";
import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
import { useScopedRoomContext } from "../../contexts/ScopedRoomContext.tsx";
@@ -41,7 +40,6 @@ interface Props {
inProgress: boolean;
promise: Promise<ISearchResults>;
abortController?: AbortController;
resizeNotifier: ResizeNotifier;
className: string;
onUpdate(inProgress: boolean, results: ISearchResults | null, error: Error | null): void;
ref?: Ref<ScrollPanel>;
@@ -54,7 +52,6 @@ export const RoomSearchView = ({
scope,
promise,
abortController,
resizeNotifier,
className,
onUpdate,
inProgress,
@@ -309,7 +306,6 @@ export const RoomSearchView = ({
ref={onRef}
className={"mx_RoomView_searchResultsPanel " + className}
onFillRequest={onSearchResultsFillRequest}
resizeNotifier={resizeNotifier}
>
<li className="mx_RoomView_scrollheader" />
{ret}

View File

@@ -151,7 +151,6 @@ interface IRoomProps {
threepidInvite?: IThreepidInvite;
oobData?: IOOBData;
resizeNotifier: ResizeNotifier;
justCreatedOpts?: IOpts;
forceTimeline?: boolean; // should we force access to the timeline, overriding (for eg) spaces
@@ -321,7 +320,7 @@ function LocalRoomView(props: LocalRoomViewProps): ReactElement {
<main className="mx_RoomView_body" ref={props.roomView} aria-label={_t("room|room_content")}>
<FileDropTarget parent={props.roomView.current} onFileDrop={props.onFileDrop} room={room} />
<div className="mx_RoomView_timeline">
<ScrollPanel className="mx_RoomView_messagePanel" resizeNotifier={props.resizeNotifier}>
<ScrollPanel className="mx_RoomView_messagePanel">
{encryptionTile}
<NewRoomIntro />
</ScrollPanel>
@@ -337,7 +336,6 @@ function LocalRoomView(props: LocalRoomViewProps): ReactElement {
interface ILocalRoomCreateLoaderProps {
localRoom: LocalRoom;
names: string;
resizeNotifier: ResizeNotifier;
mainSplitContentType: MainSplitContentType;
}
@@ -894,7 +892,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
WidgetEchoStore.on(UPDATE_EVENT, this.onWidgetEchoStoreUpdate);
this.context.widgetStore.on(UPDATE_EVENT, this.onWidgetStoreUpdate);
this.props.resizeNotifier.on("isResizing", this.onIsResizing);
this.context.resizeNotifier.on("isResizing", this.onIsResizing);
this.settingWatchers = [
SettingsStore.watchSetting("layout", null, (...[, , , value]) =>
@@ -1010,7 +1008,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
WidgetEchoStore.removeListener(UPDATE_EVENT, this.onWidgetEchoStoreUpdate);
this.context.widgetStore.removeListener(UPDATE_EVENT, this.onWidgetStoreUpdate);
this.props.resizeNotifier.off("isResizing", this.onIsResizing);
this.context.resizeNotifier.off("isResizing", this.onIsResizing);
if (this.state.room) {
this.context.widgetLayoutStore.off(
@@ -2056,7 +2054,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
<LocalRoomCreateLoader
localRoom={localRoom}
names={names}
resizeNotifier={this.props.resizeNotifier}
mainSplitContentType={this.state.mainSplitContentType}
/>
</ScopedRoomContextProvider>
@@ -2069,7 +2066,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
<LocalRoomView
e2eStatus={this.state.e2eStatus}
localRoom={localRoom}
resizeNotifier={this.props.resizeNotifier}
resizeNotifier={this.context.resizeNotifier}
permalinkCreator={this.permalinkCreator}
roomView={this.roomView}
onFileDrop={this.onFileDrop}
@@ -2083,7 +2080,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
return (
<ScopedRoomContextProvider {...this.state}>
<WaitingForThirdPartyRoomView
resizeNotifier={this.props.resizeNotifier}
resizeNotifier={this.context.resizeNotifier}
roomView={this.roomView}
inviteEvent={inviteEvent}
/>
@@ -2402,7 +2399,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
<SpaceRoomView
space={this.state.room}
justCreatedOpts={this.props.justCreatedOpts}
resizeNotifier={this.props.resizeNotifier}
resizeNotifier={this.context.resizeNotifier}
permalinkCreator={this.permalinkCreator}
onJoinButtonClicked={this.onJoinButtonClicked}
onRejectButtonClicked={
@@ -2419,18 +2416,13 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
room={this.state.room}
userId={this.context.client.getSafeUserId()}
showApps={this.state.showApps}
resizeNotifier={this.props.resizeNotifier}
>
{aux}
</AuxPanel>
);
const pinnedMessageBanner = (
<PinnedMessageBanner
room={this.state.room}
permalinkCreator={this.permalinkCreator}
resizeNotifier={this.props.resizeNotifier}
/>
<PinnedMessageBanner room={this.state.room} permalinkCreator={this.permalinkCreator} />
);
let messageComposer;
@@ -2444,7 +2436,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
<MessageComposer
room={this.state.room}
e2eStatus={this.state.e2eStatus}
resizeNotifier={this.props.resizeNotifier}
resizeNotifier={this.context.resizeNotifier}
replyToEvent={this.state.replyToEvent}
permalinkCreator={this.permalinkCreator}
/>
@@ -2466,7 +2458,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
promise={this.state.search.promise}
abortController={this.state.search.abortController}
inProgress={!!this.state.search.inProgress}
resizeNotifier={this.props.resizeNotifier}
className={this.messagePanelClassNames}
onUpdate={this.onSearchUpdate}
/>
@@ -2501,7 +2492,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
className={this.messagePanelClassNames}
membersLoaded={this.state.membersLoaded}
permalinkCreator={this.permalinkCreator}
resizeNotifier={this.props.resizeNotifier}
showReactions={true}
layout={this.state.layout}
editState={this.state.editState}
@@ -2533,7 +2523,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
const rightPanel = showRightPanel ? (
<RightPanel
room={this.state.room}
resizeNotifier={this.props.resizeNotifier}
resizeNotifier={this.context.resizeNotifier}
permalinkCreator={this.permalinkCreator}
e2eStatus={this.state.e2eStatus}
onSearchChange={this.onSearchChange}
@@ -2594,7 +2584,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
<AppsDrawer
room={this.state.room}
userId={this.context.client.getSafeUserId()}
resizeNotifier={this.props.resizeNotifier}
showApps={true}
role="main"
/>
@@ -2639,7 +2628,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
<ErrorBoundary>
<MainSplit
panel={rightPanel}
resizeNotifier={this.props.resizeNotifier}
sizeKey={sizeKey}
defaultSize={defaultSize}
analyticsRoomType={analyticsRoomType}

View File

@@ -13,8 +13,8 @@ import SettingsStore from "../../settings/SettingsStore";
import Timer from "../../utils/Timer";
import AutoHideScrollbar from "./AutoHideScrollbar";
import { getKeyBindingsManager } from "../../KeyBindingsManager";
import type ResizeNotifier from "../../utils/ResizeNotifier";
import { KeyBindingAction } from "../../accessibility/KeyboardShortcuts";
import { SDKContext } from "../../contexts/SDKContext";
// The amount of extra scroll distance to allow prior to unfilling.
// See getExcessHeight.
@@ -58,10 +58,6 @@ interface IProps {
*/
style?: CSSProperties;
/* resizeNotifier: ResizeNotifier to know when middle column has changed size
*/
resizeNotifier?: ResizeNotifier;
/* fixedChildren: allows for children to be passed which are rendered outside
* of the wrapper
*/
@@ -188,15 +184,18 @@ export default class ScrollPanel extends React.Component<IProps> {
private heightUpdateInProgress = false;
public divScroll: HTMLDivElement | null = null;
public constructor(props: IProps) {
super(props);
public static contextType = SDKContext;
declare public context: React.ContextType<typeof SDKContext>;
public constructor(props: IProps, context: React.ContextType<typeof SDKContext>) {
super(props, context);
this.resetScrollState();
}
public componentDidMount(): void {
this.unmounted = false;
this.props.resizeNotifier?.on("middlePanelResizedNoisy", this.onResize);
this.context?.resizeNotifier?.on("middlePanelResizedNoisy", this.onResize);
this.checkScroll();
}
@@ -217,14 +216,14 @@ export default class ScrollPanel extends React.Component<IProps> {
// (We could use isMounted(), but facebook have deprecated that.)
this.unmounted = true;
this.props.resizeNotifier?.removeListener("middlePanelResizedNoisy", this.onResize);
this.context?.resizeNotifier?.removeListener("middlePanelResizedNoisy", this.onResize);
this.divScroll = null;
}
private onScroll = (ev: Event): void => {
// skip scroll events caused by resizing
if (this.props.resizeNotifier && this.props.resizeNotifier.isResizing) return;
if (this.context?.resizeNotifier && this.context.resizeNotifier.isResizing) return;
debuglog("onScroll called past resize gate; scroll node top:", this.getScrollNode().scrollTop);
this.scrollTimeout?.restart();
this.saveScrollState();

View File

@@ -763,7 +763,7 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
return (
<main className="mx_SpaceRoomView">
<ErrorBoundary>
<MainSplit panel={rightPanel} resizeNotifier={this.props.resizeNotifier} analyticsRoomType="space">
<MainSplit panel={rightPanel} analyticsRoomType="space">
{this.renderBody()}
</MainSplit>
</ErrorBoundary>

View File

@@ -47,7 +47,6 @@ import shouldHideEvent from "../../shouldHideEvent";
import MessagePanel from "./MessagePanel";
import { type IScrollState } from "./ScrollPanel";
import { type ActionPayload } from "../../dispatcher/payloads";
import type ResizeNotifier from "../../utils/ResizeNotifier";
import { type RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
import Spinner from "../views/elements/Spinner";
import type EditorStateTransfer from "../../utils/EditorStateTransfer";
@@ -123,7 +122,6 @@ interface IProps {
// whether to always show timestamps for an event
alwaysShowTimestamps?: boolean;
resizeNotifier?: ResizeNotifier;
editState?: EditorStateTransfer;
permalinkCreator?: RoomPermalinkCreator;
membersLoaded?: boolean;
@@ -1849,7 +1847,6 @@ class TimelinePanel extends React.Component<IProps, IState> {
this.state.alwaysShowTimestamps
}
className={this.props.className}
resizeNotifier={this.props.resizeNotifier}
getRelationsForEvent={this.getRelationsForEvent}
editState={this.props.editState}
showReactions={this.props.showReactions}

View File

@@ -87,12 +87,7 @@ export default class UserView extends React.Component<IProps, IState> {
/>
);
return (
<MainSplit
panel={panel}
resizeNotifier={this.props.resizeNotifier}
defaultSize={420}
analyticsRoomType="user_profile"
>
<MainSplit panel={panel} defaultSize={420} analyticsRoomType="user_profile">
<HomePage />
</MainSplit>
);

View File

@@ -41,7 +41,7 @@ export const WaitingForThirdPartyRoomView: React.FC<Props> = ({ roomView, resize
<RoomHeader room={context.room!} />
<main className="mx_RoomView_body" ref={roomView}>
<div className="mx_RoomView_timeline">
<ScrollPanel className="mx_RoomView_messagePanel" resizeNotifier={resizeNotifier}>
<ScrollPanel className="mx_RoomView_messagePanel">
<EventTileBubble
className="mx_cryptoEvent mx_cryptoEvent_icon"
title={_t("room|waiting_for_join_title", { brand })}

View File

@@ -234,7 +234,6 @@ export default class TimelineCard extends React.Component<IProps, IState> {
membersLoaded={true}
editState={this.state.editState}
eventId={this.state.initialEventId}
resizeNotifier={this.props.resizeNotifier}
highlightedEventId={highlightedEventId}
onScroll={this.onScroll}
/>

View File

@@ -27,11 +27,11 @@ import UIStore from "../../../stores/UIStore";
import { type ActionPayload } from "../../../dispatcher/payloads";
import Spinner from "../elements/Spinner";
import SdkConfig from "../../../SdkConfig";
import { SDKContext } from "../../../contexts/SDKContext";
interface IProps {
userId: string;
room: Room;
resizeNotifier: ResizeNotifier;
showApps?: boolean; // Should apps be rendered
maxHeight: number;
role?: AriaRole;
@@ -57,8 +57,11 @@ export default class AppsDrawer extends React.Component<IProps, IState> {
showApps: true,
};
public constructor(props: IProps) {
super(props);
public static contextType = SDKContext;
declare public context: React.ContextType<typeof SDKContext>;
public constructor(props: IProps, context: React.ContextType<typeof SDKContext>) {
super(props, context);
this.state = {
apps: this.getApps(),
@@ -73,7 +76,7 @@ export default class AppsDrawer extends React.Component<IProps, IState> {
public componentDidMount(): void {
this.unmounted = false;
this.props.resizeNotifier.on("isResizing", this.onIsResizing);
this.context.resizeNotifier.on("isResizing", this.onIsResizing);
ScalarMessaging.startListening();
WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(this.props.room), this.updateApps);
@@ -88,7 +91,7 @@ export default class AppsDrawer extends React.Component<IProps, IState> {
if (this.resizeContainer) {
this.resizer.detach();
}
this.props.resizeNotifier.off("isResizing", this.onIsResizing);
this.context.resizeNotifier.off("isResizing", this.onIsResizing);
}
private onIsResizing = (resizing: boolean): void => {
@@ -281,7 +284,7 @@ export default class AppsDrawer extends React.Component<IProps, IState> {
className="mx_AppsDrawer_resizer"
handleWrapperClass="mx_AppsDrawer_resizer_container"
handleClass="mx_AppsDrawer_resizer_container_handle"
resizeNotifier={this.props.resizeNotifier}
resizeNotifier={this.context.resizeNotifier}
>
{appContainers}
</PersistentVResizer>

View File

@@ -13,7 +13,6 @@ import AppsDrawer from "./AppsDrawer";
import SettingsStore from "../../../settings/SettingsStore";
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
import { UIFeature } from "../../../settings/UIFeature";
import type ResizeNotifier from "../../../utils/ResizeNotifier";
import LegacyCallViewForRoom from "../voip/LegacyCallViewForRoom";
import { objectHasDiff } from "../../../utils/objects";
@@ -22,7 +21,6 @@ interface IProps {
room: Room;
userId: string;
showApps: boolean; // Render apps
resizeNotifier: ResizeNotifier;
children?: ReactNode;
}
@@ -36,23 +34,12 @@ export default class AuxPanel extends React.Component<IProps> {
}
public render(): React.ReactNode {
const callView = (
<LegacyCallViewForRoom
roomId={this.props.room.roomId}
resizeNotifier={this.props.resizeNotifier}
showApps={this.props.showApps}
/>
);
const callView = <LegacyCallViewForRoom roomId={this.props.room.roomId} showApps={this.props.showApps} />;
let appsDrawer;
if (SettingsStore.getValue(UIFeature.Widgets)) {
appsDrawer = (
<AppsDrawer
room={this.props.room}
userId={this.props.userId}
showApps={this.props.showApps}
resizeNotifier={this.props.resizeNotifier}
/>
<AppsDrawer room={this.props.room} userId={this.props.userId} showApps={this.props.showApps} />
);
}

View File

@@ -6,7 +6,7 @@
* Please see LICENSE files in the repository root for full details.
*/
import React, { type JSX, useEffect, useId, useRef, useState } from "react";
import React, { type JSX, useContext, useEffect, useId, useRef, useState } from "react";
import PinIcon from "@vector-im/compound-design-tokens/assets/web/icons/pin-solid";
import { Button } from "@vector-im/compound-web";
import { type MatrixEvent, type Room } from "matrix-js-sdk/src/matrix";
@@ -25,7 +25,7 @@ import { Action } from "../../../dispatcher/actions";
import MessageEvent from "../messages/MessageEvent";
import PosthogTrackers from "../../../PosthogTrackers.ts";
import { EventPreview } from "./EventPreview.tsx";
import type ResizeNotifier from "../../../utils/ResizeNotifier";
import { SDKContext } from "../../../contexts/SDKContext.ts";
/**
* The props for the {@link PinnedMessageBanner} component.
@@ -39,20 +39,12 @@ interface PinnedMessageBannerProps {
* The room where the banner is displayed
*/
room: Room;
/**
* The resize notifier to notify the timeline to resize itself when the banner is displayed or hidden.
*/
resizeNotifier: ResizeNotifier;
}
/**
* A banner that displays the pinned messages in a room.
*/
export function PinnedMessageBanner({
room,
permalinkCreator,
resizeNotifier,
}: PinnedMessageBannerProps): JSX.Element | null {
export function PinnedMessageBanner({ room, permalinkCreator }: PinnedMessageBannerProps): JSX.Element | null {
const pinnedEventIds = usePinnedEvents(room);
const pinnedEvents = useSortedFetchedPinnedEvents(room, pinnedEventIds);
const eventCount = pinnedEvents.length;
@@ -67,7 +59,7 @@ export function PinnedMessageBanner({
const isLastMessage = currentEventIndex === eventCount - 1;
const pinnedEvent = pinnedEvents[currentEventIndex];
useNotifyTimeline(pinnedEvent, resizeNotifier);
useNotifyTimeline(pinnedEvent);
const id = useId();
@@ -152,9 +144,10 @@ export function PinnedMessageBanner({
/**
* When the banner is displayed or hidden, we want to notify the timeline to resize itself.
* @param pinnedEvent
* @param resizeNotifier
*/
function useNotifyTimeline(pinnedEvent: MatrixEvent | null, resizeNotifier: ResizeNotifier): void {
function useNotifyTimeline(pinnedEvent: MatrixEvent | null): void {
const resizeNotifier = useContext(SDKContext).resizeNotifier;
const previousEvent = useRef<MatrixEvent | null>(null);
useEffect(() => {
// If we switch from a pinned message to no pinned message or the opposite, we want to resize the timeline

View File

@@ -12,14 +12,12 @@ import { Resizable } from "re-resizable";
import LegacyCallHandler, { LegacyCallHandlerEvent } from "../../../LegacyCallHandler";
import LegacyCallView from "./LegacyCallView";
import type ResizeNotifier from "../../../utils/ResizeNotifier";
import { SDKContext } from "../../../contexts/SDKContext";
interface IProps {
// What room we should display the call for
roomId: string;
resizeNotifier: ResizeNotifier;
showApps?: boolean;
}
@@ -33,8 +31,11 @@ interface IState {
* or nothing if there is no call in that room.
*/
export default class LegacyCallViewForRoom extends React.Component<IProps, IState> {
public constructor(props: IProps) {
super(props);
public static contextType = SDKContext;
declare public context: React.ContextType<typeof SDKContext>;
public constructor(props: IProps, context: React.ContextType<typeof SDKContext>) {
super(props, context);
const call = this.getCall();
this.state = {
call,
@@ -73,15 +74,15 @@ export default class LegacyCallViewForRoom extends React.Component<IProps, IStat
}
private onResizeStart = (): void => {
this.props.resizeNotifier.startResizing();
this.context.resizeNotifier.startResizing();
};
private onResize = (): void => {
this.props.resizeNotifier.notifyTimelineHeightChanged();
this.context.resizeNotifier.notifyTimelineHeightChanged();
};
private onResizeStop = (): void => {
this.props.resizeNotifier.stopResizing();
this.context.resizeNotifier.stopResizing();
};
private setSidebarShown = (sidebarShown: boolean): void => {

View File

@@ -24,6 +24,7 @@ import { WidgetLayoutStore } from "../stores/widgets/WidgetLayoutStore";
import { WidgetPermissionStore } from "../stores/widgets/WidgetPermissionStore";
import { OidcClientStore } from "../stores/oidc/OidcClientStore";
import WidgetStore from "../stores/WidgetStore";
import ResizeNotifier from "../utils/ResizeNotifier";
// This context is available to components under MatrixChat,
// the context must not be used by components outside a SdkContextClass tree.
@@ -64,6 +65,7 @@ export class SdkContextClass {
protected _TypingStore?: TypingStore;
protected _UserProfilesStore?: UserProfilesStore;
protected _OidcClientStore?: OidcClientStore;
protected _ResizeNotifier?: ResizeNotifier;
/**
* Automatically construct stores which need to be created eagerly so they can register with
@@ -171,6 +173,16 @@ export class SdkContextClass {
return this._OidcClientStore;
}
// This is getting increasingly tenuous to have here but we still have class components so it's
// awkward to consume multiple contexts in them. This should be replaced with ResizeObservers
// anyway really.
public get resizeNotifier(): ResizeNotifier {
if (!this._ResizeNotifier) {
this._ResizeNotifier = new ResizeNotifier();
}
return this._ResizeNotifier;
}
public onLoggedOut(): void {
this._UserProfilesStore = undefined;
}