mirror of
https://github.com/element-hq/element-web
synced 2024-11-24 02:05:45 +03:00
Merge pull request #5168 from matrix-org/t3chguy/dpsah/6785.2
Small code clean ups and tweaks
This commit is contained in:
commit
a713c9763b
11 changed files with 76 additions and 53 deletions
2
src/@types/global.d.ts
vendored
2
src/@types/global.d.ts
vendored
|
@ -28,6 +28,7 @@ import SettingsStore from "../settings/SettingsStore";
|
||||||
import {ActiveRoomObserver} from "../ActiveRoomObserver";
|
import {ActiveRoomObserver} from "../ActiveRoomObserver";
|
||||||
import {Notifier} from "../Notifier";
|
import {Notifier} from "../Notifier";
|
||||||
import type {Renderer} from "react-dom";
|
import type {Renderer} from "react-dom";
|
||||||
|
import RightPanelStore from "../stores/RightPanelStore";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
@ -49,6 +50,7 @@ declare global {
|
||||||
singletonModalManager: ModalManager;
|
singletonModalManager: ModalManager;
|
||||||
mxSettingsStore: SettingsStore;
|
mxSettingsStore: SettingsStore;
|
||||||
mxNotifier: typeof Notifier;
|
mxNotifier: typeof Notifier;
|
||||||
|
mxRightPanelStore: RightPanelStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Document {
|
interface Document {
|
||||||
|
|
|
@ -21,6 +21,8 @@ limitations under the License.
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import {Room} from "matrix-js-sdk/src/models/room";
|
||||||
|
|
||||||
import * as sdk from '../../index';
|
import * as sdk from '../../index';
|
||||||
import dis from '../../dispatcher/dispatcher';
|
import dis from '../../dispatcher/dispatcher';
|
||||||
import RateLimitedFunc from '../../ratelimitedfunc';
|
import RateLimitedFunc from '../../ratelimitedfunc';
|
||||||
|
@ -34,7 +36,7 @@ import {Action} from "../../dispatcher/actions";
|
||||||
export default class RightPanel extends React.Component {
|
export default class RightPanel extends React.Component {
|
||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
roomId: PropTypes.string, // if showing panels for a given room, this is set
|
room: PropTypes.instanceOf(Room), // if showing panels for a given room, this is set
|
||||||
groupId: PropTypes.string, // if showing panels for a given group, this is set
|
groupId: PropTypes.string, // if showing panels for a given group, this is set
|
||||||
user: PropTypes.object, // used if we know the user ahead of opening the panel
|
user: PropTypes.object, // used if we know the user ahead of opening the panel
|
||||||
};
|
};
|
||||||
|
@ -161,13 +163,13 @@ export default class RightPanel extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
onRoomStateMember(ev, state, member) {
|
onRoomStateMember(ev, state, member) {
|
||||||
if (member.roomId !== this.props.roomId) {
|
if (member.roomId !== this.props.room.roomId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// redraw the badge on the membership list
|
// redraw the badge on the membership list
|
||||||
if (this.state.phase === RightPanelPhases.RoomMemberList && member.roomId === this.props.roomId) {
|
if (this.state.phase === RightPanelPhases.RoomMemberList && member.roomId === this.props.room.roomId) {
|
||||||
this._delayedUpdate();
|
this._delayedUpdate();
|
||||||
} else if (this.state.phase === RightPanelPhases.RoomMemberInfo && member.roomId === this.props.roomId &&
|
} else if (this.state.phase === RightPanelPhases.RoomMemberInfo && member.roomId === this.props.room.roomId &&
|
||||||
member.userId === this.state.member.userId) {
|
member.userId === this.state.member.userId) {
|
||||||
// refresh the member info (e.g. new power level)
|
// refresh the member info (e.g. new power level)
|
||||||
this._delayedUpdate();
|
this._delayedUpdate();
|
||||||
|
@ -226,8 +228,8 @@ export default class RightPanel extends React.Component {
|
||||||
|
|
||||||
switch (this.state.phase) {
|
switch (this.state.phase) {
|
||||||
case RightPanelPhases.RoomMemberList:
|
case RightPanelPhases.RoomMemberList:
|
||||||
if (this.props.roomId) {
|
if (this.props.room.roomId) {
|
||||||
panel = <MemberList roomId={this.props.roomId} key={this.props.roomId} />;
|
panel = <MemberList roomId={this.props.room.roomId} key={this.props.room.roomId} />;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RightPanelPhases.GroupMemberList:
|
case RightPanelPhases.GroupMemberList:
|
||||||
|
@ -242,8 +244,8 @@ export default class RightPanel extends React.Component {
|
||||||
case RightPanelPhases.EncryptionPanel:
|
case RightPanelPhases.EncryptionPanel:
|
||||||
panel = <UserInfo
|
panel = <UserInfo
|
||||||
user={this.state.member}
|
user={this.state.member}
|
||||||
roomId={this.props.roomId}
|
roomId={this.props.room.roomId}
|
||||||
key={this.props.roomId || this.state.member.userId}
|
key={this.props.room.roomId || this.state.member.userId}
|
||||||
onClose={this.onCloseUserInfo}
|
onClose={this.onCloseUserInfo}
|
||||||
phase={this.state.phase}
|
phase={this.state.phase}
|
||||||
verificationRequest={this.state.verificationRequest}
|
verificationRequest={this.state.verificationRequest}
|
||||||
|
@ -251,7 +253,7 @@ export default class RightPanel extends React.Component {
|
||||||
/>;
|
/>;
|
||||||
break;
|
break;
|
||||||
case RightPanelPhases.Room3pidMemberInfo:
|
case RightPanelPhases.Room3pidMemberInfo:
|
||||||
panel = <ThirdPartyMemberInfo event={this.state.event} key={this.props.roomId} />;
|
panel = <ThirdPartyMemberInfo event={this.state.event} key={this.props.room.roomId} />;
|
||||||
break;
|
break;
|
||||||
case RightPanelPhases.GroupMemberInfo:
|
case RightPanelPhases.GroupMemberInfo:
|
||||||
panel = <UserInfo
|
panel = <UserInfo
|
||||||
|
@ -270,7 +272,7 @@ export default class RightPanel extends React.Component {
|
||||||
panel = <NotificationPanel />;
|
panel = <NotificationPanel />;
|
||||||
break;
|
break;
|
||||||
case RightPanelPhases.FilePanel:
|
case RightPanelPhases.FilePanel:
|
||||||
panel = <FilePanel roomId={this.props.roomId} resizeNotifier={this.props.resizeNotifier} />;
|
panel = <FilePanel roomId={this.props.room.roomId} resizeNotifier={this.props.resizeNotifier} />;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2062,7 +2062,7 @@ export default class RoomView extends React.Component {
|
||||||
|
|
||||||
const showRightPanel = !forceHideRightPanel && this.state.room && this.state.showRightPanel;
|
const showRightPanel = !forceHideRightPanel && this.state.room && this.state.showRightPanel;
|
||||||
const rightPanel = showRightPanel
|
const rightPanel = showRightPanel
|
||||||
? <RightPanel roomId={this.state.room.roomId} resizeNotifier={this.props.resizeNotifier} />
|
? <RightPanel room={this.state.room} resizeNotifier={this.props.resizeNotifier} />
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const timelineClasses = classNames("mx_RoomView_timeline", {
|
const timelineClasses = classNames("mx_RoomView_timeline", {
|
||||||
|
|
|
@ -94,7 +94,7 @@ export default class ScrollPanel extends React.Component {
|
||||||
|
|
||||||
/* startAtBottom: if set to true, the view is assumed to start
|
/* startAtBottom: if set to true, the view is assumed to start
|
||||||
* scrolled to the bottom.
|
* scrolled to the bottom.
|
||||||
* XXX: It's likley this is unecessary and can be derived from
|
* XXX: It's likely this is unnecessary and can be derived from
|
||||||
* stickyBottom, but I'm adding an extra parameter to ensure
|
* stickyBottom, but I'm adding an extra parameter to ensure
|
||||||
* behaviour stays the same for other uses of ScrollPanel.
|
* behaviour stays the same for other uses of ScrollPanel.
|
||||||
* If so, let's remove this parameter down the line.
|
* If so, let's remove this parameter down the line.
|
||||||
|
@ -138,6 +138,7 @@ export default class ScrollPanel extends React.Component {
|
||||||
/* style: styles to add to the top-level div
|
/* style: styles to add to the top-level div
|
||||||
*/
|
*/
|
||||||
style: PropTypes.object,
|
style: PropTypes.object,
|
||||||
|
|
||||||
/* resizeNotifier: ResizeNotifier to know when middle column has changed size
|
/* resizeNotifier: ResizeNotifier to know when middle column has changed size
|
||||||
*/
|
*/
|
||||||
resizeNotifier: PropTypes.object,
|
resizeNotifier: PropTypes.object,
|
||||||
|
|
|
@ -16,23 +16,24 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import {RoomMember} from "matrix-js-sdk/src/models/room-member";
|
||||||
|
|
||||||
import dis from "../../../dispatcher/dispatcher";
|
import dis from "../../../dispatcher/dispatcher";
|
||||||
import {Action} from "../../../dispatcher/actions";
|
import {Action} from "../../../dispatcher/actions";
|
||||||
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
||||||
import BaseAvatar from "./BaseAvatar";
|
import BaseAvatar from "./BaseAvatar";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
// TODO: replace with correct type
|
member: RoomMember;
|
||||||
member: any;
|
fallbackUserId?: string;
|
||||||
fallbackUserId: string;
|
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
resizeMethod: string;
|
resizeMethod?: string;
|
||||||
// The onClick to give the avatar
|
// The onClick to give the avatar
|
||||||
onClick: React.MouseEventHandler;
|
onClick?: React.MouseEventHandler;
|
||||||
// Whether the onClick of the avatar should be overriden to dispatch `Action.ViewUser`
|
// Whether the onClick of the avatar should be overriden to dispatch `Action.ViewUser`
|
||||||
viewUserOnClick: boolean;
|
viewUserOnClick?: boolean;
|
||||||
title: string;
|
title?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
|
|
|
@ -41,13 +41,9 @@ interface IProps {}
|
||||||
export default class GroupHeaderButtons extends HeaderButtons {
|
export default class GroupHeaderButtons extends HeaderButtons {
|
||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
super(props, HeaderKind.Group);
|
super(props, HeaderKind.Group);
|
||||||
this.onMembersClicked = this.onMembersClicked.bind(this);
|
|
||||||
this.onRoomsClicked = this.onRoomsClicked.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onAction(payload: ActionPayload) {
|
protected onAction(payload: ActionPayload) {
|
||||||
super.onAction(payload);
|
|
||||||
|
|
||||||
if (payload.action === Action.ViewUser) {
|
if (payload.action === Action.ViewUser) {
|
||||||
if ((payload as ViewUserPayload).member) {
|
if ((payload as ViewUserPayload).member) {
|
||||||
this.setPhase(RightPanelPhases.RoomMemberInfo, {member: payload.member});
|
this.setPhase(RightPanelPhases.RoomMemberInfo, {member: payload.member});
|
||||||
|
@ -70,7 +66,7 @@ export default class GroupHeaderButtons extends HeaderButtons {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onMembersClicked() {
|
private onMembersClicked = () => {
|
||||||
if (this.state.phase === RightPanelPhases.GroupMemberInfo) {
|
if (this.state.phase === RightPanelPhases.GroupMemberInfo) {
|
||||||
// send the active phase to trigger a toggle
|
// send the active phase to trigger a toggle
|
||||||
this.setPhase(RightPanelPhases.GroupMemberInfo);
|
this.setPhase(RightPanelPhases.GroupMemberInfo);
|
||||||
|
@ -78,12 +74,12 @@ export default class GroupHeaderButtons extends HeaderButtons {
|
||||||
// This toggles for us, if needed
|
// This toggles for us, if needed
|
||||||
this.setPhase(RightPanelPhases.GroupMemberList);
|
this.setPhase(RightPanelPhases.GroupMemberList);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
private onRoomsClicked() {
|
private onRoomsClicked = () => {
|
||||||
// This toggles for us, if needed
|
// This toggles for us, if needed
|
||||||
this.setPhase(RightPanelPhases.GroupRoomList);
|
this.setPhase(RightPanelPhases.GroupRoomList);
|
||||||
}
|
};
|
||||||
|
|
||||||
renderButtons() {
|
renderButtons() {
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -65,9 +65,7 @@ export default abstract class HeaderButtons extends React.Component<IProps, ISta
|
||||||
if (this.dispatcherRef) dis.unregister(this.dispatcherRef);
|
if (this.dispatcherRef) dis.unregister(this.dispatcherRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onAction(payload) {
|
protected abstract onAction(payload);
|
||||||
// Ignore - intended to be overridden by subclasses
|
|
||||||
}
|
|
||||||
|
|
||||||
public setPhase(phase: RightPanelPhases, extras?: Partial<SetRightPanelPhaseRefireParams>) {
|
public setPhase(phase: RightPanelPhases, extras?: Partial<SetRightPanelPhaseRefireParams>) {
|
||||||
dis.dispatch<SetRightPanelPhasePayload>({
|
dis.dispatch<SetRightPanelPhasePayload>({
|
||||||
|
|
|
@ -36,13 +36,9 @@ const MEMBER_PHASES = [
|
||||||
export default class RoomHeaderButtons extends HeaderButtons {
|
export default class RoomHeaderButtons extends HeaderButtons {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props, HeaderKind.Room);
|
super(props, HeaderKind.Room);
|
||||||
this.onMembersClicked = this.onMembersClicked.bind(this);
|
|
||||||
this.onFilesClicked = this.onFilesClicked.bind(this);
|
|
||||||
this.onNotificationsClicked = this.onNotificationsClicked.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onAction(payload: ActionPayload) {
|
protected onAction(payload: ActionPayload) {
|
||||||
super.onAction(payload);
|
|
||||||
if (payload.action === Action.ViewUser) {
|
if (payload.action === Action.ViewUser) {
|
||||||
if (payload.member) {
|
if (payload.member) {
|
||||||
this.setPhase(RightPanelPhases.RoomMemberInfo, {member: payload.member});
|
this.setPhase(RightPanelPhases.RoomMemberInfo, {member: payload.member});
|
||||||
|
@ -58,7 +54,7 @@ export default class RoomHeaderButtons extends HeaderButtons {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onMembersClicked() {
|
private onMembersClicked = () => {
|
||||||
if (this.state.phase === RightPanelPhases.RoomMemberInfo) {
|
if (this.state.phase === RightPanelPhases.RoomMemberInfo) {
|
||||||
// send the active phase to trigger a toggle
|
// send the active phase to trigger a toggle
|
||||||
// XXX: we should pass refireParams here but then it won't collapse as we desire it to
|
// XXX: we should pass refireParams here but then it won't collapse as we desire it to
|
||||||
|
@ -67,17 +63,17 @@ export default class RoomHeaderButtons extends HeaderButtons {
|
||||||
// This toggles for us, if needed
|
// This toggles for us, if needed
|
||||||
this.setPhase(RightPanelPhases.RoomMemberList);
|
this.setPhase(RightPanelPhases.RoomMemberList);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
private onFilesClicked() {
|
private onFilesClicked = () => {
|
||||||
// This toggles for us, if needed
|
// This toggles for us, if needed
|
||||||
this.setPhase(RightPanelPhases.FilePanel);
|
this.setPhase(RightPanelPhases.FilePanel);
|
||||||
}
|
};
|
||||||
|
|
||||||
private onNotificationsClicked() {
|
private onNotificationsClicked = () => {
|
||||||
// This toggles for us, if needed
|
// This toggles for us, if needed
|
||||||
this.setPhase(RightPanelPhases.NotificationPanel);
|
this.setPhase(RightPanelPhases.NotificationPanel);
|
||||||
}
|
};
|
||||||
|
|
||||||
public renderButtons() {
|
public renderButtons() {
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -45,6 +45,7 @@ import EncryptionPanel from "./EncryptionPanel";
|
||||||
import { useAsyncMemo } from '../../../hooks/useAsyncMemo';
|
import { useAsyncMemo } from '../../../hooks/useAsyncMemo';
|
||||||
import { verifyUser, legacyVerifyUser, verifyDevice } from '../../../verification';
|
import { verifyUser, legacyVerifyUser, verifyDevice } from '../../../verification';
|
||||||
import {Action} from "../../../dispatcher/actions";
|
import {Action} from "../../../dispatcher/actions";
|
||||||
|
import {useIsEncrypted} from "../../../hooks/useIsEncrypted";
|
||||||
|
|
||||||
const _disambiguateDevices = (devices) => {
|
const _disambiguateDevices = (devices) => {
|
||||||
const names = Object.create(null);
|
const names = Object.create(null);
|
||||||
|
@ -124,18 +125,6 @@ async function openDMForUser(matrixClient, userId) {
|
||||||
createRoom(createRoomOptions);
|
createRoom(createRoomOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
function useIsEncrypted(cli, room) {
|
|
||||||
const [isEncrypted, setIsEncrypted] = useState(room ? cli.isRoomEncrypted(room.roomId) : undefined);
|
|
||||||
|
|
||||||
const update = useCallback((event) => {
|
|
||||||
if (event.getType() === "m.room.encryption") {
|
|
||||||
setIsEncrypted(cli.isRoomEncrypted(room.roomId));
|
|
||||||
}
|
|
||||||
}, [cli, room]);
|
|
||||||
useEventEmitter(room ? room.currentState : undefined, "RoomState.events", update);
|
|
||||||
return isEncrypted;
|
|
||||||
}
|
|
||||||
|
|
||||||
function useHasCrossSigningKeys(cli, member, canVerify, setUpdating) {
|
function useHasCrossSigningKeys(cli, member, canVerify, setUpdating) {
|
||||||
return useAsyncMemo(async () => {
|
return useAsyncMemo(async () => {
|
||||||
if (!canVerify) {
|
if (!canVerify) {
|
||||||
|
@ -1485,7 +1474,7 @@ const UserInfoHeader = ({onClose, member, e2eStatus}) => {
|
||||||
const UserInfo = ({user, groupId, roomId, onClose, phase=RightPanelPhases.RoomMemberInfo, ...props}) => {
|
const UserInfo = ({user, groupId, roomId, onClose, phase=RightPanelPhases.RoomMemberInfo, ...props}) => {
|
||||||
const cli = useContext(MatrixClientContext);
|
const cli = useContext(MatrixClientContext);
|
||||||
|
|
||||||
// Load room if we are given a room id and memoize it
|
// Load room if we are given a room id and memoize it - this can be undefined for User Info/Group Member Info
|
||||||
const room = useMemo(() => roomId ? cli.getRoom(roomId) : null, [cli, roomId]);
|
const room = useMemo(() => roomId ? cli.getRoom(roomId) : null, [cli, roomId]);
|
||||||
// fetch latest room member if we have a room, so we don't show historical information, falling back to user
|
// fetch latest room member if we have a room, so we don't show historical information, falling back to user
|
||||||
const member = useMemo(() => room ? (room.getMember(user.userId) || user) : user, [room, user]);
|
const member = useMemo(() => room ? (room.getMember(user.userId) || user) : user, [room, user]);
|
||||||
|
|
36
src/hooks/useIsEncrypted.ts
Normal file
36
src/hooks/useIsEncrypted.ts
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {useCallback, useState} from "react";
|
||||||
|
import {MatrixClient} from "matrix-js-sdk/src/client";
|
||||||
|
import {MatrixEvent} from "matrix-js-sdk/src/models/event";
|
||||||
|
import {Room} from "matrix-js-sdk/src/models/room";
|
||||||
|
|
||||||
|
import {useEventEmitter} from "./useEventEmitter";
|
||||||
|
|
||||||
|
// Hook to simplify watching whether a Matrix room is encrypted, returns undefined if room is undefined
|
||||||
|
export function useIsEncrypted(cli: MatrixClient, room?: Room): boolean | undefined {
|
||||||
|
const [isEncrypted, setIsEncrypted] = useState(room ? cli.isRoomEncrypted(room.roomId) : undefined);
|
||||||
|
|
||||||
|
const update = useCallback((event: MatrixEvent) => {
|
||||||
|
if (room && event.getType() === "m.room.encryption") {
|
||||||
|
setIsEncrypted(cli.isRoomEncrypted(room.roomId));
|
||||||
|
}
|
||||||
|
}, [cli, room]);
|
||||||
|
useEventEmitter(room ? room.currentState : undefined, "RoomState.events", update);
|
||||||
|
|
||||||
|
return isEncrypted;
|
||||||
|
}
|
|
@ -223,3 +223,5 @@ export default class RightPanelStore extends Store<ActionPayload> {
|
||||||
return RightPanelStore.instance;
|
return RightPanelStore.instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.mxRightPanelStore = RightPanelStore.getSharedInstance();
|
||||||
|
|
Loading…
Reference in a new issue