Merge pull request #3413 from matrix-org/bwindels/room-directory-buttons
Room directory: add action buttons on room directly
This commit is contained in:
commit
1703913118
4 changed files with 104 additions and 68 deletions
|
@ -135,4 +135,13 @@ limitations under the License.
|
|||
.mx_RoomDirectory_table tr {
|
||||
padding-bottom: 10px;
|
||||
cursor: pointer;
|
||||
|
||||
.mx_RoomDirectory_roomDescription {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_join, .mx_RoomDirectory_preview {
|
||||
width: 80px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||
|
||||
.mx_AccessibleButton {
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mx_AccessibleButton:focus {
|
||||
|
|
|
@ -321,7 +321,7 @@ module.exports = createReactClass({
|
|||
}
|
||||
},
|
||||
|
||||
onJoinClick: function(alias) {
|
||||
onJoinFromSearchClick: function(alias) {
|
||||
// If we don't have a particular instance id selected, just show that rooms alias
|
||||
if (!this.state.instanceId) {
|
||||
// If the user specified an alias without a domain, add on whichever server is selected
|
||||
|
@ -363,6 +363,34 @@ module.exports = createReactClass({
|
|||
}
|
||||
},
|
||||
|
||||
onPreviewClick: function(room) {
|
||||
this.props.onFinished();
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: room.room_id,
|
||||
should_peek: true,
|
||||
});
|
||||
},
|
||||
|
||||
onViewClick: function(room) {
|
||||
this.props.onFinished();
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: room.room_id,
|
||||
should_peek: false,
|
||||
});
|
||||
},
|
||||
|
||||
onJoinClick: function(room) {
|
||||
this.props.onFinished();
|
||||
MatrixClientPeg.get().joinRoom(room.room_id);
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: room.room_id,
|
||||
joining: true,
|
||||
});
|
||||
},
|
||||
|
||||
showRoomAlias: function(alias, autoJoin=false) {
|
||||
this.showRoom(null, alias, autoJoin);
|
||||
},
|
||||
|
@ -407,74 +435,70 @@ module.exports = createReactClass({
|
|||
dis.dispatch(payload);
|
||||
},
|
||||
|
||||
getRows: function() {
|
||||
getRow(room) {
|
||||
const client = MatrixClientPeg.get();
|
||||
const clientRoom = client.getRoom(room.room_id);
|
||||
const hasJoinedRoom = clientRoom && clientRoom.getMyMembership() === "join";
|
||||
const isGuest = client.isGuest();
|
||||
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||
let previewButton;
|
||||
let joinOrViewButton;
|
||||
|
||||
if (!this.state.publicRooms) return [];
|
||||
|
||||
const rooms = this.state.publicRooms;
|
||||
const rows = [];
|
||||
const self = this;
|
||||
let guestRead; let guestJoin; let perms;
|
||||
for (let i = 0; i < rooms.length; i++) {
|
||||
guestRead = null;
|
||||
guestJoin = null;
|
||||
|
||||
if (rooms[i].world_readable) {
|
||||
guestRead = (
|
||||
<div className="mx_RoomDirectory_perm">{ _t('World readable') }</div>
|
||||
);
|
||||
}
|
||||
if (rooms[i].guest_can_join) {
|
||||
guestJoin = (
|
||||
<div className="mx_RoomDirectory_perm">{ _t('Guests can join') }</div>
|
||||
);
|
||||
}
|
||||
|
||||
perms = null;
|
||||
if (guestRead || guestJoin) {
|
||||
perms = <div className="mx_RoomDirectory_perms">{guestRead}{guestJoin}</div>;
|
||||
}
|
||||
|
||||
let name = rooms[i].name || get_display_alias_for_room(rooms[i]) || _t('Unnamed room');
|
||||
if (name.length > MAX_NAME_LENGTH) {
|
||||
name = `${name.substring(0, MAX_NAME_LENGTH)}...`;
|
||||
}
|
||||
|
||||
let topic = rooms[i].topic || '';
|
||||
if (topic.length > MAX_TOPIC_LENGTH) {
|
||||
topic = `${topic.substring(0, MAX_TOPIC_LENGTH)}...`;
|
||||
}
|
||||
topic = linkifyAndSanitizeHtml(topic);
|
||||
|
||||
rows.push(
|
||||
<tr key={ rooms[i].room_id }
|
||||
onClick={self.onRoomClicked.bind(self, rooms[i])}
|
||||
// cancel onMouseDown otherwise shift-clicking highlights text
|
||||
onMouseDown={(ev) => {ev.preventDefault();}}
|
||||
>
|
||||
<td className="mx_RoomDirectory_roomAvatar">
|
||||
<BaseAvatar width={24} height={24} resizeMethod='crop'
|
||||
name={ name } idName={ name }
|
||||
url={ ContentRepo.getHttpUriForMxc(
|
||||
MatrixClientPeg.get().getHomeserverUrl(),
|
||||
rooms[i].avatar_url, 24, 24, "crop") } />
|
||||
</td>
|
||||
<td className="mx_RoomDirectory_roomDescription">
|
||||
<div className="mx_RoomDirectory_name">{ name }</div>
|
||||
{ perms }
|
||||
<div className="mx_RoomDirectory_topic"
|
||||
onClick={ function(e) { e.stopPropagation(); } }
|
||||
dangerouslySetInnerHTML={{ __html: topic }} />
|
||||
<div className="mx_RoomDirectory_alias">{ get_display_alias_for_room(rooms[i]) }</div>
|
||||
</td>
|
||||
<td className="mx_RoomDirectory_roomMemberCount">
|
||||
{ rooms[i].num_joined_members }
|
||||
</td>
|
||||
</tr>,
|
||||
if (room.world_readable && !hasJoinedRoom) {
|
||||
previewButton = (
|
||||
<AccessibleButton kind="secondary" onClick={() => this.onPreviewClick(room)}>{_t("Preview")}</AccessibleButton>
|
||||
);
|
||||
}
|
||||
return rows;
|
||||
if (hasJoinedRoom) {
|
||||
joinOrViewButton = (
|
||||
<AccessibleButton kind="secondary" onClick={() => this.onViewClick(room)}>{_t("View")}</AccessibleButton>
|
||||
);
|
||||
} else if (!isGuest || room.guest_can_join) {
|
||||
joinOrViewButton = (
|
||||
<AccessibleButton kind="primary" onClick={() => this.onJoinClick(room)}>{_t("Join")}</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
||||
let name = room.name || get_display_alias_for_room(room) || _t('Unnamed room');
|
||||
if (name.length > MAX_NAME_LENGTH) {
|
||||
name = `${name.substring(0, MAX_NAME_LENGTH)}...`;
|
||||
}
|
||||
|
||||
let topic = room.topic || '';
|
||||
if (topic.length > MAX_TOPIC_LENGTH) {
|
||||
topic = `${topic.substring(0, MAX_TOPIC_LENGTH)}...`;
|
||||
}
|
||||
topic = linkifyAndSanitizeHtml(topic);
|
||||
const avatarUrl = ContentRepo.getHttpUriForMxc(
|
||||
MatrixClientPeg.get().getHomeserverUrl(),
|
||||
room.avatar_url, 24, 24, "crop",
|
||||
);
|
||||
return (
|
||||
<tr key={ room.room_id }
|
||||
onClick={() => this.onRoomClicked(room)}
|
||||
// cancel onMouseDown otherwise shift-clicking highlights text
|
||||
onMouseDown={(ev) => {ev.preventDefault();}}
|
||||
>
|
||||
<td className="mx_RoomDirectory_roomAvatar">
|
||||
<BaseAvatar width={24} height={24} resizeMethod='crop'
|
||||
name={ name } idName={ name }
|
||||
url={ avatarUrl } />
|
||||
</td>
|
||||
<td className="mx_RoomDirectory_roomDescription">
|
||||
<div className="mx_RoomDirectory_name">{ name }</div>
|
||||
<div className="mx_RoomDirectory_topic"
|
||||
onClick={ (ev) => { ev.stopPropagation(); } }
|
||||
dangerouslySetInnerHTML={{ __html: topic }} />
|
||||
<div className="mx_RoomDirectory_alias">{ get_display_alias_for_room(room) }</div>
|
||||
</td>
|
||||
<td className="mx_RoomDirectory_roomMemberCount">
|
||||
{ room.num_joined_members }
|
||||
</td>
|
||||
<td className="mx_RoomDirectory_preview">{previewButton}</td>
|
||||
<td className="mx_RoomDirectory_join">{joinOrViewButton}</td>
|
||||
</tr>
|
||||
);
|
||||
},
|
||||
|
||||
collectScrollPanel: function(element) {
|
||||
|
@ -528,7 +552,7 @@ module.exports = createReactClass({
|
|||
} else if (this.state.protocolsLoading || this.state.loading) {
|
||||
content = <Loader />;
|
||||
} else {
|
||||
const rows = this.getRows();
|
||||
const rows = (this.state.publicRooms || []).map(room => this.getRow(room));
|
||||
// we still show the scrollpanel, at least for now, because
|
||||
// otherwise we don't fetch more because we don't get a fill
|
||||
// request from the scrollpanel because there isn't one
|
||||
|
@ -538,7 +562,7 @@ module.exports = createReactClass({
|
|||
} else {
|
||||
scrollpanel_content = <table ref="directory_table" className="mx_RoomDirectory_table">
|
||||
<tbody>
|
||||
{ this.getRows() }
|
||||
{ rows }
|
||||
</tbody>
|
||||
</table>;
|
||||
}
|
||||
|
@ -590,7 +614,7 @@ module.exports = createReactClass({
|
|||
listHeader = <div className="mx_RoomDirectory_listheader">
|
||||
<DirectorySearchBox
|
||||
className="mx_RoomDirectory_searchbox"
|
||||
onChange={this.onFilterChange} onClear={this.onFilterClear} onJoinClick={this.onJoinClick}
|
||||
onChange={this.onFilterChange} onClear={this.onFilterClear} onJoinClick={this.onJoinFromSearchClick}
|
||||
placeholder={placeholder} showJoinButton={showJoinButton}
|
||||
/>
|
||||
<NetworkDropdown config={this.props.config} protocols={this.protocols} onOptionChange={this.onOptionChange} />
|
||||
|
|
|
@ -1598,6 +1598,8 @@
|
|||
"Couldn't find a matching Matrix room": "Couldn't find a matching Matrix room",
|
||||
"Fetching third party location failed": "Fetching third party location failed",
|
||||
"Unable to look up room ID from server": "Unable to look up room ID from server",
|
||||
"Preview": "Preview",
|
||||
"View": "View",
|
||||
"Search for a room": "Search for a room",
|
||||
"Search for a room like #example": "Search for a room like #example",
|
||||
"Message not sent due to unknown devices being present": "Message not sent due to unknown devices being present",
|
||||
|
|
Loading…
Reference in a new issue