Allow adding extra icons to the room header (#11799)
* Allow adding extra icons to the room header Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> --------- Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net>
This commit is contained in:
parent
9496097143
commit
01e7e01153
14 changed files with 210 additions and 7 deletions
|
@ -42,6 +42,7 @@ import { logger } from "matrix-js-sdk/src/logger";
|
|||
import { CallState, MatrixCall } from "matrix-js-sdk/src/webrtc/call";
|
||||
import { throttle } from "lodash";
|
||||
import { CryptoEvent } from "matrix-js-sdk/src/crypto";
|
||||
import { ViewRoomOpts } from "@matrix-org/react-sdk-module-api/lib/lifecycles/RoomViewLifecycle";
|
||||
|
||||
import shouldHideEvent from "../../shouldHideEvent";
|
||||
import { _t } from "../../languageHandler";
|
||||
|
@ -246,6 +247,8 @@ export interface IRoomState {
|
|||
|
||||
canAskToJoin: boolean;
|
||||
promptAskToJoin: boolean;
|
||||
|
||||
viewRoomOpts: ViewRoomOpts;
|
||||
}
|
||||
|
||||
interface LocalRoomViewProps {
|
||||
|
@ -458,6 +461,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
msc3946ProcessDynamicPredecessor: SettingsStore.getValue("feature_dynamic_room_predecessors"),
|
||||
canAskToJoin: this.askToJoinEnabled,
|
||||
promptAskToJoin: false,
|
||||
viewRoomOpts: { buttons: [] },
|
||||
};
|
||||
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
|
@ -663,6 +667,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
: false,
|
||||
activeCall: roomId ? CallStore.instance.getActiveCall(roomId) : null,
|
||||
promptAskToJoin: this.context.roomViewStore.promptAskToJoin(),
|
||||
viewRoomOpts: this.context.roomViewStore.getViewRoomOpts(),
|
||||
};
|
||||
|
||||
if (
|
||||
|
@ -1407,6 +1412,8 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
tombstone: this.getRoomTombstone(room),
|
||||
liveTimeline: room.getLiveTimeline(),
|
||||
});
|
||||
|
||||
dis.dispatch<ActionPayload>({ action: Action.RoomLoaded });
|
||||
};
|
||||
|
||||
private onRoomTimelineReset = (room?: Room): void => {
|
||||
|
@ -2601,7 +2608,10 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
data-layout={this.state.layout}
|
||||
>
|
||||
{SettingsStore.getValue("feature_new_room_decoration_ui") ? (
|
||||
<RoomHeader room={this.state.room} />
|
||||
<RoomHeader
|
||||
room={this.state.room}
|
||||
additionalButtons={this.state.viewRoomOpts.buttons}
|
||||
/>
|
||||
) : (
|
||||
<LegacyRoomHeader
|
||||
room={this.state.room}
|
||||
|
@ -2619,6 +2629,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
enableRoomOptionsMenu={!this.viewsLocalRoom}
|
||||
viewingCall={viewingCall}
|
||||
activeCall={this.state.activeCall}
|
||||
additionalButtons={this.state.viewRoomOpts.buttons}
|
||||
/>
|
||||
)}
|
||||
{mainSplitBody}
|
||||
|
|
|
@ -20,6 +20,8 @@ import classNames from "classnames";
|
|||
import { throttle } from "lodash";
|
||||
import { RoomStateEvent, ISearchResults } from "matrix-js-sdk/src/matrix";
|
||||
import { CallType } from "matrix-js-sdk/src/webrtc/call";
|
||||
import { IconButton, Tooltip } from "@vector-im/compound-web";
|
||||
import { ViewRoomOpts } from "@matrix-org/react-sdk-module-api/lib/lifecycles/RoomViewLifecycle";
|
||||
|
||||
import type { MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
|
||||
import { _t } from "../../../languageHandler";
|
||||
|
@ -476,6 +478,7 @@ export interface IProps {
|
|||
enableRoomOptionsMenu?: boolean;
|
||||
viewingCall: boolean;
|
||||
activeCall: Call | null;
|
||||
additionalButtons?: ViewRoomOpts["buttons"];
|
||||
}
|
||||
|
||||
interface IState {
|
||||
|
@ -669,6 +672,23 @@ export default class RoomHeader extends React.Component<IProps, IState> {
|
|||
|
||||
return (
|
||||
<>
|
||||
{this.props.additionalButtons?.map((props) => {
|
||||
const label = props.label();
|
||||
|
||||
return (
|
||||
<Tooltip label={label} key={props.id}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
props.onClick();
|
||||
this.forceUpdate();
|
||||
}}
|
||||
title={label}
|
||||
>
|
||||
{props.icon}
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
);
|
||||
})}
|
||||
{startButtons}
|
||||
<RoomHeaderButtons
|
||||
room={this.props.room}
|
||||
|
|
|
@ -24,6 +24,7 @@ import { Icon as VerifiedIcon } from "@vector-im/compound-design-tokens/icons/ve
|
|||
import { Icon as ErrorIcon } from "@vector-im/compound-design-tokens/icons/error.svg";
|
||||
import { Icon as PublicIcon } from "@vector-im/compound-design-tokens/icons/public.svg";
|
||||
import { EventType, JoinRule, type Room } from "matrix-js-sdk/src/matrix";
|
||||
import { ViewRoomOpts } from "@matrix-org/react-sdk-module-api/lib/lifecycles/RoomViewLifecycle";
|
||||
|
||||
import { useRoomName } from "../../../hooks/useRoomName";
|
||||
import { RightPanelPhases } from "../../../stores/right-panel/RightPanelStorePhases";
|
||||
|
@ -63,7 +64,13 @@ function notificationColorToIndicator(color: NotificationColor): React.Component
|
|||
}
|
||||
}
|
||||
|
||||
export default function RoomHeader({ room }: { room: Room }): JSX.Element {
|
||||
export default function RoomHeader({
|
||||
room,
|
||||
additionalButtons,
|
||||
}: {
|
||||
room: Room;
|
||||
additionalButtons?: ViewRoomOpts["buttons"];
|
||||
}): JSX.Element {
|
||||
const client = useMatrixClientContext();
|
||||
|
||||
const roomName = useRoomName(room);
|
||||
|
@ -169,6 +176,23 @@ export default function RoomHeader({ room }: { room: Room }): JSX.Element {
|
|||
)}
|
||||
</Box>
|
||||
<Flex as="nav" align="center" gap="var(--cpd-space-2x)">
|
||||
{additionalButtons?.map((props) => {
|
||||
const label = props.label();
|
||||
|
||||
return (
|
||||
<Tooltip label={label} key={props.id}>
|
||||
<IconButton
|
||||
aria-label={label}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
props.onClick();
|
||||
}}
|
||||
>
|
||||
{props.icon}
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
);
|
||||
})}
|
||||
{!useElementCallExclusively && (
|
||||
<Tooltip label={!voiceCallDisabledReason ? _t("voip|voice_call") : voiceCallDisabledReason!}>
|
||||
<IconButton
|
||||
|
|
|
@ -73,6 +73,7 @@ const RoomContext = createContext<
|
|||
msc3946ProcessDynamicPredecessor: false,
|
||||
canAskToJoin: false,
|
||||
promptAskToJoin: false,
|
||||
viewRoomOpts: { buttons: [] },
|
||||
});
|
||||
RoomContext.displayName = "RoomContext";
|
||||
export default RoomContext;
|
||||
|
|
|
@ -371,4 +371,9 @@ export enum Action {
|
|||
* Fired when we want to open spotlight search. Use with a OpenSpotlightPayload.
|
||||
*/
|
||||
OpenSpotlight = "open_spotlight",
|
||||
|
||||
/**
|
||||
* Fired when the room loaded.
|
||||
*/
|
||||
RoomLoaded = "room_loaded",
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import { ViewRoom as ViewRoomEvent } from "@matrix-org/analytics-events/types/ty
|
|||
import { JoinedRoom as JoinedRoomEvent } from "@matrix-org/analytics-events/types/typescript/JoinedRoom";
|
||||
import { Optional } from "matrix-events-sdk";
|
||||
import EventEmitter from "events";
|
||||
import { RoomViewLifecycle, ViewRoomOpts } from "@matrix-org/react-sdk-module-api/lib/lifecycles/RoomViewLifecycle";
|
||||
|
||||
import { MatrixDispatcher } from "../dispatcher/dispatcher";
|
||||
import { MatrixClientPeg } from "../MatrixClientPeg";
|
||||
|
@ -60,6 +61,7 @@ import { pauseNonLiveBroadcastFromOtherRoom } from "../voice-broadcast/utils/pau
|
|||
import { ActionPayload } from "../dispatcher/payloads";
|
||||
import { CancelAskToJoinPayload } from "../dispatcher/payloads/CancelAskToJoinPayload";
|
||||
import { SubmitAskToJoinPayload } from "../dispatcher/payloads/SubmitAskToJoinPayload";
|
||||
import { ModuleRunner } from "../modules/ModuleRunner";
|
||||
|
||||
const NUM_JOIN_RETRY = 5;
|
||||
|
||||
|
@ -119,6 +121,8 @@ interface State {
|
|||
viewingCall: boolean;
|
||||
|
||||
promptAskToJoin: boolean;
|
||||
|
||||
viewRoomOpts: ViewRoomOpts;
|
||||
}
|
||||
|
||||
const INITIAL_STATE: State = {
|
||||
|
@ -140,6 +144,7 @@ const INITIAL_STATE: State = {
|
|||
wasContextSwitch: false,
|
||||
viewingCall: false,
|
||||
promptAskToJoin: false,
|
||||
viewRoomOpts: { buttons: [] },
|
||||
};
|
||||
|
||||
type Listener = (isActive: boolean) => void;
|
||||
|
@ -370,6 +375,10 @@ export class RoomViewStore extends EventEmitter {
|
|||
this.cancelAskToJoin(payload as CancelAskToJoinPayload);
|
||||
break;
|
||||
}
|
||||
case Action.RoomLoaded: {
|
||||
this.setViewRoomOpts();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -805,4 +814,24 @@ export class RoomViewStore extends EventEmitter {
|
|||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current state of the 'viewRoomOpts' property.
|
||||
*
|
||||
* @returns {ViewRoomOpts} The value of the 'viewRoomOpts' property.
|
||||
*/
|
||||
public getViewRoomOpts(): ViewRoomOpts {
|
||||
return this.state.viewRoomOpts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the view room lifecycle to set the view room options.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
private setViewRoomOpts(): void {
|
||||
const viewRoomOpts: ViewRoomOpts = { buttons: [] };
|
||||
ModuleRunner.instance.invoke(RoomViewLifecycle.ViewRoom, viewRoomOpts, this.getRoomId());
|
||||
this.setState({ viewRoomOpts });
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue