Allow user to choose from existing DMs on new chat
When creating a new chat with one person, show a dialog that asks the user whether they'd like to use an existing chat or actually create a new room. Fixes https://github.com/vector-im/riot-web/issues/2760
This commit is contained in:
parent
6a007d01a1
commit
ca5c2fb82e
4 changed files with 142 additions and 24 deletions
|
@ -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);
|
views$create_room$RoomAlias && (module.exports.components['views.create_room.RoomAlias'] = views$create_room$RoomAlias);
|
||||||
import views$dialogs$BaseDialog from './components/views/dialogs/BaseDialog';
|
import views$dialogs$BaseDialog from './components/views/dialogs/BaseDialog';
|
||||||
views$dialogs$BaseDialog && (module.exports.components['views.dialogs.BaseDialog'] = 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';
|
import views$dialogs$ChatInviteDialog from './components/views/dialogs/ChatInviteDialog';
|
||||||
views$dialogs$ChatInviteDialog && (module.exports.components['views.dialogs.ChatInviteDialog'] = views$dialogs$ChatInviteDialog);
|
views$dialogs$ChatInviteDialog && (module.exports.components['views.dialogs.ChatInviteDialog'] = views$dialogs$ChatInviteDialog);
|
||||||
import views$dialogs$ConfirmUserActionDialog from './components/views/dialogs/ConfirmUserActionDialog';
|
import views$dialogs$ConfirmUserActionDialog from './components/views/dialogs/ConfirmUserActionDialog';
|
||||||
|
|
102
src/components/views/dialogs/ChatCreateOrReuseDialog.js
Normal file
102
src/components/views/dialogs/ChatCreateOrReuseDialog.js
Normal file
|
@ -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(
|
||||||
|
<RoomTile key={room.roomId} room={room}
|
||||||
|
collapsed={false}
|
||||||
|
selected={false}
|
||||||
|
unread={Unread.doesRoomHaveUnreadMessages(room)}
|
||||||
|
highlight={highlight}
|
||||||
|
isInvite={me.membership == "invite"}
|
||||||
|
onClick={() => this.props.onFinished(true)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const labelClasses = classNames({
|
||||||
|
mx_MemberInfo_createRoom_label: true,
|
||||||
|
mx_RoomTile_name: true,
|
||||||
|
});
|
||||||
|
const startNewChat = <AccessibleButton
|
||||||
|
className="mx_MemberInfo_createRoom"
|
||||||
|
onClick={this._onNewDMClick}
|
||||||
|
>
|
||||||
|
<div className="mx_RoomTile_avatar">
|
||||||
|
<img src="img/create-big.svg" width="26" height="26" />
|
||||||
|
</div>
|
||||||
|
<div className={labelClasses}><i>Start new chat</i></div>
|
||||||
|
</AccessibleButton>;
|
||||||
|
|
||||||
|
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||||
|
return (
|
||||||
|
<BaseDialog className='mx_CreateOrReuseChatDialog'
|
||||||
|
onFinished={() => {
|
||||||
|
this.props.onFinished(false)
|
||||||
|
}}
|
||||||
|
title='Create a new chat or reuse an existing one'
|
||||||
|
>
|
||||||
|
<h3>Direct chats</h3>
|
||||||
|
{tiles}
|
||||||
|
{startNewChat}
|
||||||
|
</BaseDialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateOrReuseChatDialog.propTyps = {
|
||||||
|
userId: React.PropTypes.string.isRequired,
|
||||||
|
onFinished: React.PropTypes.func.isRequired,
|
||||||
|
};
|
|
@ -97,18 +97,27 @@ module.exports = React.createClass({
|
||||||
if (inviteList === null) return;
|
if (inviteList === null) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const addrTexts = inviteList.map(addr => addr.address);
|
||||||
if (inviteList.length > 0) {
|
if (inviteList.length > 0) {
|
||||||
if (this._isDmChat(inviteList)) {
|
if (this._isDmChat(addrTexts)) {
|
||||||
|
const userId = inviteList[0].address;
|
||||||
// Direct Message chat
|
// Direct Message chat
|
||||||
var room = this._getDirectMessageRoom(inviteList[0]);
|
const rooms = this._getDirectMessageRooms(userId);
|
||||||
if (room) {
|
if (rooms.length > 0) {
|
||||||
// A Direct Message room already exists for this user and you
|
// A Direct Message room already exists for this user, so select a
|
||||||
// so go straight to that room
|
// room from a list that is similar to the one in MemberInfo panel
|
||||||
dis.dispatch({
|
const ChatCreateOrReuseDialog = sdk.getComponent(
|
||||||
action: 'view_room',
|
"views.dialogs.ChatCreateOrReuseDialog"
|
||||||
room_id: room.roomId,
|
);
|
||||||
|
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 {
|
} else {
|
||||||
this._startChat(inviteList);
|
this._startChat(inviteList);
|
||||||
}
|
}
|
||||||
|
@ -238,22 +247,20 @@ module.exports = React.createClass({
|
||||||
if (this._cancelThreepidLookup) this._cancelThreepidLookup();
|
if (this._cancelThreepidLookup) this._cancelThreepidLookup();
|
||||||
},
|
},
|
||||||
|
|
||||||
_getDirectMessageRoom: function(addr) {
|
_getDirectMessageRooms: function(addr) {
|
||||||
const dmRoomMap = new DMRoomMap(MatrixClientPeg.get());
|
const dmRoomMap = new DMRoomMap(MatrixClientPeg.get());
|
||||||
var dmRooms = dmRoomMap.getDMRoomsForUserId(addr);
|
const dmRooms = dmRoomMap.getDMRoomsForUserId(addr);
|
||||||
if (dmRooms.length > 0) {
|
const rooms = [];
|
||||||
// Cycle through all the DM rooms and find the first non forgotten or parted room
|
dmRooms.forEach(dmRoom => {
|
||||||
for (let i = 0; i < dmRooms.length; i++) {
|
let room = MatrixClientPeg.get().getRoom(dmRoom);
|
||||||
let room = MatrixClientPeg.get().getRoom(dmRooms[i]);
|
if (room) {
|
||||||
if (room) {
|
const me = room.getMember(MatrixClientPeg.get().credentials.userId);
|
||||||
const me = room.getMember(MatrixClientPeg.get().credentials.userId);
|
if (me.membership == 'join') {
|
||||||
if (me.membership == 'join') {
|
rooms.push(room);
|
||||||
return room;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
return null;
|
return rooms;
|
||||||
},
|
},
|
||||||
|
|
||||||
_startChat: function(addrs) {
|
_startChat: function(addrs) {
|
||||||
|
@ -386,8 +393,11 @@ module.exports = React.createClass({
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
_isDmChat: function(addrs) {
|
_isDmChat: function(addrTexts) {
|
||||||
if (addrs.length === 1 && getAddressType(addrs[0]) === "mx" && !this.props.roomId) {
|
if (addrTexts.length === 1 &&
|
||||||
|
getAddressType(addrTexts[0]) === "mx" &&
|
||||||
|
!this.props.roomId
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -35,6 +35,7 @@ module.exports = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
connectDragSource: React.PropTypes.func,
|
connectDragSource: React.PropTypes.func,
|
||||||
connectDropTarget: React.PropTypes.func,
|
connectDropTarget: React.PropTypes.func,
|
||||||
|
onClick: React.PropTypes.func,
|
||||||
isDragging: React.PropTypes.bool,
|
isDragging: React.PropTypes.bool,
|
||||||
|
|
||||||
room: React.PropTypes.object.isRequired,
|
room: React.PropTypes.object.isRequired,
|
||||||
|
@ -104,6 +105,9 @@ module.exports = React.createClass({
|
||||||
action: 'view_room',
|
action: 'view_room',
|
||||||
room_id: this.props.room.roomId,
|
room_id: this.props.room.roomId,
|
||||||
});
|
});
|
||||||
|
if (this.props.onClick) {
|
||||||
|
this.props.onClick();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onMouseEnter: function() {
|
onMouseEnter: function() {
|
||||||
|
|
Loading…
Reference in a new issue