Improve the Group View page

Show the rooms in the group in thir various categories, etc
This commit is contained in:
David Baker 2017-07-06 19:13:14 +01:00
parent 3b06db0725
commit fa37d03db6
3 changed files with 124 additions and 4 deletions

View file

@ -18,10 +18,67 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import MatrixClientPeg from '../../MatrixClientPeg'; import MatrixClientPeg from '../../MatrixClientPeg';
import sdk from '../../index'; import sdk from '../../index';
import dis from '../../dispatcher';
import { sanitizedHtmlNode } from '../../HtmlUtils'; import { sanitizedHtmlNode } from '../../HtmlUtils';
import { _t } from '../../languageHandler'; import { _t } from '../../languageHandler';
import AccessibleButton from '../views/elements/AccessibleButton';
function categoryRoomListNode(rooms, categoryId, category) {
const roomNodes = rooms.map((r) => {
return <FeaturedRoom key={r.room_id} summaryInfo={r} />;
});
let catHeader = null;
if (category && category.profile) catHeader = <div className="mx_GroupView_featuredRooms_category">{category.profile.name}</div>
return <div key={categoryId}>
{catHeader}
{roomNodes}
</div>;
}
const FeaturedRoom = React.createClass({
displayName: 'FeaturedRoom',
props: {
summaryInfo: PropTypes.object.isRequired,
},
onClick: function(e) {
e.preventDefault();
dis.dispatch({
action: 'view_room',
room_alias: this.props.summaryInfo.profile.canonical_alias,
room_id: this.props.summaryInfo.room_id,
});
},
render: function() {
const RoomAvatar = sdk.getComponent("avatars.RoomAvatar");
const oobData = {
roomId: this.props.summaryInfo.room_id,
avatarUrl: this.props.summaryInfo.profile.avatar_url,
name: this.props.summaryInfo.profile.name,
};
let permalink = null;
if (this.props.summaryInfo.profile && this.props.summaryInfo.profile.canonical_alias) {
permalink = 'https://matrix.to/#/' + this.props.summaryInfo.profile.canonical_alias;
}
let roomNameNode = null;
if (permalink) {
roomNameNode = <a href={permalink} onClick={this.onClick} >{this.props.summaryInfo.profile.name}</a>;
} else {
roomNameNode = <span>{this.props.summaryInfo.profile.name}</span>;
}
return <AccessibleButton className="mx_GroupView_featuredRoom" onClick={this.onClick}>
<RoomAvatar oobData={oobData} width={64} height={64} />
<div className="mx_GroupView_featuredRoom_name">{roomNameNode}</div>
</AccessibleButton>;
}
});
export default React.createClass({ export default React.createClass({
displayName: 'GroupView', displayName: 'GroupView',
@ -33,6 +90,7 @@ export default React.createClass({
return { return {
summary: null, summary: null,
error: null, error: null,
editing: false,
}; };
}, },
@ -64,12 +122,19 @@ export default React.createClass({
}); });
}, },
_onSettingsClick: function() {
this.setState({editing: true});
},
render: function() { render: function() {
const GroupAvatar = sdk.getComponent("avatars.GroupAvatar"); const GroupAvatar = sdk.getComponent("avatars.GroupAvatar");
const Loader = sdk.getComponent("elements.Spinner"); const Loader = sdk.getComponent("elements.Spinner");
const TintableSvg = sdk.getComponent("elements.TintableSvg");
if (this.state.summary === null && this.state.error === null) { if (this.state.summary === null && this.state.error === null) {
return <Loader />; return <Loader />;
} else if (this.state.editing) {
return <div />;
} else if (this.state.summary) { } else if (this.state.summary) {
const summary = this.state.summary; const summary = this.state.summary;
let description = null; let description = null;
@ -77,6 +142,50 @@ export default React.createClass({
description = sanitizedHtmlNode(summary.profile.long_description); description = sanitizedHtmlNode(summary.profile.long_description);
} }
let featuredRooms = null;
if (summary.rooms_section.rooms.length > 0) {
let defaultCategoryRooms = [];
let categoryRooms = {};
summary.rooms_section.rooms.forEach((r) => {
if (r.category_id === null) {
defaultCategoryRooms.push(r);
} else {
let list = categoryRooms[r.category_id];
if (list === undefined) {
list = [];
categoryRooms[r.category_id] = list;
}
list.push(r);
}
});
/*[defaultCategoryRooms, ...Object.values(categoryRooms)].forEach((roomList) => {
roomList.sort((r1, r2) => {
return r1.order - r2.order;
});
});*/
let defaultCategoryNode = null;
if (defaultCategoryRooms.length > 0) {
defaultCategoryNode = categoryRoomListNode(defaultCategoryRooms);
}
const categoryRoomNodes = Object.keys(categoryRooms).map((catId) => {
const cat = summary.rooms_section.categories[catId];
return categoryRoomListNode(categoryRooms[catId], catId, cat);
});
featuredRooms = <div className="mx_GroupView_featuredRooms">
<div className="mx_GroupView_featuredRooms_header">
{_t('Featured Rooms:')}
</div>
{defaultCategoryNode}
{categoryRoomNodes}
</div>;
}
const roomBody = <div>
<div className="mx_GroupView_groupDesc">{description}</div>
{featuredRooms}
</div>;
let nameNode; let nameNode;
if (summary.profile.name) { if (summary.profile.name) {
nameNode = <div className="mx_RoomHeader_name"> nameNode = <div className="mx_RoomHeader_name">
@ -108,9 +217,12 @@ export default React.createClass({
{summary.profile.short_description} {summary.profile.short_description}
</div> </div>
</div> </div>
<AccessibleButton className="mx_RoomHeader_button" onClick={this._onSettingsClick} title={_t("Settings")}>
<TintableSvg src="img/icons-settings-room.svg" width="16" height="16"/>
</AccessibleButton>
</div> </div>
</div> </div>
{description} {roomBody}
</div> </div>
); );
} else if (this.state.error) { } else if (this.state.error) {

View file

@ -126,9 +126,16 @@ module.exports = React.createClass({
}, },
getFallbackAvatar: function(props) { getFallbackAvatar: function(props) {
if (!this.props.room) return null; let roomId = null;
if (props.oobData && props.oobData.roomId) {
roomId = this.props.oobData.roomId;
} else if (props.room) {
roomId = props.room.roomId;
} else {
return null;
}
return Avatar.defaultAvatarUrlForString(props.room.roomId); return Avatar.defaultAvatarUrlForString(roomId);
}, },
render: function() { render: function() {

View file

@ -946,5 +946,6 @@
"You are a member of these groups": "You are a member of these groups", "You are a member of these groups": "You are a member of these groups",
"Create a group to represent your community! Define a set of rooms and your own custom homepage to mark out your space in the Matrix universe.": "Create a group to represent your community! Define a set of rooms and your own custom homepage to mark out your space in the Matrix universe.", "Create a group to represent your community! Define a set of rooms and your own custom homepage to mark out your space in the Matrix universe.": "Create a group to represent your community! Define a set of rooms and your own custom homepage to mark out your space in the Matrix universe.",
"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:"
} }