mirror of https://github.com/vector-im/riot-web
Merge pull request #3465 from matrix-org/t3chguy/nvl/userinfo
UserInfo consolidation of GroupMemberInfo and MemberInfo panelspull/21833/head
commit
c5d5cd72bc
|
@ -12,6 +12,7 @@ module.exports = {
|
|||
extends: [matrixJsSdkPath + "/.eslintrc.js"],
|
||||
plugins: [
|
||||
"react",
|
||||
"react-hooks",
|
||||
"flowtype",
|
||||
"babel"
|
||||
],
|
||||
|
@ -104,6 +105,9 @@ module.exports = {
|
|||
|
||||
// crashes currently: https://github.com/eslint/eslint/issues/6274
|
||||
"generator-star-spacing": "off",
|
||||
|
||||
"react-hooks/rules-of-hooks": "error",
|
||||
"react-hooks/exhaustive-deps": "warn",
|
||||
},
|
||||
settings: {
|
||||
flowtype: {
|
||||
|
|
|
@ -135,6 +135,7 @@
|
|||
"eslint-plugin-babel": "^5.2.1",
|
||||
"eslint-plugin-flowtype": "^2.30.0",
|
||||
"eslint-plugin-react": "^7.7.0",
|
||||
"eslint-plugin-react-hooks": "^2.0.1",
|
||||
"estree-walker": "^0.5.0",
|
||||
"expect": "^24.1.0",
|
||||
"file-loader": "^3.0.1",
|
||||
|
|
|
@ -131,6 +131,7 @@
|
|||
@import "./views/messages/_TextualEvent.scss";
|
||||
@import "./views/messages/_UnknownBody.scss";
|
||||
@import "./views/messages/_ViewSourceEvent.scss";
|
||||
@import "./views/right_panel/_UserInfo.scss";
|
||||
@import "./views/room_settings/_AliasSettings.scss";
|
||||
@import "./views/room_settings/_ColorSettings.scss";
|
||||
@import "./views/rooms/_AppsDrawer.scss";
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2019 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.
|
||||
*/
|
||||
|
||||
.mx_UserInfo {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.mx_UserInfo_profile .mx_E2EIcon {
|
||||
display: inline;
|
||||
margin: auto;
|
||||
padding-right: 25px;
|
||||
mask-size: contain;
|
||||
}
|
||||
|
||||
.mx_UserInfo_cancel {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
padding: 10px 0 10px 10px;
|
||||
cursor: pointer;
|
||||
mask-image: url('$(res)/img/minimise.svg');
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: 16px center;
|
||||
background-color: $rightpanel-button-color;
|
||||
}
|
||||
|
||||
.mx_UserInfo_profile h2 {
|
||||
flex: 1;
|
||||
overflow-x: auto;
|
||||
max-height: 50px;
|
||||
}
|
||||
|
||||
.mx_UserInfo h2 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin: 16px 0 8px 0;
|
||||
}
|
||||
|
||||
.mx_UserInfo_container {
|
||||
padding: 0 16px 16px 16px;
|
||||
border-bottom: 1px solid lightgray;
|
||||
}
|
||||
|
||||
.mx_UserInfo_memberDetailsContainer {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.mx_UserInfo .mx_RoomTile_nameContainer {
|
||||
width: 154px;
|
||||
}
|
||||
|
||||
.mx_UserInfo .mx_RoomTile_badge {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_UserInfo .mx_RoomTile_name {
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
.mx_UserInfo_avatar {
|
||||
background: $tagpanel-bg-color;
|
||||
}
|
||||
|
||||
.mx_UserInfo_avatar > img {
|
||||
height: auto;
|
||||
width: 100%;
|
||||
max-height: 30vh;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mx_UserInfo_avatar .mx_BaseAvatar.mx_BaseAvatar_image {
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
.mx_UserInfo h3 {
|
||||
text-transform: uppercase;
|
||||
color: $input-darker-fg-color;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.mx_UserInfo_profileField {
|
||||
font-size: 15px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mx_UserInfo_memberDetails {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mx_UserInfo_field {
|
||||
cursor: pointer;
|
||||
font-size: 15px;
|
||||
color: $primary-fg-color;
|
||||
margin-left: 8px;
|
||||
line-height: 23px;
|
||||
}
|
||||
|
||||
.mx_UserInfo_createRoom {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.mx_UserInfo_createRoom_label {
|
||||
width: initial !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_UserInfo_statusMessage {
|
||||
font-size: 11px;
|
||||
opacity: 0.5;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: clip;
|
||||
}
|
||||
.mx_UserInfo .mx_UserInfo_scrollContainer {
|
||||
flex: 1;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.mx_UserInfo .mx_UserInfo_scrollContainer .mx_UserInfo_container {
|
||||
padding-top: 16px;
|
||||
padding-bottom: 0;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.mx_UserInfo_container_header {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.mx_UserInfo_container_header_right {
|
||||
position: relative;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.mx_UserInfo_newDmButton {
|
||||
background-color: $roomheader-addroom-bg-color;
|
||||
border-radius: 10px; // 16/2 + 2 padding
|
||||
height: 16px;
|
||||
flex: 0 0 16px;
|
||||
|
||||
&::before {
|
||||
background-color: $roomheader-addroom-fg-color;
|
||||
mask: url('$(res)/img/icons-room-add.svg');
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
|
@ -27,6 +27,7 @@ import { MatrixClient } from 'matrix-js-sdk';
|
|||
import RateLimitedFunc from '../../ratelimitedfunc';
|
||||
import { showGroupInviteDialog, showGroupAddRoomDialog } from '../../GroupAddressPicker';
|
||||
import GroupStore from '../../stores/GroupStore';
|
||||
import SettingsStore from "../../settings/SettingsStore";
|
||||
|
||||
export default class RightPanel extends React.Component {
|
||||
static get propTypes() {
|
||||
|
@ -165,6 +166,7 @@ export default class RightPanel extends React.Component {
|
|||
render() {
|
||||
const MemberList = sdk.getComponent('rooms.MemberList');
|
||||
const MemberInfo = sdk.getComponent('rooms.MemberInfo');
|
||||
const UserInfo = sdk.getComponent('right_panel.UserInfo');
|
||||
const ThirdPartyMemberInfo = sdk.getComponent('rooms.ThirdPartyMemberInfo');
|
||||
const NotificationPanel = sdk.getComponent('structures.NotificationPanel');
|
||||
const FilePanel = sdk.getComponent('structures.FilePanel');
|
||||
|
@ -183,14 +185,46 @@ export default class RightPanel extends React.Component {
|
|||
} else if (this.state.phase === RightPanel.Phase.GroupRoomList) {
|
||||
panel = <GroupRoomList groupId={this.props.groupId} key={this.props.groupId} />;
|
||||
} else if (this.state.phase === RightPanel.Phase.RoomMemberInfo) {
|
||||
panel = <MemberInfo member={this.state.member} key={this.props.roomId || this.state.member.userId} />;
|
||||
if (SettingsStore.isFeatureEnabled("feature_user_info_panel")) {
|
||||
const onClose = () => {
|
||||
dis.dispatch({
|
||||
action: "view_user",
|
||||
member: null,
|
||||
});
|
||||
};
|
||||
panel = <UserInfo
|
||||
user={this.state.member}
|
||||
roomId={this.props.roomId}
|
||||
key={this.props.roomId || this.state.member.userId}
|
||||
onClose={onClose}
|
||||
/>;
|
||||
} else {
|
||||
panel = <MemberInfo member={this.state.member} key={this.props.roomId || this.state.member.userId} />;
|
||||
}
|
||||
} else if (this.state.phase === RightPanel.Phase.Room3pidMemberInfo) {
|
||||
panel = <ThirdPartyMemberInfo event={this.state.event} key={this.props.roomId} />;
|
||||
} else if (this.state.phase === RightPanel.Phase.GroupMemberInfo) {
|
||||
panel = <GroupMemberInfo
|
||||
groupMember={this.state.member}
|
||||
groupId={this.props.groupId}
|
||||
key={this.state.member.user_id} />;
|
||||
if (SettingsStore.isFeatureEnabled("feature_user_info_panel")) {
|
||||
const onClose = () => {
|
||||
dis.dispatch({
|
||||
action: "view_user",
|
||||
member: null,
|
||||
});
|
||||
};
|
||||
panel = <UserInfo
|
||||
user={this.state.member}
|
||||
groupId={this.props.groupId}
|
||||
key={this.state.member.userId}
|
||||
onClose={onClose} />;
|
||||
} else {
|
||||
panel = (
|
||||
<GroupMemberInfo
|
||||
groupMember={this.state.member}
|
||||
groupId={this.props.groupId}
|
||||
key={this.state.member.user_id}
|
||||
/>
|
||||
);
|
||||
}
|
||||
} else if (this.state.phase === RightPanel.Phase.GroupRoomInfo) {
|
||||
panel = <GroupRoomInfo
|
||||
groupRoomId={this.state.groupRoomId}
|
||||
|
|
|
@ -596,6 +596,7 @@ module.exports = createReactClass({
|
|||
e.preventDefault();
|
||||
|
||||
// Update the IS in account data. Actually using it may trigger terms.
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
useDefaultIdentityServer();
|
||||
|
||||
// Add email as a valid address type.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
Copyright 2019 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 {useRef, useEffect} from "react";
|
||||
|
||||
// Hook to wrap event emitter on and removeListener in hook lifecycle
|
||||
export const useEventEmitter = (emitter, eventName, handler) => {
|
||||
// Create a ref that stores handler
|
||||
const savedHandler = useRef();
|
||||
|
||||
// Update ref.current value if handler changes.
|
||||
useEffect(() => {
|
||||
savedHandler.current = handler;
|
||||
}, [handler]);
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
// Create event listener that calls handler function stored in ref
|
||||
const eventListener = event => savedHandler.current(event);
|
||||
|
||||
// Add event listener
|
||||
emitter.on(eventName, eventListener);
|
||||
|
||||
// Remove event listener on cleanup
|
||||
return () => {
|
||||
emitter.removeListener(eventName, eventListener);
|
||||
};
|
||||
},
|
||||
[eventName, emitter], // Re-run if eventName or emitter changes
|
||||
);
|
||||
};
|
|
@ -334,6 +334,7 @@
|
|||
"Group & filter rooms by custom tags (refresh to apply changes)": "Group & filter rooms by custom tags (refresh to apply changes)",
|
||||
"Render simple counters in room header": "Render simple counters in room header",
|
||||
"Multiple integration managers": "Multiple integration managers",
|
||||
"Use the new, consistent UserInfo panel for Room Members and Group Members": "Use the new, consistent UserInfo panel for Room Members and Group Members",
|
||||
"Use the new, faster, composer for writing messages": "Use the new, faster, composer for writing messages",
|
||||
"Enable Emoji suggestions while typing": "Enable Emoji suggestions while typing",
|
||||
"Use compact timeline layout": "Use compact timeline layout",
|
||||
|
@ -1028,6 +1029,16 @@
|
|||
"When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.",
|
||||
"Members": "Members",
|
||||
"Files": "Files",
|
||||
"Trust & Devices": "Trust & Devices",
|
||||
"Direct messages": "Direct messages",
|
||||
"Remove from community": "Remove from community",
|
||||
"Disinvite this user from community?": "Disinvite this user from community?",
|
||||
"Remove this user from community?": "Remove this user from community?",
|
||||
"Failed to withdraw invitation": "Failed to withdraw invitation",
|
||||
"Failed to remove user from community": "Failed to remove user from community",
|
||||
"Failed to deactivate user": "Failed to deactivate user",
|
||||
"This client does not support end-to-end encryption.": "This client does not support end-to-end encryption.",
|
||||
"Messages in this room are not end-to-end encrypted.": "Messages in this room are not end-to-end encrypted.",
|
||||
"Sunday": "Sunday",
|
||||
"Monday": "Monday",
|
||||
"Tuesday": "Tuesday",
|
||||
|
@ -1072,11 +1083,6 @@
|
|||
"Removed or unknown message type": "Removed or unknown message type",
|
||||
"Message removed by %(userId)s": "Message removed by %(userId)s",
|
||||
"Message removed": "Message removed",
|
||||
"Remove from community": "Remove from community",
|
||||
"Disinvite this user from community?": "Disinvite this user from community?",
|
||||
"Remove this user from community?": "Remove this user from community?",
|
||||
"Failed to withdraw invitation": "Failed to withdraw invitation",
|
||||
"Failed to remove user from community": "Failed to remove user from community",
|
||||
"Failed to load group members": "Failed to load group members",
|
||||
"Filter community members": "Filter community members",
|
||||
"Invite to this community": "Invite to this community",
|
||||
|
|
|
@ -120,6 +120,12 @@ export const SETTINGS = {
|
|||
supportedLevels: LEVELS_FEATURE,
|
||||
default: false,
|
||||
},
|
||||
"feature_user_info_panel": {
|
||||
isFeature: true,
|
||||
displayName: _td("Use the new, consistent UserInfo panel for Room Members and Group Members"),
|
||||
supportedLevels: LEVELS_FEATURE,
|
||||
default: false,
|
||||
},
|
||||
"useCiderComposer": {
|
||||
displayName: _td("Use the new, faster, composer for writing messages"),
|
||||
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
Copyright 2019 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 React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import {MatrixClient} from "matrix-js-sdk";
|
||||
|
||||
// Higher Order Component to allow use of legacy MatrixClient React Context
|
||||
// in Functional Components which do not otherwise support legacy React Contexts
|
||||
export default (Component) => class extends React.PureComponent {
|
||||
static contextTypes = {
|
||||
matrixClient: PropTypes.instanceOf(MatrixClient).isRequired,
|
||||
};
|
||||
|
||||
render() {
|
||||
return <Component {...this.props} matrixClient={this.context.matrixClient} />;
|
||||
}
|
||||
};
|
|
@ -2891,6 +2891,11 @@ eslint-plugin-flowtype@^2.30.0:
|
|||
dependencies:
|
||||
lodash "^4.17.10"
|
||||
|
||||
eslint-plugin-react-hooks@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.0.1.tgz#e898ec26a0a335af6f7b0ad1f0bedda7143ed756"
|
||||
integrity sha512-xir+3KHKo86AasxlCV8AHRtIZPHljqCRRUYgASkbatmt0fad4+5GgC7zkT7o/06hdKM6MIwp8giHVXqBPaarHQ==
|
||||
|
||||
eslint-plugin-react@^7.7.0:
|
||||
version "7.14.3"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz#911030dd7e98ba49e1b2208599571846a66bdf13"
|
||||
|
|
Loading…
Reference in New Issue