Add UserInfo panel (consolidation of MemberInfo & GroupMemberInfo) Labs

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2019-10-07 16:52:50 +01:00
parent b091cf1f6d
commit df02eb8e92
10 changed files with 1445 additions and 5 deletions

View file

@ -12,6 +12,7 @@ module.exports = {
extends: [matrixJsSdkPath + "/.eslintrc.js"], extends: [matrixJsSdkPath + "/.eslintrc.js"],
plugins: [ plugins: [
"react", "react",
"react-hooks",
"flowtype", "flowtype",
"babel" "babel"
], ],
@ -104,6 +105,9 @@ module.exports = {
// crashes currently: https://github.com/eslint/eslint/issues/6274 // crashes currently: https://github.com/eslint/eslint/issues/6274
"generator-star-spacing": "off", "generator-star-spacing": "off",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
}, },
settings: { settings: {
flowtype: { flowtype: {

View file

@ -57,6 +57,7 @@
"test-multi": "karma start" "test-multi": "karma start"
}, },
"dependencies": { "dependencies": {
"@use-it/event-listener": "^0.1.3",
"babel-plugin-syntax-dynamic-import": "^6.18.0", "babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-runtime": "^6.26.0", "babel-runtime": "^6.26.0",
"bluebird": "^3.5.0", "bluebird": "^3.5.0",
@ -134,6 +135,7 @@
"eslint-plugin-babel": "^5.2.1", "eslint-plugin-babel": "^5.2.1",
"eslint-plugin-flowtype": "^2.30.0", "eslint-plugin-flowtype": "^2.30.0",
"eslint-plugin-react": "^7.7.0", "eslint-plugin-react": "^7.7.0",
"eslint-plugin-react-hooks": "^2.0.1",
"estree-walker": "^0.5.0", "estree-walker": "^0.5.0",
"expect": "^24.1.0", "expect": "^24.1.0",
"file-loader": "^3.0.1", "file-loader": "^3.0.1",

View file

@ -132,6 +132,7 @@
@import "./views/messages/_TextualEvent.scss"; @import "./views/messages/_TextualEvent.scss";
@import "./views/messages/_UnknownBody.scss"; @import "./views/messages/_UnknownBody.scss";
@import "./views/messages/_ViewSourceEvent.scss"; @import "./views/messages/_ViewSourceEvent.scss";
@import "./views/right_panel/_UserInfo.scss";
@import "./views/room_settings/_AliasSettings.scss"; @import "./views/room_settings/_AliasSettings.scss";
@import "./views/room_settings/_ColorSettings.scss"; @import "./views/room_settings/_ColorSettings.scss";
@import "./views/rooms/_AppsDrawer.scss"; @import "./views/rooms/_AppsDrawer.scss";

View file

@ -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;
}
}

View file

@ -27,6 +27,7 @@ import { MatrixClient } from 'matrix-js-sdk';
import RateLimitedFunc from '../../ratelimitedfunc'; import RateLimitedFunc from '../../ratelimitedfunc';
import { showGroupInviteDialog, showGroupAddRoomDialog } from '../../GroupAddressPicker'; import { showGroupInviteDialog, showGroupAddRoomDialog } from '../../GroupAddressPicker';
import GroupStore from '../../stores/GroupStore'; import GroupStore from '../../stores/GroupStore';
import SettingsStore from "../../settings/SettingsStore";
export default class RightPanel extends React.Component { export default class RightPanel extends React.Component {
static get propTypes() { static get propTypes() {
@ -165,6 +166,7 @@ export default class RightPanel extends React.Component {
render() { render() {
const MemberList = sdk.getComponent('rooms.MemberList'); const MemberList = sdk.getComponent('rooms.MemberList');
const MemberInfo = sdk.getComponent('rooms.MemberInfo'); const MemberInfo = sdk.getComponent('rooms.MemberInfo');
const UserInfo = sdk.getComponent('right_panel.UserInfo');
const ThirdPartyMemberInfo = sdk.getComponent('rooms.ThirdPartyMemberInfo'); const ThirdPartyMemberInfo = sdk.getComponent('rooms.ThirdPartyMemberInfo');
const NotificationPanel = sdk.getComponent('structures.NotificationPanel'); const NotificationPanel = sdk.getComponent('structures.NotificationPanel');
const FilePanel = sdk.getComponent('structures.FilePanel'); 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) { } else if (this.state.phase === RightPanel.Phase.GroupRoomList) {
panel = <GroupRoomList groupId={this.props.groupId} key={this.props.groupId} />; panel = <GroupRoomList groupId={this.props.groupId} key={this.props.groupId} />;
} else if (this.state.phase === RightPanel.Phase.RoomMemberInfo) { } else if (this.state.phase === RightPanel.Phase.RoomMemberInfo) {
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} />; panel = <MemberInfo member={this.state.member} key={this.props.roomId || this.state.member.userId} />;
}
} else if (this.state.phase === RightPanel.Phase.Room3pidMemberInfo) { } else if (this.state.phase === RightPanel.Phase.Room3pidMemberInfo) {
panel = <ThirdPartyMemberInfo event={this.state.event} key={this.props.roomId} />; panel = <ThirdPartyMemberInfo event={this.state.event} key={this.props.roomId} />;
} else if (this.state.phase === RightPanel.Phase.GroupMemberInfo) { } else if (this.state.phase === RightPanel.Phase.GroupMemberInfo) {
panel = <GroupMemberInfo 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} groupMember={this.state.member}
groupId={this.props.groupId} groupId={this.props.groupId}
key={this.state.member.user_id} />; key={this.state.member.user_id}
/>
);
}
} else if (this.state.phase === RightPanel.Phase.GroupRoomInfo) { } else if (this.state.phase === RightPanel.Phase.GroupRoomInfo) {
panel = <GroupRoomInfo panel = <GroupRoomInfo
groupRoomId={this.state.groupRoomId} groupRoomId={this.state.groupRoomId}

View file

@ -596,6 +596,7 @@ module.exports = createReactClass({
e.preventDefault(); e.preventDefault();
// Update the IS in account data. Actually using it may trigger terms. // Update the IS in account data. Actually using it may trigger terms.
// eslint-disable-next-line react-hooks/rules-of-hooks
useDefaultIdentityServer(); useDefaultIdentityServer();
// Add email as a valid address type. // Add email as a valid address type.

File diff suppressed because it is too large Load diff

View file

@ -332,6 +332,7 @@
"Group & filter rooms by custom tags (refresh to apply changes)": "Group & filter rooms by custom tags (refresh to apply changes)", "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", "Render simple counters in room header": "Render simple counters in room header",
"Multiple integration managers": "Multiple integration managers", "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", "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", "Enable Emoji suggestions while typing": "Enable Emoji suggestions while typing",
"Use compact timeline layout": "Use compact timeline layout", "Use compact timeline layout": "Use compact timeline layout",
@ -1203,6 +1204,11 @@
"This alias is already in use": "This alias is already in use", "This alias is already in use": "This alias is already in use",
"Room directory": "Room directory", "Room directory": "Room directory",
"And %(count)s more...|other": "And %(count)s more...", "And %(count)s more...|other": "And %(count)s more...",
"Trust & Devices": "Trust & Devices",
"Direct messages": "Direct messages",
"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.",
"ex. @bob:example.com": "ex. @bob:example.com", "ex. @bob:example.com": "ex. @bob:example.com",
"Add User": "Add User", "Add User": "Add User",
"Matrix ID": "Matrix ID", "Matrix ID": "Matrix ID",

View file

@ -120,6 +120,12 @@ export const SETTINGS = {
supportedLevels: LEVELS_FEATURE, supportedLevels: LEVELS_FEATURE,
default: false, 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": { "useCiderComposer": {
displayName: _td("Use the new, faster, composer for writing messages"), displayName: _td("Use the new, faster, composer for writing messages"),
supportedLevels: LEVELS_ACCOUNT_SETTINGS, supportedLevels: LEVELS_ACCOUNT_SETTINGS,

View file

@ -293,6 +293,11 @@
dependencies: dependencies:
"@types/yargs-parser" "*" "@types/yargs-parser" "*"
"@use-it/event-listener@^0.1.3":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@use-it/event-listener/-/event-listener-0.1.3.tgz#a9920b2819d211cf55e68e830997546eec6886d3"
integrity sha512-UCHkLOVU+xj3/1R8jXz8GzDTowkzfIDPESOBlVC2ndgwUSBEqiFdwCoUEs2lcGhJOOiEdmWxF+T23C5+60eEew==
"@webassemblyjs/ast@1.8.5": "@webassemblyjs/ast@1.8.5":
version "1.8.5" version "1.8.5"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359"
@ -2891,6 +2896,11 @@ eslint-plugin-flowtype@^2.30.0:
dependencies: dependencies:
lodash "^4.17.10" 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: eslint-plugin-react@^7.7.0:
version "7.14.3" version "7.14.3"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz#911030dd7e98ba49e1b2208599571846a66bdf13" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz#911030dd7e98ba49e1b2208599571846a66bdf13"