Merge remote-tracking branch 'origin/develop' into read_receipts

pull/21833/head
David Baker 2015-11-05 15:05:29 +00:00
commit 3114422cb7
20 changed files with 145 additions and 233 deletions

View File

@ -18,7 +18,7 @@ var skin = args._[0];
try {
fs.accessSync(path.join('src', 'skins', skin), fs.F_OK);
} catch (e) {
console.log("Skin "+skin+" not found");
console.log("Skin "+skin+" not found: "+e);
process.exit(1);
}

View File

@ -173,17 +173,27 @@ function _onAction(payload) {
console.error("Unknown conf call type: %s", payload.type);
}
}
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
switch (payload.action) {
case 'place_call':
if (module.exports.getAnyActiveCall()) {
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Existing Call",
description: "You are already in a call."
});
return; // don't allow >1 call to be placed.
}
// if the runtime env doesn't do VoIP, whine.
if (!MatrixClientPeg.get().supportsVoip()) {
Modal.createDialog(ErrorDialog, {
title: "VoIP is unsupported",
description: "You cannot place VoIP calls in this browser."
});
return;
}
var room = MatrixClientPeg.get().getRoom(payload.room_id);
if (!room) {
console.error("Room %s does not exist.", payload.room_id);
@ -218,11 +228,17 @@ function _onAction(payload) {
case 'place_conference_call':
console.log("Place conference call in %s", payload.room_id);
if (!Modulator.hasConferenceHandler()) {
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
Modal.createDialog(ErrorDialog, {
description: "Conference calls are not supported in this client"
});
} else {
}
else if (!MatrixClientPeg.get().supportsVoip()) {
Modal.createDialog(ErrorDialog, {
title: "VoIP is unsupported",
description: "You cannot place VoIP calls in this browser."
});
}
else {
var ConferenceHandler = Modulator.getConferenceHandler();
ConferenceHandler.createNewMatrixCall(
MatrixClientPeg.get(), payload.room_id
@ -238,6 +254,12 @@ function _onAction(payload) {
payload.call.hangup("busy");
return; // don't allow >1 call to be received, hangup newer one.
}
// if the runtime env doesn't do VoIP, stop here.
if (!MatrixClientPeg.get().supportsVoip()) {
return;
}
var call = payload.call;
_setCallListeners(call);
_setCallState(call, call.roomId, "ringing");

View File

@ -31,6 +31,31 @@ module.exports = {
}
}
return null;
},
/**
* Given a list of room objects, return the room which has the given alias,
* else null.
*/
getRoomForAlias: function(rooms, room_alias) {
var room;
for (var i = 0; i < rooms.length; i++) {
var aliasEvents = rooms[i].currentState.getStateEvents(
"m.room.aliases"
);
for (var j = 0; j < aliasEvents.length; j++) {
var aliases = aliasEvents[j].getContent().aliases || [];
for (var k = 0; k < aliases.length; k++) {
if (aliases[k] === room_alias) {
room = rooms[i];
break;
}
}
if (room) { break; }
}
if (room) { break; }
}
return room || null;
}
}

View File

@ -34,7 +34,7 @@ module.exports = {
return container;
},
createDialogWithElement: function(element, props) {
createDialogWithElement: function(element, props, className) {
var self = this;
var closeDialog = function() {
@ -44,7 +44,7 @@ module.exports = {
};
var dialog = (
<div className="mx_Dialog_wrapper">
<div className={"mx_Dialog_wrapper " + className}>
<div className="mx_Dialog">
{element}
</div>
@ -57,7 +57,7 @@ module.exports = {
return {close: closeDialog};
},
createDialog: function (Element, props) {
createDialog: function (Element, props, className) {
var self = this;
var closeDialog = function() {
@ -69,7 +69,7 @@ module.exports = {
// FIXME: If a dialog uses getDefaultProps it clobbers the onFinished
// property set here so you can't close the dialog from a button click!
var dialog = (
<div className="mx_Dialog_wrapper">
<div className={"mx_Dialog_wrapper " + className}>
<div className="mx_Dialog">
<Element {...props} onFinished={closeDialog}/>
</div>

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
var MatrixClientPeg = require("./MatrixClientPeg");
var MatrixTools = require("./MatrixTools");
var dis = require("./dispatcher");
var encryption = require("./encryption");
@ -98,28 +99,14 @@ var commands = {
}
// Try to find a room with this alias
var rooms = MatrixClientPeg.get().getRooms();
var roomId;
for (var i = 0; i < rooms.length; i++) {
var aliasEvents = rooms[i].currentState.getStateEvents(
"m.room.aliases"
);
for (var j = 0; j < aliasEvents.length; j++) {
var aliases = aliasEvents[j].getContent().aliases || [];
for (var k = 0; k < aliases.length; k++) {
if (aliases[k] === room_alias) {
roomId = rooms[i].roomId;
break;
}
}
if (roomId) { break; }
}
if (roomId) { break; }
}
if (roomId) { // we've already joined this room, view it.
var foundRoom = MatrixTools.getRoomForAlias(
MatrixClientPeg.get().getRooms(),
room_alias
);
if (foundRoom) { // we've already joined this room, view it.
dis.dispatch({
action: 'view_room',
room_id: roomId
room_id: foundRoom.roomId
});
return success();
}

View File

@ -1,6 +1,7 @@
var MatrixClientPeg = require("./MatrixClientPeg");
function textForMemberEvent(ev) {
// XXX: SYJS-16
// XXX: SYJS-16 "sender is sometimes null for join messages"
var senderName = ev.sender ? ev.sender.name : ev.getSender();
var targetName = ev.target ? ev.target.name : ev.getStateKey();
var reason = ev.getContent().reason ? (
@ -58,6 +59,12 @@ function textForTopicEvent(ev) {
return senderDisplayName + ' changed the topic to, "' + ev.getContent().topic + '"';
};
function textForRoomNameEvent(ev) {
var senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
return senderDisplayName + ' changed the room name to "' + ev.getContent().name + '"';
};
function textForMessageEvent(ev) {
var senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
@ -72,12 +79,14 @@ function textForMessageEvent(ev) {
function textForCallAnswerEvent(event) {
var senderName = event.sender ? event.sender.name : "Someone";
return senderName + " answered the call.";
var supported = MatrixClientPeg.get().supportsVoip() ? "" : " (not supported by this browser)";
return senderName + " answered the call." + supported;
};
function textForCallHangupEvent(event) {
var senderName = event.sender ? event.sender.name : "Someone";
return senderName + " ended the call.";
var supported = MatrixClientPeg.get().supportsVoip() ? "" : " (not supported by this browser)";
return senderName + " ended the call." + supported;
};
function textForCallInviteEvent(event) {
@ -88,16 +97,18 @@ function textForCallInviteEvent(event) {
event.getContent().offer.sdp.indexOf('m=video') !== -1) {
type = "video";
}
return senderName + " placed a " + type + " call.";
var supported = MatrixClientPeg.get().supportsVoip() ? "" : " (not supported by this browser)";
return senderName + " placed a " + type + " call." + supported;
};
var handlers = {
'm.room.message': textForMessageEvent,
'm.room.topic': textForTopicEvent,
'm.room.member': textForMemberEvent,
'm.call.invite': textForCallInviteEvent,
'm.call.answer': textForCallAnswerEvent,
'm.call.hangup': textForCallHangupEvent,
'm.room.name': textForRoomNameEvent,
'm.room.topic': textForTopicEvent,
'm.room.member': textForMemberEvent,
'm.call.invite': textForCallInviteEvent,
'm.call.answer': textForCallAnswerEvent,
'm.call.hangup': textForCallHangupEvent,
};
module.exports = {

View File

@ -1,21 +0,0 @@
/*
Copyright 2015 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.
*/
'use strict';
module.exports = {
};

View File

@ -1,19 +0,0 @@
/*
Copyright 2015 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.
*/
module.exports = {
};

View File

@ -1,19 +0,0 @@
/*
Copyright 2015 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.
*/
module.exports = {
};

View File

@ -1,21 +0,0 @@
/*
Copyright 2015 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.
*/
'use strict';
module.exports = {
};

View File

@ -1,21 +0,0 @@
/*
Copyright 2015 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.
*/
'use strict';
module.exports = {
};

View File

@ -1,21 +0,0 @@
/*
Copyright 2015 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.
*/
'use strict';
module.exports = {
};

View File

@ -161,6 +161,7 @@ module.exports = {
onChatClick: function() {
// check if there are any existing rooms with just us and them (1:1)
// If so, just view that room. If not, create a private room with them.
var self = this;
var rooms = MatrixClientPeg.get().getRooms();
var userIds = [
this.props.member.userId,
@ -189,23 +190,28 @@ module.exports = {
action: 'view_room',
room_id: existingRoomId
});
this.props.onFinished();
}
else {
self.setState({ creatingRoom: true });
MatrixClientPeg.get().createRoom({
invite: [this.props.member.userId],
preset: "private_chat"
}).done(function(res) {
self.setState({ creatingRoom: false });
dis.dispatch({
action: 'view_room',
room_id: res.room_id
});
self.props.onFinished();
}, function(err) {
self.setState({ creatingRoom: false });
console.error(
"Failed to create room: %s", JSON.stringify(err)
);
self.props.onFinished();
});
}
this.props.onFinished();
},
// FIXME: this is horribly duplicated with MemberTile's onLeaveClick.
@ -249,7 +255,8 @@ module.exports = {
modifyLevel: false
},
muted: false,
isTargetMod: false
isTargetMod: false,
creatingRoom: false
}
},

View File

@ -1,21 +0,0 @@
/*
Copyright 2015 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.
*/
'use strict';
module.exports = {
};

View File

@ -1,20 +0,0 @@
/*
Copyright 2015 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.
*/
'use strict';
module.exports = {
};

View File

@ -1,19 +0,0 @@
/*
Copyright 2015 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.
*/
module.exports = {
};

View File

@ -22,6 +22,7 @@ var dis = require("../../dispatcher");
var sdk = require('../../index');
var MatrixTools = require('../../MatrixTools');
var linkifyMatrix = require("../../linkify-matrix");
var Cas = require("../../CasLogic");
@ -67,6 +68,15 @@ module.exports = {
} else {
this.notifyNewScreen('login');
}
// this can technically be done anywhere but doing this here keeps all
// the routing url path logic together.
if (this.onAliasClick) {
linkifyMatrix.onAliasClick = this.onAliasClick;
}
if (this.onUserClick) {
linkifyMatrix.onUserClick = this.onUserClick;
}
},
componentWillUnmount: function() {
@ -214,7 +224,19 @@ module.exports = {
}
break;
case 'view_room_alias':
MatrixClientPeg.get().getRoomIdForAlias(payload.room_alias).done(function(result) {
var foundRoom = MatrixTools.getRoomForAlias(
MatrixClientPeg.get().getRooms(), payload.room_alias
);
if (foundRoom) {
dis.dispatch({
action: 'view_room',
room_id: foundRoom.roomId
});
return;
}
// resolve the alias and *then* view it
MatrixClientPeg.get().getRoomIdForAlias(payload.room_alias).done(
function(result) {
dis.dispatch({
action: 'view_room',
room_id: result.room_id
@ -325,6 +347,9 @@ module.exports = {
onKeyDown: function(ev) {
if (ev.altKey) {
/*
// Remove this for now as ctrl+alt = alt-gr so this breaks keyboards which rely on alt-gr for numbers
// Will need to find a better meta key if anyone actually cares about using this.
if (ev.ctrlKey && ev.keyCode > 48 && ev.keyCode < 58) {
dis.dispatch({
action: 'view_indexed_room',
@ -334,6 +359,7 @@ module.exports = {
ev.preventDefault();
return;
}
*/
switch (ev.keyCode) {
case 38:
dis.dispatch({action: 'view_prev_room'});

View File

@ -94,8 +94,14 @@ module.exports = {
self.setStep("stage_m.login.password");
if (error.httpStatus == 400 && loginParams.medium) {
self.setState({errorText: 'This Home Server does not support login using email address.'});
} else {
self.setState({errorText: 'Login failed.'});
}
else if (error.httpStatus === 403) {
self.setState({errorText: 'Incorrect username and/or password.'});
}
else {
self.setState({
errorText: 'There was a problem logging in. (HTTP ' + error.httpStatus + ")"
});
}
});
},

View File

@ -22,7 +22,8 @@ module.exports = {
PasswordMismatch: 'PasswordMismatch',
TooShort: 'TooShort',
Missing: 'Missing',
InUse: 'InUse'
InUse: 'InUse',
Length: 'Length'
},
getInitialState: function() {

View File

@ -95,17 +95,26 @@ function matrixLinkify(linkify) {
S_AT_NAME_COLON_DOMAIN_DOT.on(TT.TLD, S_USERID);
}
matrixLinkify.onUserClick = function(e, userId) { e.preventDefault(); };
matrixLinkify.onAliasClick = function(e, roomAlias) { e.preventDefault(); };
matrixLinkify.options = {
formatHref: function (href, type) {
events: function (href, type) {
switch (type) {
case 'roomalias':
return '#';
case 'userid':
return '#';
default:
return href;
case "userid":
return {
click: function(e) {
matrixLinkify.onUserClick(e, href);
}
};
case "roomalias":
return {
click: function(e) {
matrixLinkify.onAliasClick(e, href);
}
};
}
}
}
};
module.exports = matrixLinkify;