Merge pull request #2341 from matrix-org/bwindels/redesignminimalgroupux
Redesign: make community UX usablepull/21833/head
commit
e0e87d1e8b
|
@ -34,6 +34,8 @@ limitations under the License.
|
||||||
.mx_GroupView_header_view {
|
.mx_GroupView_header_view {
|
||||||
border-bottom: 1px solid $primary-hairline-color;
|
border-bottom: 1px solid $primary-hairline-color;
|
||||||
padding-bottom: 0px;
|
padding-bottom: 0px;
|
||||||
|
padding-left: 8px;
|
||||||
|
padding-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_GroupView_header_avatar, .mx_GroupView_header_info {
|
.mx_GroupView_header_avatar, .mx_GroupView_header_info {
|
||||||
|
|
|
@ -15,10 +15,6 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_MyGroups {
|
.mx_MyGroups {
|
||||||
max-width: 960px;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +30,11 @@ limitations under the License.
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_MyGroups > :not(.mx_RoomHeader) {
|
||||||
|
max-width: 960px;
|
||||||
|
margin: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
.mx_MyGroups_headerCard {
|
.mx_MyGroups_headerCard {
|
||||||
flex: 1 0 50%;
|
flex: 1 0 50%;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
|
@ -43,14 +44,31 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MyGroups_headerCard .mx_MyGroups_headerCard_button {
|
.mx_MyGroups_headerCard .mx_MyGroups_headerCard_button {
|
||||||
|
flex: 0 0 auto;
|
||||||
margin-right: 13px;
|
margin-right: 13px;
|
||||||
height: 50px;
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
border-radius: 20px;
|
||||||
|
background-color: $roomheader-addroom-color;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
background-color: $accent-fg-color;
|
||||||
|
mask: url('../../img/icons-create-room.svg');
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-position: center;
|
||||||
|
mask-size: 80%;
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MyGroups_headerCard_button object {
|
|
||||||
/* Otherwise the SVG object absorbs clicks and the button doesn't work */
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_MyGroups_headerCard_header {
|
.mx_MyGroups_headerCard_header {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
|
@ -124,13 +124,28 @@ limitations under the License.
|
||||||
padding-right: 4px;
|
padding-right: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_TagPanel_groupsButton {
|
.mx_TagPanel_groupsButton > .mx_AccessibleButton {
|
||||||
|
flex: auto;
|
||||||
margin-bottom: 17px;
|
margin-bottom: 17px;
|
||||||
margin-top: 18px;
|
margin-top: 18px;
|
||||||
height: 25px;
|
height: 40px;
|
||||||
display: none;
|
width: 40px;
|
||||||
}
|
border-radius: 20px;
|
||||||
|
background-color: $roomheader-addroom-color;
|
||||||
|
position: relative;
|
||||||
|
/* overwrite mx_RoleButton inline-block */
|
||||||
|
display: block !important;
|
||||||
|
|
||||||
.mx_TagPanel_groupsButton object {
|
&:before {
|
||||||
pointer-events: none;
|
background-color: $tagpanel-bg-color;
|
||||||
|
mask: url('../../img/icons-groups-nobg.svg');
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-position: center 8px;
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,4 +18,10 @@ limitations under the License.
|
||||||
position: relative;
|
position: relative;
|
||||||
color: $primary-fg-color;
|
color: $primary-fg-color;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_GroupRoomList_wrapper {
|
||||||
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,21 @@ limitations under the License.
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
|
||||||
|
|
||||||
.mx_MemberList .mx_Spinner {
|
.mx_Spinner {
|
||||||
flex: 1 0 auto;
|
flex: 1 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: $h3-color;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 13px;
|
||||||
|
padding-left: 3px;
|
||||||
|
padding-right: 12px;
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MemberList_chevron {
|
.mx_MemberList_chevron {
|
||||||
|
@ -45,23 +56,15 @@ limitations under the License.
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MemberList h2, .mx_GroupMemberList h2 {
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: $h3-color;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 13px;
|
|
||||||
padding-left: 3px;
|
|
||||||
padding-right: 12px;
|
|
||||||
margin-top: 8px;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_MemberList_wrapper {
|
.mx_MemberList_wrapper {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.mx_MemberList_invite {
|
.mx_MemberList_invite,
|
||||||
|
.mx_RightPanel_invite {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: $button-bg-color;
|
background-color: $button-bg-color;
|
||||||
|
@ -69,15 +72,20 @@ limitations under the License.
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
margin: 9px;
|
margin: 9px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
color: $button-fg-color;
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
span {
|
.mx_RightPanel_icon {
|
||||||
|
padding-right: 5px;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_MemberList_invite span {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
background-image: url('../../img/icon-invite-people.svg');
|
background-image: url('../../img/icon-invite-people.svg');
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center left;
|
background-position: center left;
|
||||||
padding-left: 25px;
|
padding-left: 25px;
|
||||||
|
|
||||||
font-weight: 600;
|
|
||||||
color: $button-fg-color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
viewBox="0 0 25.087629 21.62648"
|
||||||
|
y="0px"
|
||||||
|
x="0px"
|
||||||
|
id="Layer_2"
|
||||||
|
version="1.1"
|
||||||
|
width="25.087629"
|
||||||
|
height="21.62648"><metadata
|
||||||
|
id="metadata24"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs22">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</defs>
|
||||||
|
<style
|
||||||
|
id="style2"
|
||||||
|
type="text/css">
|
||||||
|
.st4{fill:none;stroke-miterlimit:10;}
|
||||||
|
</style>
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1.20877647;stroke-miterlimit:10;stroke-opacity:1"
|
||||||
|
d="m 19.186977,20.022092 c 0,-3.868085 0,-6.890026 -6.890026,-6.890026 -6.8900252,0 -6.8900252,3.021941 -6.8900252,6.890026 4.8351052,0 7.7361692,0 13.7800512,0 z"
|
||||||
|
class="st4"
|
||||||
|
id="path4242_1_" /><circle
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1.20877647;stroke-miterlimit:10;stroke-opacity:1"
|
||||||
|
r="3.8680847"
|
||||||
|
cy="7.2090473"
|
||||||
|
cx="12.296951"
|
||||||
|
class="st4"
|
||||||
|
id="circle4244_1_" /><path
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke-width:1.20877647"
|
||||||
|
id="path8"
|
||||||
|
d="m 2.3296541,15.626195 c 0,-3.021941 0.362633,-4.835106 5.4394941,-4.835106 0.362633,0 0.7252659,0 0.9670212,0 -0.3626329,-0.362633 -0.7252659,-0.725266 -0.9670212,-1.208776 0,0 0,0 -0.1208776,0 C 1,9.582313 1,12.846009 1,16.230583 v 0.604389 h 3.2636965 c 0.1208776,-0.362633 0.1208776,-0.846144 0.2417553,-1.208777 z" /><path
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke-width:1.20877647"
|
||||||
|
id="path10"
|
||||||
|
d="m 4.9889623,5.1098401 c 0,-1.5714095 1.2087765,-2.7801859 2.7801859,-2.7801859 0.7252659,0 1.3296542,0.2417553 1.8131647,0.6043882 C 9.9449463,2.6922871 10.307579,2.5714095 10.791089,2.3296542 10.065823,1.4835106 8.9779247,1 7.8900259,1 5.7142282,1 3.9010635,2.8131648 3.9010635,4.9889624 c 0,2.1757977 1.6922871,3.8680849 3.8680847,3.9889619 C 7.6482706,8.6152923 7.5273929,8.1317812 7.4065153,7.7691483 5.9559835,7.6482706 4.9889623,6.5603718 4.9889623,5.1098401 Z" /><path
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke-width:1.20877647"
|
||||||
|
id="path12"
|
||||||
|
d="m 24.08763,16.230583 c 0,-3.384574 0,-6.64827 -6.64827,-6.64827 -0.241756,0 -0.362633,0 -0.604389,0 -0.241755,0.48351 -0.604388,0.846143 -0.967021,1.208776 0.483511,0 0.967021,-0.120877 1.57141,-0.120877 5.076861,0 5.439494,1.813164 5.439494,4.835105 H 19.97779 c 0.120878,0.362633 0.241756,0.846144 0.241756,1.208777 h 3.747207 v -0.483511 z" /><path
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke-width:1.20877647"
|
||||||
|
id="path14"
|
||||||
|
d="m 17.43936,2.3296542 c 1.571409,0 2.780186,1.2087764 2.780186,2.7801859 0,1.5714094 -1.208777,2.7801858 -2.780186,2.7801858 0,0 0,0 0,0 0,0.362633 -0.120878,0.8461434 -0.362633,1.2087761 0.120877,0 0.241755,0 0.362633,0 2.175797,0 3.988962,-1.8131643 3.988962,-3.9889619 0,-2.1757977 -1.813165,-3.9889624 -3.988962,-3.9889624 -1.208777,0 -2.296676,0.6043882 -3.021941,1.4505318 0.362632,0.1208776 0.725265,0.3626329 1.087898,0.6043882 0.362633,-0.4835106 1.087899,-0.8461435 1.934043,-0.8461435 z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.3 KiB |
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="enable-background:new 0 0 25 25;"
|
||||||
|
viewBox="0 0 25 25"
|
||||||
|
y="0px"
|
||||||
|
x="0px"
|
||||||
|
id="Layer_1"
|
||||||
|
version="1.1"><metadata
|
||||||
|
id="metadata11"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs9">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</defs>
|
||||||
|
<path
|
||||||
|
style="fill:#9fa9ba;fill-opacity:1;stroke-width:1.24281836"
|
||||||
|
d="m 16.418416,10.445225 -0.763833,4.003888 h 3.564555 v 1.57729 h -3.819166 l -1.018445,5.095858 H 12.726556 L 13.745,16.026403 H 9.9258345 L 8.9073901,21.122261 H 7.2524182 L 8.2708625,16.026403 H 4.9609188 v -1.57729 H 8.5254735 L 9.416612,10.445225 H 5.9793629 V 8.989265 H 9.6712233 L 10.689667,3.7720766 h 1.782277 L 11.453501,8.989265 h 3.819166 L 16.29111,3.7720766 h 1.654972 L 16.927638,8.989265 h 3.309944 v 1.45596 h -3.819166 m -6.23797,4.125218 h 3.819166 l 0.763832,-4.003888 h -3.819166 l -0.763832,4.003888"
|
||||||
|
id="path3002" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -19,7 +19,6 @@ import ResizeHandle from '../views/elements/ResizeHandle';
|
||||||
import {Resizer, FixedDistributor} from '../../resizer';
|
import {Resizer, FixedDistributor} from '../../resizer';
|
||||||
|
|
||||||
export default class MainSplit extends React.Component {
|
export default class MainSplit extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this._setResizeContainerRef = this._setResizeContainerRef.bind(this);
|
this._setResizeContainerRef = this._setResizeContainerRef.bind(this);
|
||||||
|
|
|
@ -60,7 +60,6 @@ export default withMatrixClient(React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
const Loader = sdk.getComponent("elements.Spinner");
|
const Loader = sdk.getComponent("elements.Spinner");
|
||||||
const SimpleRoomHeader = sdk.getComponent('rooms.SimpleRoomHeader');
|
const SimpleRoomHeader = sdk.getComponent('rooms.SimpleRoomHeader');
|
||||||
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
|
||||||
const GroupTile = sdk.getComponent("groups.GroupTile");
|
const GroupTile = sdk.getComponent("groups.GroupTile");
|
||||||
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
||||||
|
|
||||||
|
@ -112,7 +111,6 @@ export default withMatrixClient(React.createClass({
|
||||||
<div className='mx_MyGroups_header'>
|
<div className='mx_MyGroups_header'>
|
||||||
<div className="mx_MyGroups_headerCard">
|
<div className="mx_MyGroups_headerCard">
|
||||||
<AccessibleButton className='mx_MyGroups_headerCard_button' onClick={this._onCreateGroupClick}>
|
<AccessibleButton className='mx_MyGroups_headerCard_button' onClick={this._onCreateGroupClick}>
|
||||||
<TintableSvg src="img/icons-create-room.svg" width="50" height="50" />
|
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
<div className="mx_MyGroups_headerCard_content">
|
<div className="mx_MyGroups_headerCard_content">
|
||||||
<div className="mx_MyGroups_headerCard_header">
|
<div className="mx_MyGroups_headerCard_header">
|
||||||
|
|
|
@ -20,17 +20,14 @@ 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 { _t } from '../../languageHandler';
|
|
||||||
import sdk from '../../index';
|
import sdk from '../../index';
|
||||||
import dis from '../../dispatcher';
|
import dis from '../../dispatcher';
|
||||||
import { MatrixClient } from 'matrix-js-sdk';
|
import { MatrixClient } from 'matrix-js-sdk';
|
||||||
import RateLimitedFunc from '../../ratelimitedfunc';
|
import RateLimitedFunc from '../../ratelimitedfunc';
|
||||||
import AccessibleButton from '../../components/views/elements/AccessibleButton';
|
|
||||||
import { showGroupInviteDialog, showGroupAddRoomDialog } from '../../GroupAddressPicker';
|
import { showGroupInviteDialog, showGroupAddRoomDialog } from '../../GroupAddressPicker';
|
||||||
import GroupStore from '../../stores/GroupStore';
|
import GroupStore from '../../stores/GroupStore';
|
||||||
|
|
||||||
export default class RightPanel extends React.Component {
|
export default class RightPanel extends React.Component {
|
||||||
|
|
||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
roomId: React.PropTypes.string, // if showing panels for a given room, this is set
|
roomId: React.PropTypes.string, // if showing panels for a given room, this is set
|
||||||
|
@ -141,6 +138,8 @@ export default class RightPanel extends React.Component {
|
||||||
if (payload.action === "view_right_panel_phase") {
|
if (payload.action === "view_right_panel_phase") {
|
||||||
this.setState({
|
this.setState({
|
||||||
phase: payload.phase,
|
phase: payload.phase,
|
||||||
|
groupRoomId: payload.groupRoomId,
|
||||||
|
groupId: payload.groupId,
|
||||||
member: payload.member,
|
member: payload.member,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -157,13 +156,6 @@ export default class RightPanel extends React.Component {
|
||||||
const GroupRoomList = sdk.getComponent('groups.GroupRoomList');
|
const GroupRoomList = sdk.getComponent('groups.GroupRoomList');
|
||||||
const GroupRoomInfo = sdk.getComponent('groups.GroupRoomInfo');
|
const GroupRoomInfo = sdk.getComponent('groups.GroupRoomInfo');
|
||||||
|
|
||||||
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
|
||||||
|
|
||||||
const isPhaseGroup = [
|
|
||||||
RightPanel.Phase.GroupMemberInfo,
|
|
||||||
RightPanel.Phase.GroupMemberList,
|
|
||||||
].includes(this.state.phase);
|
|
||||||
|
|
||||||
let panel = <div />;
|
let panel = <div />;
|
||||||
|
|
||||||
if (this.props.roomId && this.state.phase === RightPanel.Phase.RoomMemberList) {
|
if (this.props.roomId && this.state.phase === RightPanel.Phase.RoomMemberList) {
|
||||||
|
@ -190,26 +182,6 @@ export default class RightPanel extends React.Component {
|
||||||
panel = <FilePanel roomId={this.props.roomId} />;
|
panel = <FilePanel roomId={this.props.roomId} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: either include this in the DOM again, or move it to other component
|
|
||||||
if (this.props.groupId && this.state.isUserPrivilegedInGroup) {
|
|
||||||
// inviteGroup =
|
|
||||||
isPhaseGroup ? (
|
|
||||||
<AccessibleButton className="mx_RightPanel_invite" onClick={this.onInviteToGroupButtonClick}>
|
|
||||||
<div className="mx_RightPanel_icon" >
|
|
||||||
<TintableSvg src="img/icon-invite-people.svg" width="35" height="35" />
|
|
||||||
</div>
|
|
||||||
<div className="mx_RightPanel_message">{ _t('Invite to this community') }</div>
|
|
||||||
</AccessibleButton>
|
|
||||||
) : (
|
|
||||||
<AccessibleButton className="mx_RightPanel_invite" onClick={this.onAddRoomToGroupButtonClick}>
|
|
||||||
<div className="mx_RightPanel_icon" >
|
|
||||||
<TintableSvg src="img/icons-room-add.svg" width="35" height="35" />
|
|
||||||
</div>
|
|
||||||
<div className="mx_RightPanel_message">{ _t('Add rooms to this community') }</div>
|
|
||||||
</AccessibleButton>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const classes = classNames("mx_RightPanel", "mx_fadable", {
|
const classes = classNames("mx_RightPanel", "mx_fadable", {
|
||||||
"collapsed": this.props.collapsed,
|
"collapsed": this.props.collapsed,
|
||||||
"mx_fadable_faded": this.props.disabled,
|
"mx_fadable_faded": this.props.disabled,
|
||||||
|
|
|
@ -30,7 +30,7 @@ export default React.createClass({
|
||||||
action: PropTypes.string.isRequired,
|
action: PropTypes.string.isRequired,
|
||||||
mouseOverAction: PropTypes.string,
|
mouseOverAction: PropTypes.string,
|
||||||
label: PropTypes.string.isRequired,
|
label: PropTypes.string.isRequired,
|
||||||
iconPath: PropTypes.string.isRequired,
|
iconPath: PropTypes.string,
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
|
@ -72,6 +72,10 @@ export default React.createClass({
|
||||||
tooltip = <RoomTooltip className="mx_RoleButton_tooltip" label={this.props.label} />;
|
tooltip = <RoomTooltip className="mx_RoleButton_tooltip" label={this.props.label} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const icon = this.props.iconPath ?
|
||||||
|
(<TintableSvg src={this.props.iconPath} width={this.props.size} height={this.props.size} />) :
|
||||||
|
undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AccessibleButton className="mx_RoleButton"
|
<AccessibleButton className="mx_RoleButton"
|
||||||
onClick={this._onClick}
|
onClick={this._onClick}
|
||||||
|
@ -79,7 +83,7 @@ export default React.createClass({
|
||||||
onMouseLeave={this._onMouseLeave}
|
onMouseLeave={this._onMouseLeave}
|
||||||
aria-label={this.props.label}
|
aria-label={this.props.label}
|
||||||
>
|
>
|
||||||
<TintableSvg src={this.props.iconPath} width={this.props.size} height={this.props.size} />
|
{ icon }
|
||||||
{ tooltip }
|
{ tooltip }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
|
|
|
@ -24,7 +24,6 @@ const GroupsButton = function(props) {
|
||||||
return (
|
return (
|
||||||
<ActionButton action="view_my_groups"
|
<ActionButton action="view_my_groups"
|
||||||
label={_t("Communities")}
|
label={_t("Communities")}
|
||||||
iconPath="img/icons-groups.svg"
|
|
||||||
size={props.size}
|
size={props.size}
|
||||||
tooltip={props.tooltip}
|
tooltip={props.tooltip}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -17,8 +17,13 @@ limitations under the License.
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
|
import dis from '../../../dispatcher';
|
||||||
import GroupStore from '../../../stores/GroupStore';
|
import GroupStore from '../../../stores/GroupStore';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { showGroupInviteDialog } from '../../../GroupAddressPicker';
|
||||||
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
|
import TintableSvg from '../elements/TintableSvg';
|
||||||
|
import RightPanel from '../../structures/RightPanel';
|
||||||
|
|
||||||
const INITIAL_LOAD_NUM_MEMBERS = 30;
|
const INITIAL_LOAD_NUM_MEMBERS = 30;
|
||||||
|
|
||||||
|
@ -135,6 +140,16 @@ export default React.createClass({
|
||||||
</TruncatedList>;
|
</TruncatedList>;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onInviteToGroupButtonClick() {
|
||||||
|
showGroupInviteDialog(this.props.groupId).then(() => {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'view_right_panel_phase',
|
||||||
|
phase: RightPanel.Phase.GroupMemberList,
|
||||||
|
groupId: this.props.groupId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
||||||
if (this.state.fetching || this.state.fetchingInvitedMembers) {
|
if (this.state.fetching || this.state.fetchingInvitedMembers) {
|
||||||
|
@ -145,11 +160,9 @@ export default React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
const inputBox = (
|
const inputBox = (
|
||||||
<form autoComplete="off">
|
<input className="mx_GroupMemberList_query mx_textinput" id="mx_GroupMemberList_query" type="text"
|
||||||
<input className="mx_GroupMemberList_query" id="mx_GroupMemberList_query" type="text"
|
|
||||||
onChange={this.onSearchQueryChanged} value={this.state.searchQuery}
|
onChange={this.onSearchQueryChanged} value={this.state.searchQuery}
|
||||||
placeholder={_t('Filter community members')} />
|
placeholder={_t('Filter community members')} autoComplete="off" />
|
||||||
</form>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const joined = this.state.members ? <div className="mx_MemberList_joined">
|
const joined = this.state.members ? <div className="mx_MemberList_joined">
|
||||||
|
@ -162,13 +175,28 @@ export default React.createClass({
|
||||||
{ this.makeGroupMemberTiles(this.state.searchQuery, this.state.invitedMembers) }
|
{ this.makeGroupMemberTiles(this.state.searchQuery, this.state.invitedMembers) }
|
||||||
</div> : <div />;
|
</div> : <div />;
|
||||||
|
|
||||||
|
let inviteButton;
|
||||||
|
if (GroupStore.isUserPrivileged(this.props.groupId)) {
|
||||||
|
inviteButton = (
|
||||||
|
<AccessibleButton
|
||||||
|
className="mx_RightPanel_invite"
|
||||||
|
onClick={this.onInviteToGroupButtonClick}
|
||||||
|
>
|
||||||
|
<div className="mx_RightPanel_icon" >
|
||||||
|
<TintableSvg src="img/icon-invite-people.svg" width="18" height="14" />
|
||||||
|
</div>
|
||||||
|
<div className="mx_RightPanel_message">{ _t('Invite to this community') }</div>
|
||||||
|
</AccessibleButton>);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_MemberList">
|
<div className="mx_MemberList">
|
||||||
{ inputBox }
|
{ inviteButton }
|
||||||
<GeminiScrollbarWrapper autoshow={true}>
|
<GeminiScrollbarWrapper autoshow={true}>
|
||||||
{ joined }
|
{ joined }
|
||||||
{ invited }
|
{ invited }
|
||||||
</GeminiScrollbarWrapper>
|
</GeminiScrollbarWrapper>
|
||||||
|
{ inputBox }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -18,6 +18,9 @@ import { _t } from '../../../languageHandler';
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
import GroupStore from '../../../stores/GroupStore';
|
import GroupStore from '../../../stores/GroupStore';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { showGroupAddRoomDialog } from '../../../GroupAddressPicker';
|
||||||
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
|
import TintableSvg from '../elements/TintableSvg';
|
||||||
|
|
||||||
const INITIAL_LOAD_NUM_ROOMS = 30;
|
const INITIAL_LOAD_NUM_ROOMS = 30;
|
||||||
|
|
||||||
|
@ -90,6 +93,12 @@ export default React.createClass({
|
||||||
this.setState({ searchQuery: ev.target.value });
|
this.setState({ searchQuery: ev.target.value });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onAddRoomToGroupButtonClick() {
|
||||||
|
showGroupAddRoomDialog(this.props.groupId).then(() => {
|
||||||
|
this.forceUpdate();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
makeGroupRoomTiles: function(query) {
|
makeGroupRoomTiles: function(query) {
|
||||||
const GroupRoomTile = sdk.getComponent("groups.GroupRoomTile");
|
const GroupRoomTile = sdk.getComponent("groups.GroupRoomTile");
|
||||||
query = (query || "").toLowerCase();
|
query = (query || "").toLowerCase();
|
||||||
|
@ -120,25 +129,38 @@ export default React.createClass({
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inviteButton;
|
||||||
|
if (GroupStore.isUserPrivileged(this.props.groupId)) {
|
||||||
|
inviteButton = (
|
||||||
|
<AccessibleButton
|
||||||
|
className="mx_RightPanel_invite"
|
||||||
|
onClick={this.onAddRoomToGroupButtonClick}
|
||||||
|
>
|
||||||
|
<div className="mx_RightPanel_icon" >
|
||||||
|
<TintableSvg src="img/icons-room-add.svg" width="18" height="14" />
|
||||||
|
</div>
|
||||||
|
<div className="mx_RightPanel_message">{ _t('Add rooms to this community') }</div>
|
||||||
|
</AccessibleButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
const inputBox = (
|
const inputBox = (
|
||||||
<form autoComplete="off">
|
<input className="mx_GroupRoomList_query mx_textinput" id="mx_GroupRoomList_query" type="text"
|
||||||
<input className="mx_GroupRoomList_query" id="mx_GroupRoomList_query" type="text"
|
|
||||||
onChange={this.onSearchQueryChanged} value={this.state.searchQuery}
|
onChange={this.onSearchQueryChanged} value={this.state.searchQuery}
|
||||||
placeholder={_t('Filter community rooms')} />
|
placeholder={_t('Filter community rooms')} autoComplete="off" />
|
||||||
</form>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
||||||
const TruncatedList = sdk.getComponent("elements.TruncatedList");
|
const TruncatedList = sdk.getComponent("elements.TruncatedList");
|
||||||
return (
|
return (
|
||||||
<div className="mx_GroupRoomList">
|
<div className="mx_GroupRoomList">
|
||||||
{ inputBox }
|
{ inviteButton }
|
||||||
<GeminiScrollbarWrapper autoshow={true} className="mx_GroupRoomList_joined mx_GroupRoomList_outerWrapper">
|
<GeminiScrollbarWrapper autoshow={true} className="mx_GroupRoomList_joined mx_GroupRoomList_outerWrapper">
|
||||||
<TruncatedList className="mx_GroupRoomList_wrapper" truncateAt={this.state.truncateAt}
|
<TruncatedList className="mx_GroupRoomList_wrapper" truncateAt={this.state.truncateAt}
|
||||||
createOverflowElement={this._createOverflowTile}>
|
createOverflowElement={this._createOverflowTile}>
|
||||||
{ this.makeGroupRoomTiles(this.state.searchQuery) }
|
{ this.makeGroupRoomTiles(this.state.searchQuery) }
|
||||||
</TruncatedList>
|
</TruncatedList>
|
||||||
</GeminiScrollbarWrapper>
|
</GeminiScrollbarWrapper>
|
||||||
|
{ inputBox }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -25,7 +25,6 @@ import HeaderButtons from './HeaderButtons';
|
||||||
import RightPanel from '../../structures/RightPanel';
|
import RightPanel from '../../structures/RightPanel';
|
||||||
|
|
||||||
export default class GroupHeaderButtons extends HeaderButtons {
|
export default class GroupHeaderButtons extends HeaderButtons {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props, RightPanel.Phase.GroupMemberList);
|
super(props, RightPanel.Phase.GroupMemberList);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +44,7 @@ export default class GroupHeaderButtons extends HeaderButtons {
|
||||||
} else if (payload.action === "view_group") {
|
} else if (payload.action === "view_group") {
|
||||||
this.setPhase(RightPanel.Phase.GroupMemberList);
|
this.setPhase(RightPanel.Phase.GroupMemberList);
|
||||||
} else if (payload.action === "view_group_room") {
|
} else if (payload.action === "view_group_room") {
|
||||||
this.setPhase(RightPanel.Phase.GroupRoomInfo, {groupRoomId: payload.groupRoomId});
|
this.setPhase(RightPanel.Phase.GroupRoomInfo, {groupRoomId: payload.groupRoomId, groupId: payload.groupId});
|
||||||
} else if (payload.action === "view_group_room_list") {
|
} else if (payload.action === "view_group_room_list") {
|
||||||
this.setPhase(RightPanel.Phase.GroupRoomList);
|
this.setPhase(RightPanel.Phase.GroupRoomList);
|
||||||
} else if (payload.action === "view_group_member_list") {
|
} else if (payload.action === "view_group_member_list") {
|
||||||
|
@ -71,7 +70,7 @@ export default class GroupHeaderButtons extends HeaderButtons {
|
||||||
clickPhase={RightPanel.Phase.GroupMemberList}
|
clickPhase={RightPanel.Phase.GroupMemberList}
|
||||||
analytics={['Right Panel', 'Group Member List Button', 'click']}
|
analytics={['Right Panel', 'Group Member List Button', 'click']}
|
||||||
/>,
|
/>,
|
||||||
<HeaderButton key="_roomsButton" title={_t('Rooms')} iconSrc="img/icons-room.svg"
|
<HeaderButton key="_roomsButton" title={_t('Rooms')} iconSrc="img/icons-room-nobg.svg"
|
||||||
isHighlighted={isPhaseRoom}
|
isHighlighted={isPhaseRoom}
|
||||||
clickPhase={RightPanel.Phase.GroupRoomList}
|
clickPhase={RightPanel.Phase.GroupRoomList}
|
||||||
analytics={['Right Panel', 'Group Room List Button', 'click']}
|
analytics={['Right Panel', 'Group Room List Button', 'click']}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import React from 'react';
|
||||||
import dis from '../../../dispatcher';
|
import dis from '../../../dispatcher';
|
||||||
|
|
||||||
export default class HeaderButtons extends React.Component {
|
export default class HeaderButtons extends React.Component {
|
||||||
|
|
||||||
constructor(props, initialPhase) {
|
constructor(props, initialPhase) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@ import HeaderButtons from './HeaderButtons';
|
||||||
import RightPanel from '../../structures/RightPanel';
|
import RightPanel from '../../structures/RightPanel';
|
||||||
|
|
||||||
export default class RoomHeaderButtons extends HeaderButtons {
|
export default class RoomHeaderButtons extends HeaderButtons {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props, RightPanel.Phase.RoomMemberList);
|
super(props, RightPanel.Phase.RoomMemberList);
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,7 +164,10 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// load stored sizes
|
// load stored sizes
|
||||||
Object.entries(this.subListSizes).forEach(([id, size]) => {
|
Object.entries(this.subListSizes).forEach(([id, size]) => {
|
||||||
this.resizer.forHandleWithId(id).resize(size);
|
const handle = this.resizer.forHandleWithId(id);
|
||||||
|
if (handle) {
|
||||||
|
handle.resize(size);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.resizer.attach();
|
this.resizer.attach();
|
||||||
|
|
|
@ -38,6 +38,9 @@ class RoomSizer extends Sizer {
|
||||||
class RoomDistributor extends FixedDistributor {
|
class RoomDistributor extends FixedDistributor {
|
||||||
resize(itemSize) {
|
resize(itemSize) {
|
||||||
const scrollItem = this.item.querySelector(".mx_RoomSubList_scroll");
|
const scrollItem = this.item.querySelector(".mx_RoomSubList_scroll");
|
||||||
|
if (!scrollItem) {
|
||||||
|
return; //FIXME: happens when starting the page on a community url, taking the safe way out for now
|
||||||
|
}
|
||||||
const fixedHeight = this.item.offsetHeight - scrollItem.offsetHeight;
|
const fixedHeight = this.item.offsetHeight - scrollItem.offsetHeight;
|
||||||
if (itemSize > (fixedHeight + scrollItem.scrollHeight)) {
|
if (itemSize > (fixedHeight + scrollItem.scrollHeight)) {
|
||||||
super.resize("resized-all");
|
super.resize("resized-all");
|
||||||
|
|
Loading…
Reference in New Issue