Merge branch 'develop' into wmwragg/one-to-one-chat

This commit is contained in:
wmwragg 2016-09-07 17:22:10 +01:00
commit 7dfb8857d8
9 changed files with 169 additions and 67 deletions

View file

@ -276,6 +276,7 @@ function _onAction(payload) {
).done(function(call) {
placeCall(call);
}, function(err) {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to set up conference call",
description: "Conference call failed: " + err,

View file

@ -1,58 +0,0 @@
/*
Copyright 2015, 2016 OpenMarket 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.
*/
var CallHandler = require('./CallHandler');
module.exports = {
/**
* Given a room object, return the alias we should use for it,
* if any. This could be the canonical alias if one exists, otherwise
* an alias selected arbitrarily but deterministically from the list
* of aliases. Otherwise return null;
*/
getDisplayAliasForRoom: function(room) {
return room.getCanonicalAlias() || room.getAliases()[0];
},
isDirectMessageRoom: function(room, me, ConferenceHandler, hideConferenceChans) {
if (me.membership == "join" || me.membership === "ban" ||
(me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey()))
{
// Used to split rooms via tags
var tagNames = Object.keys(room.tags);
// Used for 1:1 direct chats
var joinedMembers = room.getJoinedMembers();
// Show 1:1 chats in seperate "Direct Messages" section as long as they haven't
// been moved to a different tag section
if (joinedMembers.length === 2 && !tagNames.length) {
var otherMember = joinedMembers.filter(function(m) {
return m.userId !== me.userId
})[0];
if (ConferenceHandler && ConferenceHandler.isConferenceUser(otherMember.userId)) {
// console.log("Hiding conference 1:1 room %s", room.roomId);
if (!hideConferenceChans) {
return true;
}
} else {
return true;
}
}
}
return false;
},
}

77
src/Rooms.js Normal file
View file

@ -0,0 +1,77 @@
/*
Copyright 2015, 2016 OpenMarket 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.
*/
/**
* Given a room object, return the alias we should use for it,
* if any. This could be the canonical alias if one exists, otherwise
* an alias selected arbitrarily but deterministically from the list
* of aliases. Otherwise return null;
*/
export function getDisplayAliasForRoom(room) {
return room.getCanonicalAlias() || room.getAliases()[0];
}
/**
* If the room contains only two members including the logged-in user,
* return the other one. Otherwise, return null.
*/
export function getOnlyOtherMember(room, me) {
const joinedMembers = room.getJoinedMembers();
if (joinedMembers.length === 2) {
return joinedMembers.filter(function(m) {
return m.userId !== me.userId
})[0];
}
return null;
}
export function isConfCallRoom(room, me, conferenceHandler) {
if (!conferenceHandler) return false;
if (me.membership != "join") {
return false;
}
const otherMember = getOnlyOtherMember(room, me);
if (otherMember === null) {
return false;
}
if (conferenceHandler.isConferenceUser(otherMember.userId)) {
return true;
}
}
export function looksLikeDirectMessageRoom(room, me) {
if (me.membership == "join" || me.membership === "ban" ||
(me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey()))
{
// Used to split rooms via tags
const tagNames = Object.keys(room.tags);
// Used for 1:1 direct chats
const joinedMembers = room.getJoinedMembers();
// Show 1:1 chats in seperate "Direct Messages" section as long as they haven't
// been moved to a different tag section
if (joinedMembers.length === 2 && !tagNames.length) {
return true;
}
}
return false;
}

View file

@ -15,7 +15,6 @@ limitations under the License.
*/
var MatrixClientPeg = require("./MatrixClientPeg");
var MatrixTools = require("./MatrixTools");
var dis = require("./dispatcher");
var Tinter = require("./Tinter");

View file

@ -4,7 +4,7 @@ import Q from 'q';
import MatrixClientPeg from '../MatrixClientPeg';
import Fuse from 'fuse.js';
import {PillCompletion} from './Components';
import {getDisplayAliasForRoom} from '../MatrixTools';
import {getDisplayAliasForRoom} from '../Rooms';
import sdk from '../index';
const ROOM_REGEX = /(?=#)([^\s]*)/g;

View file

@ -36,7 +36,7 @@ var PostRegistration = require("./login/PostRegistration");
var Modal = require("../../Modal");
var Tinter = require("../../Tinter");
var sdk = require('../../index');
var MatrixTools = require('../../MatrixTools');
var Rooms = require('../../Rooms');
var linkifyMatrix = require("../../linkify-matrix");
var KeyCode = require('../../KeyCode');
var Lifecycle = require('../../Lifecycle');
@ -482,7 +482,7 @@ module.exports = React.createClass({
var presentedId = room_info.room_alias || room_info.room_id;
var room = MatrixClientPeg.get().getRoom(room_info.room_id);
if (room) {
var theAlias = MatrixTools.getDisplayAliasForRoom(room);
var theAlias = Rooms.getDisplayAliasForRoom(room);
if (theAlias) presentedId = theAlias;
// No need to do this given RoomView triggers it itself...
@ -602,7 +602,7 @@ module.exports = React.createClass({
var presentedId = self.state.currentRoomId;
var room = MatrixClientPeg.get().getRoom(self.state.currentRoomId);
if (room) {
var theAlias = MatrixTools.getDisplayAliasForRoom(room);
var theAlias = Rooms.getDisplayAliasForRoom(room);
if (theAlias) presentedId = theAlias;
}

View file

@ -36,7 +36,6 @@ var dis = require("../../dispatcher");
var Tinter = require("../../Tinter");
var rate_limited_func = require('../../ratelimitedfunc');
var ObjectUtils = require('../../ObjectUtils');
var MatrixTools = require('../../MatrixTools');
import UserProvider from '../../autocomplete/UserProvider';

View file

@ -25,7 +25,8 @@ var Unread = require('../../../Unread');
var dis = require("../../../dispatcher");
var sdk = require('../../../index');
var rate_limited_func = require('../../../ratelimitedfunc');
var MatrixTools = require('../../../MatrixTools');
var Rooms = require('../../../Rooms');
var DMRoomMap = require('../../../utils/DMRoomMap');
var HIDE_CONFERENCE_CHANS = true;
@ -207,8 +208,10 @@ module.exports = React.createClass({
s.lists["m.lowpriority"] = [];
s.lists["im.vector.fake.archived"] = [];
const dmRoomMap = new DMRoomMap(MatrixClientPeg.get());
MatrixClientPeg.get().getRooms().forEach(function(room) {
var me = room.getMember(MatrixClientPeg.get().credentials.userId);
const me = room.getMember(MatrixClientPeg.get().credentials.userId);
if (!me) return;
// console.log("room = " + room.name + ", me.membership = " + me.membership +
@ -219,7 +222,10 @@ module.exports = React.createClass({
if (me.membership == "invite") {
s.lists["im.vector.fake.invite"].push(room);
}
else if (MatrixTools.isDirectMessageRoom(room, me, self.props.ConferenceHandler, HIDE_CONFERENCE_CHANS)) {
else if (HIDE_CONFERENCE_CHANS && Rooms.isConfCallRoom(room, me, self.props.ConferenceHandler)) {
// skip past this room & don't put it in any lists
}
else if (dmRoomMap.getUserIdForRoomId(room.roomId)) {
// "Direct Message" rooms
s.lists["im.vector.fake.direct"].push(room);
}
@ -248,6 +254,38 @@ module.exports = React.createClass({
}
});
if (s.lists["im.vector.fake.direct"].length == 0 && MatrixClientPeg.get().getAccountData('m.direct') === undefined) {
// scan through the 'recents' list for any rooms which look like DM rooms
// and make them DM rooms
const oldRecents = s.lists["im.vector.fake.recent"];
s.lists["im.vector.fake.recent"] = [];
for (const room of oldRecents) {
const me = room.getMember(MatrixClientPeg.get().credentials.userId);
if (me && Rooms.looksLikeDirectMessageRoom(room, me)) {
s.lists["im.vector.fake.direct"].push(room);
} else {
s.lists["im.vector.fake.recent"].push(room);
}
}
// save these new guessed DM rooms into the account data
const newMDirectEvent = {};
for (const room of s.lists["im.vector.fake.direct"]) {
const me = room.getMember(MatrixClientPeg.get().credentials.userId);
const otherPerson = Rooms.getOnlyOtherMember(room, me);
if (!otherPerson) continue;
const roomList = newMDirectEvent[otherPerson.userId] || [];
roomList.push(room.roomId);
newMDirectEvent[otherPerson.userId] = roomList;
}
// if this fails, fine, we'll just do the same thing next time we get the room lists
MatrixClientPeg.get().setAccountData('m.direct', newMDirectEvent).done();
}
//console.log("calculated new roomLists; im.vector.fake.recent = " + s.lists["im.vector.fake.recent"]);
// we actually apply the sorting to this when receiving the prop in RoomSubLists.

46
src/utils/DMRoomMap.js Normal file
View file

@ -0,0 +1,46 @@
/*
Copyright 2016 OpenMarket 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.
*/
/**
* Class that takes a Matrix Client and flips the m.direct map
* so the operation of mapping a room ID to which user it's a DM
* with can be performed efficiently.
*/
export default class DMRoomMap {
constructor(matrixClient) {
const mDirectEvent = matrixClient.getAccountData('m.direct');
if (!mDirectEvent) {
this.userToRooms = {};
this.roomToUser = {};
} else {
this.userToRooms = mDirectEvent.getContent();
this.roomToUser = {};
for (const user of Object.keys(this.userToRooms)) {
for (const roomId of this.userToRooms[user]) {
this.roomToUser[roomId] = user;
}
}
}
}
getDMRoomsForUserId(userId) {
return this.userToRooms[userId];
}
getUserIdForRoomId(roomId) {
return this.roomToUser[roomId];
}
}