diff --git a/__tests__/__snapshots__/Storyshots.test.js.snap b/__tests__/__snapshots__/Storyshots.test.js.snap index e95058caa..a5c96752f 100644 --- a/__tests__/__snapshots__/Storyshots.test.js.snap +++ b/__tests__/__snapshots__/Storyshots.test.js.snap @@ -71,51 +71,69 @@ exports[`Storyshots Message list 1`] = ` } > - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + - + > + + { numberOfLines={props.tmid ? 1 : 0} getCustomEmoji={props.getCustomEmoji} useMarkdown={props.useMarkdown} + navToRoomInfo={props.navToRoomInfo} /> ); } @@ -50,6 +51,7 @@ Content.propTypes = { user: PropTypes.object, mentions: PropTypes.oneOfType([PropTypes.array, PropTypes.object]), channels: PropTypes.oneOfType([PropTypes.array, PropTypes.object]), + navToRoomInfo: PropTypes.func, getCustomEmoji: PropTypes.func }; Content.displayName = 'MessageContent'; diff --git a/app/containers/message/Markdown.js b/app/containers/message/Markdown.js index 01d182b58..b7622b0b2 100644 --- a/app/containers/message/Markdown.js +++ b/app/containers/message/Markdown.js @@ -48,7 +48,7 @@ const emojiCount = (str) => { }; const Markdown = React.memo(({ - msg, style, rules, baseUrl, username, isEdited, numberOfLines, mentions, channels, getCustomEmoji, useMarkdown = true + msg, style, rules, baseUrl, username, isEdited, numberOfLines, mentions, channels, getCustomEmoji, useMarkdown = true, navToRoomInfo }) => { if (!msg) { return null; @@ -92,8 +92,17 @@ const Markdown = React.memo(({ }; } if (mentions && mentions.length && mentions.findIndex(mention => mention.username === content) !== -1) { + const index = mentions.findIndex(mention => mention.username === content); + const navParam = { + t: 'd', + rid: mentions[index]._id + }; return ( - + navToRoomInfo(navParam)} + >  {content}  ); @@ -103,8 +112,17 @@ const Markdown = React.memo(({ hashtag: (node) => { const { content, key } = node; if (channels && channels.length && channels.findIndex(channel => channel.name === content) !== -1) { + const index = channels.findIndex(channel => channel.name === content); + const navParam = { + t: 'c', + rid: channels[index]._id + }; return ( - + navToRoomInfo(navParam)} + >  #{content}  ); @@ -161,7 +179,8 @@ Markdown.propTypes = { useMarkdown: PropTypes.bool, mentions: PropTypes.oneOfType([PropTypes.array, PropTypes.object]), channels: PropTypes.oneOfType([PropTypes.array, PropTypes.object]), - getCustomEmoji: PropTypes.func + getCustomEmoji: PropTypes.func, + navToRoomInfo: PropTypes.func }; Markdown.displayName = 'MessageMarkdown'; diff --git a/app/containers/message/MessageAvatar.js b/app/containers/message/MessageAvatar.js index eb1dc6719..f5d6b1d85 100644 --- a/app/containers/message/MessageAvatar.js +++ b/app/containers/message/MessageAvatar.js @@ -1,24 +1,34 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { TouchableOpacity } from 'react-native'; import Avatar from '../Avatar'; import styles from './styles'; const MessageAvatar = React.memo(({ - isHeader, avatar, author, baseUrl, user, small + isHeader, avatar, author, baseUrl, user, small, navToRoomInfo }) => { if (isHeader) { + const navParam = { + t: 'd', + rid: author._id + }; return ( - + navToRoomInfo(navParam)} + disabled={author._id === user.id} + > + + ); } return null; @@ -30,7 +40,8 @@ MessageAvatar.propTypes = { author: PropTypes.obj, baseUrl: PropTypes.string, user: PropTypes.obj, - small: PropTypes.bool + small: PropTypes.bool, + navToRoomInfo: PropTypes.func }; MessageAvatar.displayName = 'MessageAvatar'; diff --git a/app/containers/message/index.js b/app/containers/message/index.js index 7adf26dc8..605859a96 100644 --- a/app/containers/message/index.js +++ b/app/containers/message/index.js @@ -39,7 +39,8 @@ export default class MessageContainer extends React.Component { toggleReactionPicker: PropTypes.func, fetchThreadName: PropTypes.func, onOpenFileModal: PropTypes.func, - onReactionLongPress: PropTypes.func + onReactionLongPress: PropTypes.func, + navToRoomInfo: PropTypes.func } static defaultProps = { @@ -199,7 +200,7 @@ export default class MessageContainer extends React.Component { render() { const { - item, user, style, archived, baseUrl, useRealName, broadcast, fetchThreadName, customThreadTimeFormat, onOpenFileModal, timeFormat, useMarkdown, isReadReceiptEnabled, autoTranslateRoom, autoTranslateLanguage + item, user, style, archived, baseUrl, useRealName, broadcast, fetchThreadName, customThreadTimeFormat, onOpenFileModal, timeFormat, useMarkdown, isReadReceiptEnabled, autoTranslateRoom, autoTranslateLanguage, navToRoomInfo } = this.props; const { _id, msg, ts, attachments, urls, reactions, t, avatar, u, alias, editedBy, role, drid, dcount, dlm, tmid, tcount, tlm, tmsg, mentions, channels, unread, autoTranslate: autoTranslateMessage @@ -263,6 +264,7 @@ export default class MessageContainer extends React.Component { onDiscussionPress={this.onDiscussionPress} onOpenFileModal={onOpenFileModal} getCustomEmoji={getCustomEmoji} + navToRoomInfo={navToRoomInfo} /> ); } diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index 3955f9665..b4723b329 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -640,6 +640,10 @@ const RocketChat = { // RC 0.48.0 return this.sdk.get('users.info', { userId }); }, + getRoomInfo(roomId) { + // RC 0.72.0 + return this.sdk.get('rooms.info', { roomId }); + }, getRoomMemberId(rid, currentUserId) { if (rid === `${ currentUserId }${ currentUserId }`) { return currentUserId; diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index a1603f069..5b4fd589a 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -184,7 +184,7 @@ class RoomActionsView extends React.Component { name: I18n.t('Room_Info'), route: 'RoomInfoView', // forward room only if room isn't joined - params: { rid, t, room: joined ? null : room }, + params: { rid, t }, testID: 'room-actions-info' }], renderItem: this.renderRoomInfo diff --git a/app/views/RoomInfoView/index.js b/app/views/RoomInfoView/index.js index 6c75f10b6..f2bcd03bc 100644 --- a/app/views/RoomInfoView/index.js +++ b/app/views/RoomInfoView/index.js @@ -9,7 +9,7 @@ import Status from '../../containers/Status'; import Avatar from '../../containers/Avatar'; import styles from './styles'; import sharedStyles from '../Styles'; -import database, { safeAddListener } from '../../lib/realm'; +import database from '../../lib/realm'; import RocketChat from '../../lib/rocketchat'; import RoomTypeIcon from '../../containers/RoomTypeIcon'; import I18n from '../../i18n'; @@ -20,8 +20,8 @@ import log from '../../utils/log'; const PERMISSION_EDIT_ROOM = 'edit-room'; const camelize = str => str.replace(/^(.)/, (match, chr) => chr.toUpperCase()); -const getRoomTitle = room => (room.t === 'd' - ? {room.fname} +const getRoomTitle = (room, type, name) => (type === 'd' + ? {name} : ( @@ -59,28 +59,18 @@ class RoomInfoView extends React.Component { constructor(props) { super(props); this.rid = props.navigation.getParam('rid'); - const room = props.navigation.getParam('room'); this.t = props.navigation.getParam('t'); - this.rooms = database.objects('subscriptions').filtered('rid = $0', this.rid); this.roles = database.objects('roles'); this.sub = { unsubscribe: () => {} }; this.state = { - room: this.rooms[0] || room || {}, + room: {}, roomUser: {} }; } async componentDidMount() { - safeAddListener(this.rooms, this.updateRoom); - const { room } = this.state; - const permissions = RocketChat.hasPermission([PERMISSION_EDIT_ROOM], room.rid); - if (permissions[PERMISSION_EDIT_ROOM] && !room.prid) { - const { navigation } = this.props; - navigation.setParams({ showEdit: true }); - } - if (this.t === 'd') { const { user } = this.props; const roomUserId = RocketChat.getRoomMemberId(this.rid, user.id); @@ -92,11 +82,30 @@ class RoomInfoView extends React.Component { } catch (error) { log('err_get_user_info', error); } + return; + } + const rooms = database.objects('subscriptions').filtered('rid = $0', this.rid); + let room = {}; + if (rooms.length > 0) { + this.setState({ room: rooms[0] }); + [room] = rooms; + } else { + try { + const result = await RocketChat.getRoomInfo(this.rid); + if (result.success) { + // eslint-disable-next-line prefer-destructuring + room = result.room; + this.setState({ room }); + } + } catch (error) { + log('err_get_room_info', error); + } + } + const permissions = RocketChat.hasPermission([PERMISSION_EDIT_ROOM], room.rid); + if (permissions[PERMISSION_EDIT_ROOM] && !room.prid) { + const { navigation } = this.props; + navigation.setParams({ showEdit: true }); } - } - - componentWillUnmount() { - this.rooms.removeAllListeners(); } getRoleDescription = (id) => { @@ -107,10 +116,7 @@ class RoomInfoView extends React.Component { return null; } - isDirect = () => { - const { room: { t } } = this.state; - return t === 'd'; - } + isDirect = () => this.t === 'd' updateRoom = () => { if (this.rooms.length > 0) { @@ -181,15 +187,15 @@ class RoomInfoView extends React.Component { return ( - {room.t === 'd' && roomUser._id ? : null} + {this.t === 'd' && roomUser._id ? : null} ); } @@ -231,6 +237,29 @@ class RoomInfoView extends React.Component { return null; } + renderChannel = () => { + const { room } = this.state; + return ( + + {this.renderItem('description', room)} + {this.renderItem('topic', room)} + {this.renderItem('announcement', room)} + {room.broadcast ? this.renderBroadcast() : null} + + ); + } + + renderDirect = () => { + const { roomUser } = this.state; + return ( + + {this.renderRoles()} + {this.renderTimezone()} + {this.renderCustomFields(roomUser._id)} + + ); + } + render() { const { room, roomUser } = this.state; if (!room) { @@ -242,15 +271,9 @@ class RoomInfoView extends React.Component { {this.renderAvatar(room, roomUser)} - { getRoomTitle(room) } + { getRoomTitle(room, this.t, roomUser && roomUser.name) } - {!this.isDirect() ? this.renderItem('description', room) : null} - {!this.isDirect() ? this.renderItem('topic', room) : null} - {!this.isDirect() ? this.renderItem('announcement', room) : null} - {this.isDirect() ? this.renderRoles() : null} - {this.isDirect() ? this.renderTimezone() : null} - {this.isDirect() ? this.renderCustomFields(roomUser._id) : null} - {room.broadcast ? this.renderBroadcast() : null} + {this.isDirect() ? this.renderDirect() : this.renderChannel()} ); diff --git a/app/views/RoomView/index.js b/app/views/RoomView/index.js index 017d0f643..02d4fa1fb 100644 --- a/app/views/RoomView/index.js +++ b/app/views/RoomView/index.js @@ -452,6 +452,14 @@ class RoomView extends React.Component { } } + navToRoomInfo = (navParam) => { + const { navigation, user } = this.props; + if (navParam.rid === user.id) { + return; + } + navigation.navigate('RoomInfoView', navParam); + } + renderItem = (item, previousItem) => { const { room, lastOpen, canAutoTranslate } = this.state; const { @@ -500,6 +508,7 @@ class RoomView extends React.Component { isReadReceiptEnabled={Message_Read_Receipt_Enabled} autoTranslateRoom={canAutoTranslate && room.autoTranslate} autoTranslateLanguage={room.autoTranslateLanguage} + navToRoomInfo={this.navToRoomInfo} /> ); diff --git a/yarn.lock b/yarn.lock index 6aaeb0e93..8e8273f0d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8754,7 +8754,7 @@ pad-component@0.0.1: resolved "https://registry.yarnpkg.com/pad-component/-/pad-component-0.0.1.tgz#ad1f22ce1bf0fdc0d6ddd908af17f351a404b8ac" integrity sha1-rR8izhvw/cDW3dkIrxfzUaQEuKw= -"paho-mqtt@github:eclipse/paho.mqtt.javascript#master": +paho-mqtt@eclipse/paho.mqtt.javascript#master: version "1.1.0" resolved "https://codeload.github.com/eclipse/paho.mqtt.javascript/tar.gz/f5859463aba9a9b7c19f99ab7c4849a723f8d832"