Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 35 additions & 30 deletions apps/web/src/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import AsyncWrapper from "./AsyncWrapper";
import { type Defaultize } from "./@types/common";
import { type ActionPayload } from "./dispatcher/payloads";
import { filterBoolean } from "./utils/arrays.ts";
import { SDKContext } from "./contexts/SDKContext.ts";

const DIALOG_CONTAINER_ID = "mx_Dialog_Container";
const STATIC_DIALOG_CONTAINER_ID = "mx_Dialog_StaticContainer";
Expand Down Expand Up @@ -437,21 +438,23 @@ export class ModalManager extends TypedEventEmitter<ModalManagerEvent, HandlerMa

const staticDialog = (
<StrictMode>
{/* Provide I18nContext for shared-components used inside dialogs rendered in a separate root. */}
<I18nContext.Provider value={window.mxModuleApi.i18n}>
<TooltipProvider>
<div className={classes}>
<Glass className="mx_Dialog_border">
<div className="mx_Dialog">{this.staticModal.elem}</div>
</Glass>
<div
data-testid="dialog-background"
className="mx_Dialog_background mx_Dialog_staticBackground"
onClick={this.onBackgroundClick}
/>
</div>
</TooltipProvider>
</I18nContext.Provider>
<SDKContext.Provider value={window.mxSdkContext}>
{/* Provide I18nContext for shared-components used inside dialogs rendered in a separate root. */}
<I18nContext.Provider value={window.mxModuleApi.i18n}>
<TooltipProvider>
<div className={classes}>
<Glass className="mx_Dialog_border">
<div className="mx_Dialog">{this.staticModal.elem}</div>
</Glass>
<div
data-testid="dialog-background"
className="mx_Dialog_background mx_Dialog_staticBackground"
onClick={this.onBackgroundClick}
/>
</div>
</TooltipProvider>
</I18nContext.Provider>
</SDKContext.Provider>
</StrictMode>
);

Expand All @@ -469,21 +472,23 @@ export class ModalManager extends TypedEventEmitter<ModalManagerEvent, HandlerMa

const dialog = (
<StrictMode>
{/* Provide I18nContext for shared-components used inside dialogs rendered in a separate root. */}
<I18nContext.Provider value={window.mxModuleApi.i18n}>
<TooltipProvider>
<div className={classes}>
<Glass className="mx_Dialog_border">
<div className="mx_Dialog">{modal.elem}</div>
</Glass>
<div
data-testid="dialog-background"
className="mx_Dialog_background"
onClick={this.onBackgroundClick}
/>
</div>
</TooltipProvider>
</I18nContext.Provider>
<SDKContext.Provider value={window.mxSdkContext}>
{/* Provide I18nContext for shared-components used inside dialogs rendered in a separate root. */}
<I18nContext.Provider value={window.mxModuleApi.i18n}>
<TooltipProvider>
<div className={classes}>
<Glass className="mx_Dialog_border">
<div className="mx_Dialog">{modal.elem}</div>
</Glass>
<div
data-testid="dialog-background"
className="mx_Dialog_background"
onClick={this.onBackgroundClick}
/>
</div>
</TooltipProvider>
</I18nContext.Provider>
</SDKContext.Provider>
</StrictMode>
);

Expand Down
15 changes: 9 additions & 6 deletions apps/web/src/components/structures/LeftPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
import classNames from "classnames";

import type ResizeNotifier from "../../utils/ResizeNotifier";
import SpaceStore from "../../stores/spaces/SpaceStore";
import { type SpaceKey, UPDATE_SELECTED_SPACE } from "../../stores/spaces";
import { RoomListPanel } from "../views/rooms/RoomListPanel";
import { SDKContext } from "../../contexts/SDKContext.ts";

interface IProps {
isMinimized: boolean;
Expand All @@ -24,20 +24,23 @@
}

export default class LeftPanel extends React.Component<IProps, IState> {
public constructor(props: IProps) {
super(props);
public static contextType = SDKContext;

Check warning on line 27 in apps/web/src/components/structures/LeftPanel.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make this public static property readonly.

See more on https://sonarcloud.io/project/issues?id=element-web&issues=AZ8iSlA9XijY4QmtHTnx&open=AZ8iSlA9XijY4QmtHTnx&pullRequest=34099
declare public context: React.ContextType<typeof SDKContext>;

public constructor(props: IProps, context: React.ContextType<typeof SDKContext>) {
super(props, context);

this.state = {
activeSpace: SpaceStore.instance.activeSpace,
activeSpace: context.spaceStore.activeSpace,
};
}

public componentDidMount(): void {
SpaceStore.instance.on(UPDATE_SELECTED_SPACE, this.updateActiveSpace);
this.context.spaceStore.on(UPDATE_SELECTED_SPACE, this.updateActiveSpace);
}

public componentWillUnmount(): void {
SpaceStore.instance.off(UPDATE_SELECTED_SPACE, this.updateActiveSpace);
this.context.spaceStore.off(UPDATE_SELECTED_SPACE, this.updateActiveSpace);
}

private updateActiveSpace = (activeSpace: SpaceKey): void => {
Expand Down
3 changes: 1 addition & 2 deletions apps/web/src/components/structures/LoggedInView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ import UserView from "./UserView";
import { mediaFromMxc } from "../../customisations/Media";
import { UserTab } from "../views/dialogs/UserTab";
import { type OpenToTabPayload } from "../../dispatcher/payloads/OpenToTabPayload";
import RightPanelStore from "../../stores/right-panel/RightPanelStore";
import { TimelineRenderingType } from "../../contexts/RoomContext";
import { KeyBindingAction } from "../../accessibility/KeyboardShortcuts";
import { type SwitchSpacePayload } from "../../dispatcher/payloads/SwitchSpacePayload";
Expand Down Expand Up @@ -494,7 +493,7 @@ class LoggedInView extends React.Component<IProps, IState> {
break;
case KeyBindingAction.ToggleRoomSidePanel:
if (this.props.page_type === "room_view") {
RightPanelStore.instance.togglePanel(null);
this.context.rightPanelStore.togglePanel(null);
handled = true;
}
break;
Expand Down
9 changes: 4 additions & 5 deletions apps/web/src/components/structures/RoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ import { WaitingForThirdPartyRoomView } from "./WaitingForThirdPartyRoomView";
import { isNotUndefined } from "../../Typeguards";
import { type CancelAskToJoinPayload } from "../../dispatcher/payloads/CancelAskToJoinPayload";
import { type SubmitAskToJoinPayload } from "../../dispatcher/payloads/SubmitAskToJoinPayload";
import RightPanelStore from "../../stores/right-panel/RightPanelStore";
import { onView3pidInvite } from "../../stores/right-panel/action-handlers";
import RoomSearchAuxPanel from "../views/rooms/RoomSearchAuxPanel";
import { PinnedMessageBanner } from "../views/rooms/PinnedMessageBanner";
Expand Down Expand Up @@ -1332,23 +1331,23 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
case Action.ViewUser:
if (payload.member) {
if (payload.push) {
RightPanelStore.instance.pushCard({
this.context.rightPanelStore.pushCard({
phase: RightPanelPhases.MemberInfo,
state: { member: payload.member },
});
} else {
RightPanelStore.instance.setCards([
this.context.rightPanelStore.setCards([
{ phase: RightPanelPhases.RoomSummary },
{ phase: RightPanelPhases.MemberList },
{ phase: RightPanelPhases.MemberInfo, state: { member: payload.member } },
]);
}
} else {
RightPanelStore.instance.showOrHidePhase(RightPanelPhases.MemberList);
this.context.rightPanelStore.showOrHidePhase(RightPanelPhases.MemberList);
}
break;
case Action.View3pidInvite:
onView3pidInvite(payload, RightPanelStore.instance);
onView3pidInvite(payload, this.context.rightPanelStore);
break;
case Action.FocusMessageSearch:
if ((payload as FocusMessageSearchPayload).initialText) {
Expand Down
37 changes: 18 additions & 19 deletions apps/web/src/components/structures/SpaceRoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
VideoCallSolidIcon,
} from "@vector-im/compound-design-tokens/assets/web/icons";

import MatrixClientContext from "../../contexts/MatrixClientContext";
import createRoom, { type IOpts } from "../../createRoom";
import { shouldShowComponent } from "../../customisations/helpers/UIComponents";
import { Action } from "../../dispatcher/actions";
Expand All @@ -37,7 +36,6 @@
import { showRoomInviteDialog } from "../../RoomInvite";
import { UIComponent } from "../../settings/UIFeature";
import { UPDATE_EVENT } from "../../stores/AsyncStore";
import RightPanelStore from "../../stores/right-panel/RightPanelStore";
import { RightPanelPhases } from "../../stores/right-panel/RightPanelStorePhases";
import type ResizeNotifier from "../../utils/ResizeNotifier";
import {
Expand Down Expand Up @@ -77,6 +75,7 @@
import SpacePillButton from "./SpacePillButton.tsx";
import { useRoomName } from "../../hooks/useRoomName.ts";
import MultiInviter from "../../utils/MultiInviter.ts";
import { SDKContext } from "../../contexts/SDKContext.ts";

interface IProps {
space: Room;
Expand Down Expand Up @@ -212,18 +211,18 @@
};

const SpaceLanding: React.FC<{ space: Room }> = ({ space }) => {
const cli = useContext(MatrixClientContext);
const sdkContext = useContext(SDKContext);
const myMembership = useMyRoomMembership(space);
const userId = cli.getSafeUserId();
const userId = sdkContext.client!.getSafeUserId();
const name = useRoomName(space);

const storeIsShowingSpaceMembers = useCallback(
() =>
RightPanelStore.instance.isOpenForRoom(space.roomId) &&
RightPanelStore.instance.currentCardForRoom(space.roomId)?.phase === RightPanelPhases.MemberList,
[space.roomId],
sdkContext.rightPanelStore.isOpenForRoom(space.roomId) &&
sdkContext.rightPanelStore.currentCardForRoom(space.roomId)?.phase === RightPanelPhases.MemberList,
[space.roomId, sdkContext.rightPanelStore],
);
const isShowingMembers = useEventEmitterState(RightPanelStore.instance, UPDATE_EVENT, storeIsShowingSpaceMembers);
const isShowingMembers = useEventEmitterState(sdkContext.rightPanelStore, UPDATE_EVENT, storeIsShowingSpaceMembers);

let inviteButton;
if (shouldShowSpaceInvite(space) && shouldShowComponent(UIComponent.InviteUsers)) {
Expand Down Expand Up @@ -266,7 +265,7 @@
}

const onMembersClick = (): void => {
RightPanelStore.instance.setCard({ phase: RightPanelPhases.MemberList });
sdkContext.rightPanelStore.setCard({ phase: RightPanelPhases.MemberList });
};

return (
Expand Down Expand Up @@ -603,18 +602,18 @@
};

export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
public static contextType = MatrixClientContext;
declare public context: React.ContextType<typeof MatrixClientContext>;
public static contextType = SDKContext;

Check warning on line 605 in apps/web/src/components/structures/SpaceRoomView.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make this public static property readonly.

See more on https://sonarcloud.io/project/issues?id=element-web&issues=AZ8iSlC0XijY4QmtHTny&open=AZ8iSlC0XijY4QmtHTny&pullRequest=34099
declare public context: React.ContextType<typeof SDKContext>;

private dispatcherRef?: string;

public constructor(props: IProps, context: React.ContextType<typeof MatrixClientContext>) {
public constructor(props: IProps, context: React.ContextType<typeof SDKContext>) {
super(props, context);

let phase = Phase.Landing;

const creator = this.props.space.currentState.getStateEvents(EventType.RoomCreate, "")?.getSender();
const showSetup = this.props.justCreatedOpts && context.getSafeUserId() === creator;
const showSetup = this.props.justCreatedOpts && this.context.client?.getSafeUserId() === creator;

if (showSetup) {
phase =
Expand All @@ -625,21 +624,21 @@

this.state = {
phase,
showRightPanel: RightPanelStore.instance.isOpenForRoom(this.props.space.roomId),
showRightPanel: this.context.rightPanelStore.isOpenForRoom(this.props.space.roomId),
myMembership: this.props.space.getMyMembership(),
};
}

public componentDidMount(): void {
this.dispatcherRef = defaultDispatcher.register(this.onAction);
RightPanelStore.instance.on(UPDATE_EVENT, this.onRightPanelStoreUpdate);
this.context.on(RoomEvent.MyMembership, this.onMyMembership);
this.context.rightPanelStore.on(UPDATE_EVENT, this.onRightPanelStoreUpdate);
this.context.client?.on(RoomEvent.MyMembership, this.onMyMembership);
}

public componentWillUnmount(): void {
defaultDispatcher.unregister(this.dispatcherRef);
RightPanelStore.instance.off(UPDATE_EVENT, this.onRightPanelStoreUpdate);
this.context.off(RoomEvent.MyMembership, this.onMyMembership);
this.context.rightPanelStore.off(UPDATE_EVENT, this.onRightPanelStoreUpdate);
this.context.client?.off(RoomEvent.MyMembership, this.onMyMembership);
}

private onMyMembership = (room: Room, myMembership: string): void => {
Expand All @@ -650,7 +649,7 @@

private onRightPanelStoreUpdate = (): void => {
this.setState({
showRightPanel: RightPanelStore.instance.isOpenForRoom(this.props.space.roomId),
showRightPanel: this.context.rightPanelStore.isOpenForRoom(this.props.space.roomId),
});
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import { type MatrixClient, type RoomMember, type User } from "matrix-js-sdk/src
import { useContext } from "react";
import { type UserVerificationStatus } from "matrix-js-sdk/src/crypto-api";

import MatrixClientContext from "../../../../contexts/MatrixClientContext";
import { type IDevice } from "../../../views/right_panel/UserInfo";
import { useAsyncMemo } from "../../../../hooks/useAsyncMemo";
import { verifyUser } from "../../../../verification";
import { SDKContext } from "../../../../contexts/SDKContext.ts";

export interface UserInfoVerificationSectionState {
/**
Expand Down Expand Up @@ -44,21 +44,22 @@ export const useUserInfoVerificationViewModel = (
member: User | RoomMember,
devices: IDevice[],
): UserInfoVerificationSectionState => {
const cli = useContext(MatrixClientContext);
const sdkContext = useContext(SDKContext);

const userTrust = useAsyncMemo<UserVerificationStatus | undefined>(
async () => cli.getCrypto()?.getUserVerificationStatus(member.userId),
async () => sdkContext.client?.getCrypto()?.getUserVerificationStatus(member.userId),
[member.userId],
// the user verification status is not initialized
undefined,
);
const hasUserVerificationStatus = Boolean(userTrust);
const isUserVerified = Boolean(userTrust?.isVerified());
const isMe = member.userId === cli.getUserId();
const isMe = member.userId === sdkContext.client!.getUserId();
const canVerify = hasUserVerificationStatus && !isUserVerified && !isMe && devices && devices.length > 0;

const hasCrossSigningKeys = useHasCrossSigningKeys(cli, member as User, canVerify);
const verifySelectedUser = (): Promise<void> => verifyUser(cli, member as User);
const hasCrossSigningKeys = useHasCrossSigningKeys(sdkContext.client!, member as User, canVerify);
const verifySelectedUser = (): Promise<void> =>
verifyUser(sdkContext.rightPanelStore, sdkContext.client!, member as User);

return {
canVerify,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/

import React, { useCallback, useEffect } from "react";
import React, { useCallback, useContext, useEffect } from "react";
import { type MatrixEvent } from "matrix-js-sdk/src/matrix";
import { LinkIcon, OverflowHorizontalIcon, VisibilityOnIcon } from "@vector-im/compound-design-tokens/assets/web/icons";

Expand All @@ -18,9 +18,8 @@ import { copyPlaintext } from "../../../utils/strings";
import { ChevronFace, ContextMenuTooltipButton, type MenuProps, useContextMenu } from "../../structures/ContextMenu";
import { _t } from "../../../languageHandler";
import IconizedContextMenu, { IconizedContextMenuOption, IconizedContextMenuOptionList } from "./IconizedContextMenu";
import { WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import { type ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
import { SDKContext } from "../../../contexts/SDKContext.ts";

export interface ThreadListContextMenuProps {
mxEvent: MatrixEvent;
Expand All @@ -42,6 +41,7 @@ const ThreadListContextMenu: React.FC<ThreadListContextMenuProps> = ({
onMenuToggle,
...props
}) => {
const sdkContext = useContext(SDKContext);
const [menuDisplayed, button, openMenu, closeThreadOptions] = useContextMenu();

const viewInRoom = useCallback(
Expand Down Expand Up @@ -77,8 +77,8 @@ const ThreadListContextMenu: React.FC<ThreadListContextMenuProps> = ({
onMenuToggle?.(menuDisplayed);
}, [menuDisplayed, onMenuToggle]);

const room = MatrixClientPeg.safeGet().getRoom(mxEvent.getRoomId());
const isMainSplitTimelineShown = !!room && !WidgetLayoutStore.instance.hasMaximisedWidget(room);
const room = sdkContext.client?.getRoom(mxEvent.getRoomId());
const isMainSplitTimelineShown = !!room && !sdkContext.widgetLayoutStore.hasMaximisedWidget(room);
return (
<React.Fragment>
<ContextMenuTooltipButton
Expand Down
Loading
Loading