diff --git a/src/component-index.js b/src/component-index.js index c705150e12..2644f1a379 100644 --- a/src/component-index.js +++ b/src/component-index.js @@ -75,6 +75,8 @@ import views$create_room$RoomAlias from './components/views/create_room/RoomAlia views$create_room$RoomAlias && (module.exports.components['views.create_room.RoomAlias'] = views$create_room$RoomAlias); import views$dialogs$BaseDialog from './components/views/dialogs/BaseDialog'; views$dialogs$BaseDialog && (module.exports.components['views.dialogs.BaseDialog'] = views$dialogs$BaseDialog); +import views$dialogs$ChatCreateOrReuseDialog from './components/views/dialogs/ChatCreateOrReuseDialog'; +views$dialogs$ChatCreateOrReuseDialog && (module.exports.components['views.dialogs.ChatCreateOrReuseDialog'] = views$dialogs$ChatCreateOrReuseDialog); import views$dialogs$ChatInviteDialog from './components/views/dialogs/ChatInviteDialog'; views$dialogs$ChatInviteDialog && (module.exports.components['views.dialogs.ChatInviteDialog'] = views$dialogs$ChatInviteDialog); import views$dialogs$ConfirmUserActionDialog from './components/views/dialogs/ConfirmUserActionDialog'; diff --git a/src/components/views/dialogs/ChatCreateOrReuseDialog.js b/src/components/views/dialogs/ChatCreateOrReuseDialog.js new file mode 100644 index 0000000000..241c7755d2 --- /dev/null +++ b/src/components/views/dialogs/ChatCreateOrReuseDialog.js @@ -0,0 +1,102 @@ +/* +Copyright 2017 Vector Creations 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 React from 'react'; +import sdk from '../../../index'; +import dis from '../../../dispatcher'; +import MatrixClientPeg from '../../../MatrixClientPeg'; +import DMRoomMap from '../../../utils/DMRoomMap'; +import AccessibleButton from '../elements/AccessibleButton'; +import Unread from '../../../Unread'; +import classNames from 'classnames'; +import createRoom from '../../../createRoom'; + +export default class CreateOrReuseChatDialog extends React.Component { + + constructor (props) { + super(props); + this._onNewDMClick = this._onNewDMClick.bind(this); + } + + _onNewDMClick () { + createRoom({dmUserId: this.props.userId}); + this.props.onFinished(true); + } + + render () { + const client = MatrixClientPeg.get(); + + const dmRoomMap = new DMRoomMap(client); + const dmRooms = dmRoomMap.getDMRoomsForUserId(this.props.userId); + + const RoomTile = sdk.getComponent("rooms.RoomTile"); + + const tiles = []; + for (const roomId of dmRooms) { + const room = client.getRoom(roomId); + if (room) { + const me = room.getMember(client.credentials.userId); + const highlight = ( + room.getUnreadNotificationCount('highlight') > 0 || + me.membership == "invite" + ); + tiles.push( + this.props.onFinished(true)} + /> + ); + } + } + + const labelClasses = classNames({ + mx_MemberInfo_createRoom_label: true, + mx_RoomTile_name: true, + }); + const startNewChat = +
+ +
+
Start new chat
+
; + + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + return ( + { + this.props.onFinished(false) + }} + title='Create a new chat or reuse an existing one' + > +

Direct chats

+ {tiles} + {startNewChat} +
+ ); + } +} + +CreateOrReuseChatDialog.propTyps = { + userId: React.PropTypes.string.isRequired, + onFinished: React.PropTypes.func.isRequired, +}; diff --git a/src/components/views/dialogs/ChatInviteDialog.js b/src/components/views/dialogs/ChatInviteDialog.js index ca3b07aa00..db50a12904 100644 --- a/src/components/views/dialogs/ChatInviteDialog.js +++ b/src/components/views/dialogs/ChatInviteDialog.js @@ -97,18 +97,27 @@ module.exports = React.createClass({ if (inviteList === null) return; } + const addrTexts = inviteList.map(addr => addr.address); if (inviteList.length > 0) { - if (this._isDmChat(inviteList)) { + if (this._isDmChat(addrTexts)) { + const userId = inviteList[0].address; // Direct Message chat - var room = this._getDirectMessageRoom(inviteList[0]); - if (room) { - // A Direct Message room already exists for this user and you - // so go straight to that room - dis.dispatch({ - action: 'view_room', - room_id: room.roomId, + const rooms = this._getDirectMessageRooms(userId); + if (rooms.length > 0) { + // A Direct Message room already exists for this user, so select a + // room from a list that is similar to the one in MemberInfo panel + const ChatCreateOrReuseDialog = sdk.getComponent( + "views.dialogs.ChatCreateOrReuseDialog" + ); + Modal.createDialog(ChatCreateOrReuseDialog, { + userId: userId, + onFinished: (success) => { + if (success) { + this.props.onFinished(true, inviteList[0]); + } + // else show this ChatInviteDialog again + } }); - this.props.onFinished(true, inviteList[0]); } else { this._startChat(inviteList); } @@ -238,22 +247,20 @@ module.exports = React.createClass({ if (this._cancelThreepidLookup) this._cancelThreepidLookup(); }, - _getDirectMessageRoom: function(addr) { + _getDirectMessageRooms: function(addr) { const dmRoomMap = new DMRoomMap(MatrixClientPeg.get()); - var dmRooms = dmRoomMap.getDMRoomsForUserId(addr); - if (dmRooms.length > 0) { - // Cycle through all the DM rooms and find the first non forgotten or parted room - for (let i = 0; i < dmRooms.length; i++) { - let room = MatrixClientPeg.get().getRoom(dmRooms[i]); - if (room) { - const me = room.getMember(MatrixClientPeg.get().credentials.userId); - if (me.membership == 'join') { - return room; - } + const dmRooms = dmRoomMap.getDMRoomsForUserId(addr); + const rooms = []; + dmRooms.forEach(dmRoom => { + let room = MatrixClientPeg.get().getRoom(dmRoom); + if (room) { + const me = room.getMember(MatrixClientPeg.get().credentials.userId); + if (me.membership == 'join') { + rooms.push(room); } } - } - return null; + }); + return rooms; }, _startChat: function(addrs) { @@ -386,8 +393,11 @@ module.exports = React.createClass({ return false; }, - _isDmChat: function(addrs) { - if (addrs.length === 1 && getAddressType(addrs[0]) === "mx" && !this.props.roomId) { + _isDmChat: function(addrTexts) { + if (addrTexts.length === 1 && + getAddressType(addrTexts[0]) === "mx" && + !this.props.roomId + ) { return true; } else { return false; diff --git a/src/components/views/rooms/RoomTile.js b/src/components/views/rooms/RoomTile.js index f6c0f7034e..485b567ddc 100644 --- a/src/components/views/rooms/RoomTile.js +++ b/src/components/views/rooms/RoomTile.js @@ -35,6 +35,7 @@ module.exports = React.createClass({ propTypes: { connectDragSource: React.PropTypes.func, connectDropTarget: React.PropTypes.func, + onClick: React.PropTypes.func, isDragging: React.PropTypes.bool, room: React.PropTypes.object.isRequired, @@ -104,6 +105,9 @@ module.exports = React.createClass({ action: 'view_room', room_id: this.props.room.roomId, }); + if (this.props.onClick) { + this.props.onClick(); + } }, onMouseEnter: function() {