Add featured users to Group View

pull/21833/head
David Baker 2017-07-10 19:32:02 +01:00
parent 0e67a9158c
commit 925d5bd480
3 changed files with 135 additions and 43 deletions

View File

@ -30,7 +30,7 @@ function categoryRoomListNode(rooms, categoryId, category) {
}); });
let catHeader = null; let catHeader = null;
if (category && category.profile) { if (category && category.profile) {
catHeader = <div className="mx_GroupView_featuredRooms_category">{category.profile.name}</div>; catHeader = <div className="mx_GroupView_featuredThings_category">{category.profile.name}</div>;
} }
return <div key={categoryId}> return <div key={categoryId}>
{catHeader} {catHeader}
@ -47,6 +47,7 @@ const FeaturedRoom = React.createClass({
onClick: function(e) { onClick: function(e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation();
dis.dispatch({ dis.dispatch({
action: 'view_room', action: 'view_room',
@ -74,9 +75,54 @@ const FeaturedRoom = React.createClass({
roomNameNode = <span>{this.props.summaryInfo.profile.name}</span>; roomNameNode = <span>{this.props.summaryInfo.profile.name}</span>;
} }
return <AccessibleButton className="mx_GroupView_featuredRoom" onClick={this.onClick}> return <AccessibleButton className="mx_GroupView_featuredThing" onClick={this.onClick}>
<RoomAvatar oobData={oobData} width={64} height={64} /> <RoomAvatar oobData={oobData} width={64} height={64} />
<div className="mx_GroupView_featuredRoom_name">{roomNameNode}</div> <div className="mx_GroupView_featuredThing_name">{roomNameNode}</div>
</AccessibleButton>;
},
});
function roleUserListNode(users, roleId, role) {
const userNodes = users.map((u) => {
return <FeaturedUser key={u.user_id} summaryInfo={u} />;
});
let roleHeader = null;
if (role && role.profile) {
roleHeader = <div className="mx_GroupView_featuredThings_category">{role.profile.name}</div>;
}
return <div key={roleId}>
{roleHeader}
{userNodes}
</div>;
}
const FeaturedUser = React.createClass({
displayName: 'FeaturedUser',
props: {
summaryInfo: PropTypes.object.isRequired,
},
onClick: function(e) {
e.preventDefault();
e.stopPropagation();
dis.dispatch({
action: 'view_start_chat_or_reuse',
user_id: this.props.summaryInfo.user_id,
go_home_on_cancel: false,
});
},
render: function() {
// Add avatar once we get profile info inline in the summary response
//const BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
const permalink = 'https://matrix.to/#/' + this.props.summaryInfo.user_id;
const userNameNode = <a href={permalink} onClick={this.onClick} >{this.props.summaryInfo.user_id}</a>;
return <AccessibleButton className="mx_GroupView_featuredThing" onClick={this.onClick}>
<div className="mx_GroupView_featuredThing_name">{userNameNode}</div>
</AccessibleButton>; </AccessibleButton>;
}, },
}); });
@ -129,24 +175,11 @@ export default React.createClass({
this.setState({editing: true}); this.setState({editing: true});
}, },
render: function() { _getFeaturedRoomsNode() {
const GroupAvatar = sdk.getComponent("avatars.GroupAvatar");
const Loader = sdk.getComponent("elements.Spinner");
const TintableSvg = sdk.getComponent("elements.TintableSvg");
if (this.state.summary === null && this.state.error === null) {
return <Loader />;
} else if (this.state.editing) {
return <div />;
} else if (this.state.summary) {
const summary = this.state.summary; const summary = this.state.summary;
let description = null;
if (summary.profile && summary.profile.long_description) {
description = sanitizedHtmlNode(summary.profile.long_description);
}
let featuredRooms = null; if (summary.rooms_section.rooms.length == 0) return null;
if (summary.rooms_section.rooms.length > 0) {
const defaultCategoryRooms = []; const defaultCategoryRooms = [];
const categoryRooms = {}; const categoryRooms = {};
summary.rooms_section.rooms.forEach((r) => { summary.rooms_section.rooms.forEach((r) => {
@ -171,17 +204,73 @@ export default React.createClass({
return categoryRoomListNode(categoryRooms[catId], catId, cat); return categoryRoomListNode(categoryRooms[catId], catId, cat);
}); });
featuredRooms = <div className="mx_GroupView_featuredRooms"> return <div className="mx_GroupView_featuredThings">
<div className="mx_GroupView_featuredRooms_header"> <div className="mx_GroupView_featuredThings_header">
{_t('Featured Rooms:')} {_t('Featured Rooms:')}
</div> </div>
{defaultCategoryNode} {defaultCategoryNode}
{categoryRoomNodes} {categoryRoomNodes}
</div>; </div>;
},
_getFeaturedUsersNode() {
const summary = this.state.summary;
if (summary.users_section.users.length == 0) return null;
const noRoleUsers = [];
const roleUsers = {};
summary.users_section.users.forEach((u) => {
if (u.role_id === null) {
noRoleUsers.push(u);
} else {
let list = roleUsers[u.role_id];
if (list === undefined) {
list = [];
roleUsers[u.role_id] = list;
} }
list.push(u);
}
});
let noRoleNode = null;
if (noRoleUsers.length > 0) {
noRoleNode = roleUserListNode(noRoleUsers);
}
const roleUserNodes = Object.keys(roleUsers).map((roleId) => {
const role = summary.users_section.roles[roleId];
return roleUserListNode(roleUsers[roleId], roleId, role);
});
return <div className="mx_GroupView_featuredThings">
<div className="mx_GroupView_featuredThings_header">
{_t('Featured Users:')}
</div>
{noRoleNode}
{roleUserNodes}
</div>;
},
render: function() {
const GroupAvatar = sdk.getComponent("avatars.GroupAvatar");
const Loader = sdk.getComponent("elements.Spinner");
const TintableSvg = sdk.getComponent("elements.TintableSvg");
if (this.state.summary === null && this.state.error === null) {
return <Loader />;
} else if (this.state.editing) {
return <div />;
} else if (this.state.summary) {
const summary = this.state.summary;
let description = null;
if (summary.profile && summary.profile.long_description) {
description = sanitizedHtmlNode(summary.profile.long_description);
}
const roomBody = <div> const roomBody = <div>
<div className="mx_GroupView_groupDesc">{description}</div> <div className="mx_GroupView_groupDesc">{description}</div>
{featuredRooms} {this._getFeaturedRoomsNode()}
{this._getFeaturedUsersNode()}
</div>; </div>;
let nameNode; let nameNode;
@ -200,6 +289,7 @@ export default React.createClass({
const groupAvatarUrl = summary.profile ? summary.profile.avatar_url : null; const groupAvatarUrl = summary.profile ? summary.profile.avatar_url : null;
// settings button is display: none until settings is wired up
return ( return (
<div className="mx_GroupView"> <div className="mx_GroupView">
<div className="mx_RoomHeader"> <div className="mx_RoomHeader">
@ -217,7 +307,6 @@ export default React.createClass({
{summary.profile.short_description} {summary.profile.short_description}
</div> </div>
</div> </div>
// display: none until settings is wired up
<AccessibleButton className="mx_RoomHeader_button" onClick={this._onSettingsClick} title={_t("Settings")} style={{display: 'none'}}> <AccessibleButton className="mx_RoomHeader_button" onClick={this._onSettingsClick} title={_t("Settings")} style={{display: 'none'}}>
<TintableSvg src="img/icons-settings-room.svg" width="16" height="16"/> <TintableSvg src="img/icons-settings-room.svg" width="16" height="16"/>
</AccessibleButton> </AccessibleButton>

View File

@ -506,7 +506,7 @@ module.exports = React.createClass({
this._setMxId(payload); this._setMxId(payload);
break; break;
case 'view_start_chat_or_reuse': case 'view_start_chat_or_reuse':
this._chatCreateOrReuse(payload.user_id); this._chatCreateOrReuse(payload.user_id, payload.go_home_on_cancel);
break; break;
case 'view_create_chat': case 'view_create_chat':
this._createChat(); this._createChat();
@ -801,7 +801,9 @@ module.exports = React.createClass({
}); });
}, },
_chatCreateOrReuse: function(userId) { _chatCreateOrReuse: function(userId, go_home_on_cancel) {
if (go_home_on_cancel === undefined) go_home_on_cancel = true;
const ChatCreateOrReuseDialog = sdk.getComponent( const ChatCreateOrReuseDialog = sdk.getComponent(
'views.dialogs.ChatCreateOrReuseDialog', 'views.dialogs.ChatCreateOrReuseDialog',
); );
@ -832,7 +834,7 @@ module.exports = React.createClass({
const close = Modal.createDialog(ChatCreateOrReuseDialog, { const close = Modal.createDialog(ChatCreateOrReuseDialog, {
userId: userId, userId: userId,
onFinished: (success) => { onFinished: (success) => {
if (!success) { if (!success && go_home_on_cancel) {
// Dialog cancelled, default to home // Dialog cancelled, default to home
dis.dispatch({ action: 'view_home_page' }); dis.dispatch({ action: 'view_home_page' });
} }

View File

@ -953,5 +953,6 @@
"Join an existing group": "Join an existing group", "Join an existing group": "Join an existing group",
"To join an exisitng group you'll have to know its group identifier; this will look something like <i>+example:matrix.org</i>.": "To join an exisitng group you'll have to know its group identifier; this will look something like <i>+example:matrix.org</i>.", "To join an exisitng group you'll have to know its group identifier; this will look something like <i>+example:matrix.org</i>.": "To join an exisitng group you'll have to know its group identifier; this will look something like <i>+example:matrix.org</i>.",
"Featured Rooms:": "Featured Rooms:", "Featured Rooms:": "Featured Rooms:",
"Error whilst fetching joined groups": "Error whilst fetching joined groups" "Error whilst fetching joined groups": "Error whilst fetching joined groups",
"Featured Users:": "Featured Users:"
} }