Add UserInfo panel (consolidation of MemberInfo & GroupMemberInfo) Labs
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
b091cf1f6d
commit
df02eb8e92
10 changed files with 1445 additions and 5 deletions
|
@ -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: {
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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";
|
||||||
|
|
175
res/css/views/right_panel/_UserInfo.scss
Normal file
175
res/css/views/right_panel/_UserInfo.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
1201
src/components/views/right_panel/UserInfo.js
Normal file
1201
src/components/views/right_panel/UserInfo.js
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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",
|
||||||
|
|
|
@ -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,
|
||||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -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"
|
||||||
|
|
Loading…
Reference in a new issue