From f0752572a76da82f73a1cfc6e31babbcc11c8011 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 19 Nov 2017 12:49:26 +0000 Subject: [PATCH] make RoomDetailRow reusable for the Room Directory Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/RoomDetailList.js | 109 +++-------------- src/components/views/rooms/RoomDetailRow.js | 119 +++++++++++++++++++ 2 files changed, 133 insertions(+), 95 deletions(-) create mode 100644 src/components/views/rooms/RoomDetailRow.js diff --git a/src/components/views/rooms/RoomDetailList.js b/src/components/views/rooms/RoomDetailList.js index 27972af484..11fad41b39 100644 --- a/src/components/views/rooms/RoomDetailList.js +++ b/src/components/views/rooms/RoomDetailList.js @@ -18,121 +18,40 @@ import sdk from '../../../index'; import dis from '../../../dispatcher'; import React from 'react'; import { _t } from '../../../languageHandler'; -import linkifyString from 'linkifyjs/string'; -import sanitizeHtml from 'sanitize-html'; -import { ContentRepo } from 'matrix-js-sdk'; -import MatrixClientPeg from '../../../MatrixClientPeg'; import PropTypes from 'prop-types'; import classNames from 'classnames'; -function getDisplayAliasForRoom(room) { - return room.canonicalAlias || (room.aliases ? room.aliases[0] : ""); -} - -const RoomDetailRow = React.createClass({ - propTypes: { - room: PropTypes.shape({ - name: PropTypes.string, - topic: PropTypes.string, - roomId: PropTypes.string, - avatarUrl: PropTypes.string, - numJoinedMembers: PropTypes.number, - canonicalAlias: PropTypes.string, - aliases: PropTypes.arrayOf(PropTypes.string), - - worldReadable: PropTypes.bool, - guestCanJoin: PropTypes.bool, - }), - }, - - onClick: function(ev) { - ev.preventDefault(); - dis.dispatch({ - action: 'view_room', - room_id: this.props.room.roomId, - room_alias: this.props.room.canonicalAlias || (this.props.room.aliases || [])[0], - }); - }, - - onTopicClick: function(ev) { - // When clicking a link in the topic, prevent the event being propagated - // to `onClick`. - ev.stopPropagation(); - }, - - render: function() { - const BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); - - const room = this.props.room; - const name = room.name || getDisplayAliasForRoom(room) || _t('Unnamed room'); - const topic = linkifyString(sanitizeHtml(room.topic || '')); - - const guestRead = room.worldReadable ? ( -
{ _t('World readable') }
- ) :
; - const guestJoin = room.guestCanJoin ? ( -
{ _t('Guests can join') }
- ) :
; - - const perms = (guestRead || guestJoin) ? (
- { guestRead } - { guestJoin } -
) :
; - - return - - - - -
{ name }
  - { perms } -
-
{ getDisplayAliasForRoom(room) }
- - - { room.numJoinedMembers } - - ; - }, -}); +import {roomShape} from './RoomDetailRow'; export default React.createClass({ displayName: 'RoomDetailList', propTypes: { - rooms: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.string, - topic: PropTypes.string, - roomId: PropTypes.string, - avatarUrl: PropTypes.string, - numJoinedMembers: PropTypes.number, - canonicalAlias: PropTypes.string, - aliases: PropTypes.arrayOf(PropTypes.string), - - worldReadable: PropTypes.bool, - guestCanJoin: PropTypes.bool, - })), - + rooms: PropTypes.arrayOf(roomShape), className: PropTypes.string, }, getRows: function() { if (!this.props.rooms) return []; + + const RoomDetailRow = sdk.getComponent('rooms.RoomDetailRow'); return this.props.rooms.map((room, index) => { - return ; + return ; + }); + }, + + onDetailsClick: function(ev, room) { + dis.dispatch({ + action: 'view_room', + room_id: room.roomId, + room_alias: room.canonicalAlias || (room.aliases || [])[0], }); }, render() { const rows = this.getRows(); let rooms; - if (rows.length == 0) { + if (rows.length === 0) { rooms = { _t('No rooms to show') }; } else { rooms = diff --git a/src/components/views/rooms/RoomDetailRow.js b/src/components/views/rooms/RoomDetailRow.js new file mode 100644 index 0000000000..fbb9db4505 --- /dev/null +++ b/src/components/views/rooms/RoomDetailRow.js @@ -0,0 +1,119 @@ +/* +Copyright 2017 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import sdk from '../../../index'; +import dis from '../../../dispatcher'; +import React from 'react'; +import { _t } from '../../../languageHandler'; +import linkifyElement from 'linkifyjs/element'; +import linkifyMatrix from '../../../linkify-matrix'; +import { ContentRepo } from 'matrix-js-sdk'; +import MatrixClientPeg from '../../../MatrixClientPeg'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; + +function getDisplayAliasForRoom(room) { + return room.canonicalAlias || (room.aliases ? room.aliases[0] : ""); +} + +export const roomShape = PropTypes.shape({ + name: PropTypes.string, + topic: PropTypes.string, + roomId: PropTypes.string, + avatarUrl: PropTypes.string, + numJoinedMembers: PropTypes.number, + canonicalAlias: PropTypes.string, + aliases: PropTypes.arrayOf(PropTypes.string), + + worldReadable: PropTypes.bool, + guestCanJoin: PropTypes.bool, +}); + +export default React.createClass({ + propTypes: { + room: roomShape, + // passes ev, room as args + onClick: PropTypes.func, + onMouseDown: PropTypes.func, + }, + + _linkifyTopic: function() { + if (this.refs.topic) { + linkifyElement(this.refs.topic, linkifyMatrix.options); + } + }, + + componentDidMount: function() { + this._linkifyTopic(); + }, + + componentDidUpdate: function() { + this._linkifyTopic(); + }, + + onClick: function(ev) { + ev.preventDefault(); + if (this.props.onClick) { + this.props.onClick(ev, this.props.room); + } + }, + + onTopicClick: function(ev) { + // When clicking a link in the topic, prevent the event being propagated + // to `onClick`. + ev.stopPropagation(); + }, + + render: function() { + const BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); + + const room = this.props.room; + const name = room.name || getDisplayAliasForRoom(room) || _t('Unnamed room'); + + const guestRead = room.worldReadable ? ( +
{ _t('World readable') }
+ ) :
; + const guestJoin = room.guestCanJoin ? ( +
{ _t('Guests can join') }
+ ) :
; + + const perms = (guestRead || guestJoin) ? (
+ { guestRead }  + { guestJoin } +
) :
; + + return
+ + + + ; + }, +});
+ + +
{ name }
  + { perms } +
+ { room.topic } +
+
{ getDisplayAliasForRoom(room) }
+
+ { room.numJoinedMembers } +