Merge branch 'develop' into luke/groups-membership-section-redesign

pull/21833/head
Luke Barnard 2017-09-21 17:25:12 +01:00 committed by GitHub
commit d75efb83f1
4 changed files with 78 additions and 21 deletions

View File

@ -547,9 +547,20 @@ export default React.createClass({
</div>
</div>;
} else if (group.myMembership === 'join') {
let youAreAMemberText = _t("You are a member of this group");
if (this.state.summary.user && this.state.summary.user.is_privileged) {
youAreAMemberText = _t("You are an administrator of this group");
}
return <div className="mx_GroupView_membershipSection mx_GroupView_membershipSection_joined">
<div className="mx_GroupView_membershipSection_description">
{_t("You are a member of this group")}
{youAreAMemberText}
</div>
<div className="mx_GroupView_membership_buttonContainer">
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
onClick={this._onLeaveClick}
>
{_t("Leave")}
</AccessibleButton>
</div>
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
onClick={this._onLeaveClick}
@ -669,6 +680,7 @@ export default React.createClass({
{this._getFeaturedRoomsNode()}
{this._getFeaturedUsersNode()}
</div>;
if (summary.user && summary.user.is_privileged) {
rightButtons.push(
<AccessibleButton className="mx_GroupHeader_button"
onClick={this._onEditClick} title={_t("Edit Group")} key="_editButton"
@ -676,6 +688,7 @@ export default React.createClass({
<TintableSvg src="img/icons-settings-room.svg" width="16" height="16"/>
</AccessibleButton>,
);
}
if (this.props.collapsedRhs) {
rightButtons.push(
<AccessibleButton className="mx_GroupHeader_button"

View File

@ -20,6 +20,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import {MatrixClient} from 'matrix-js-sdk';
import UserSettingsStore from '../../../UserSettingsStore';
import dis from '../../../dispatcher';
import Promise from 'bluebird';
const BULK_REQUEST_DEBOUNCE_MS = 200;
@ -120,15 +121,54 @@ async function getGroupProfileCached(matrixClient, groupId) {
return groupProfiles[groupId];
}
groupProfiles[groupId] = await matrixClient.getGroupProfile(groupId);
const profile = await matrixClient.getGroupProfile(groupId);
groupProfiles[groupId] = {
groupId,
avatarUrl: profile.avatar_url,
};
return groupProfiles[groupId];
}
class FlairAvatar extends React.Component {
constructor() {
super();
this.onClick = this.onClick.bind(this);
}
onClick(ev) {
ev.preventDefault();
// Don't trigger onClick of parent element
ev.stopPropagation();
dis.dispatch({
action: 'view_group',
group_id: this.props.groupProfile.groupId,
});
}
render() {
const httpUrl = this.context.matrixClient.mxcUrlToHttp(
this.props.groupProfile.avatarUrl, 14, 14, 'scale', false);
return <img src={httpUrl} width="14px" height="14px" onClick={this.onClick}/>;
}
}
FlairAvatar.propTypes = {
groupProfile: PropTypes.shape({
groupId: PropTypes.string.isRequired,
avatarUrl: PropTypes.string.isRequired,
}),
};
FlairAvatar.contextTypes = {
matrixClient: React.PropTypes.instanceOf(MatrixClient).isRequired,
};
export default class Flair extends React.Component {
constructor() {
super();
this.state = {
avatarUrls: [],
profiles: [],
};
}
@ -143,7 +183,7 @@ export default class Flair extends React.Component {
}
}
async _getAvatarUrls(groups) {
async _getGroupProfiles(groups) {
const profiles = [];
for (const groupId of groups) {
let groupProfile = null;
@ -154,9 +194,7 @@ export default class Flair extends React.Component {
}
profiles.push(groupProfile);
}
const avatarUrls = profiles.filter((p) => p !== null).map((p) => p.avatar_url);
return avatarUrls;
return profiles.filter((p) => p !== null);
}
async _generateAvatars() {
@ -176,19 +214,18 @@ export default class Flair extends React.Component {
if (!groups || groups.length === 0) {
return;
}
const avatarUrls = await this._getAvatarUrls(groups);
const profiles = await this._getGroupProfiles(groups);
if (!this.unmounted) {
this.setState({avatarUrls});
this.setState({profiles});
}
}
render() {
if (this.state.avatarUrls.length === 0) {
if (this.state.profiles.length === 0) {
return <div />;
}
const avatars = this.state.avatarUrls.map((avatarUrl, index) => {
const httpUrl = this.context.matrixClient.mxcUrlToHttp(avatarUrl, 14, 14, 'scale', false);
return <img key={index} src={httpUrl} width="14px" height="14px"/>;
const avatars = this.state.profiles.map((profile, index) => {
return <FlairAvatar key={index} groupProfile={profile}/>;
});
return (
<span className="mx_Flair" style={{"marginLeft": "5px", "verticalAlign": "-3px"}}>

View File

@ -89,6 +89,7 @@ module.exports = React.createClass({
cli.on("RoomMember.name", this.onRoomMemberName);
cli.on("Event.decrypted", this.onEventDecrypted);
cli.on("accountData", this.onAccountData);
cli.on("Group.myMembership", this._onGroupMyMembership);
this.refreshRoomList();
@ -157,6 +158,7 @@ module.exports = React.createClass({
MatrixClientPeg.get().removeListener("RoomMember.name", this.onRoomMemberName);
MatrixClientPeg.get().removeListener("Event.decrypted", this.onEventDecrypted);
MatrixClientPeg.get().removeListener("accountData", this.onAccountData);
MatrixClientPeg.get().removeListener("Group.myMembership", this._onGroupMyMembership);
}
// cancel any pending calls to the rate_limited_funcs
this._delayedRefreshRoomList.cancelPendingCall();
@ -236,6 +238,10 @@ module.exports = React.createClass({
}
},
_onGroupMyMembership: function(group) {
this.forceUpdate();
},
_delayedRefreshRoomList: new rate_limited_func(function() {
this.refreshRoomList();
}, 500),

View File

@ -892,5 +892,6 @@
"Add users to the group summary": "Add users to the group summary",
"Who would you like to add to this summary?": "Who would you like to add to this summary?",
"Add to summary": "Add to summary",
"Failed to add the following users to the summary of %(groupId)s:": "Failed to add the following users to the summary of %(groupId)s:"
"Failed to add the following users to the summary of %(groupId)s:": "Failed to add the following users to the summary of %(groupId)s:",
"You are an administrator of this group": "You are an administrator of this group"
}