Merge branch 'develop' of github.com:vector-im/vector-web into read_receipts

This commit is contained in:
David Baker 2015-10-29 11:27:56 +00:00
commit f00ee95563
15 changed files with 99 additions and 22 deletions

View file

@ -1,3 +1,14 @@
Changes in vector v0.1.2 (2015-10-28)
======================================
* Support Room Avatars
* Fullscreen video calls
* Mute mic in VoIP calls
* Fix bug with multiple desktop notifications
* Context menu on messages
* Better hover-over on member list
* Support CAS auth
* Many other bug fixes
Changes in vector v0.1.1 (2015-08-10) Changes in vector v0.1.1 (2015-08-10)
====================================== ======================================

View file

@ -1,6 +1,6 @@
{ {
"name": "vector-web", "name": "vector-web",
"version": "0.0.1", "version": "0.1.2",
"description": "Vector webapp", "description": "Vector webapp",
"author": "matrix.org", "author": "matrix.org",
"repository": { "repository": {
@ -27,8 +27,8 @@
"filesize": "^3.1.2", "filesize": "^3.1.2",
"flux": "~2.0.3", "flux": "~2.0.3",
"linkifyjs": "^2.0.0-beta.4", "linkifyjs": "^2.0.0-beta.4",
"matrix-js-sdk": "^0.2.2", "matrix-js-sdk": "^0.3.0",
"matrix-react-sdk": "^0.0.1", "matrix-react-sdk": "^0.0.2",
"q": "^1.4.1", "q": "^1.4.1",
"react": "^0.13.3", "react": "^0.13.3",
"react-loader": "^1.4.0" "react-loader": "^1.4.0"

View file

@ -90,6 +90,7 @@ module.exports = {
else { else {
this.getVideoView().getLocalVideoElement().style.display = "none"; this.getVideoView().getLocalVideoElement().style.display = "none";
this.getVideoView().getRemoteVideoElement().style.display = "none"; this.getVideoView().getRemoteVideoElement().style.display = "none";
dis.dispatch({action: 'video_fullscreen', fullscreen: false});
} }
} }
}; };

View file

@ -34,6 +34,7 @@ module.exports = {
cli.on("Room.timeline", this.onRoomTimeline); cli.on("Room.timeline", this.onRoomTimeline);
cli.on("Room.name", this.onRoomName); cli.on("Room.name", this.onRoomName);
cli.on("RoomState.events", this.onRoomStateEvents); cli.on("RoomState.events", this.onRoomStateEvents);
cli.on("RoomMember.name", this.onRoomMemberName);
var rooms = this.getRoomList(); var rooms = this.getRoomList();
this.setState({ this.setState({
@ -116,6 +117,10 @@ module.exports = {
setTimeout(this.refreshRoomList, 0); setTimeout(this.refreshRoomList, 0);
}, },
onRoomMemberName: function(ev, member) {
setTimeout(this.refreshRoomList, 0);
},
refreshRoomList: function() { refreshRoomList: function() {
var rooms = this.getRoomList(); var rooms = this.getRoomList();

View file

@ -86,6 +86,10 @@ a:visited {
cursor: pointer; cursor: pointer;
} }
.mx_ContextualMenu_spinner {
display: block;
margin: 0 auto;
}
.mx_Dialog_background { .mx_Dialog_background {
position: fixed; position: fixed;

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View file

@ -17,7 +17,6 @@ limitations under the License.
'use strict'; 'use strict';
var React = require('react'); var React = require('react');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var RoomAvatarController = require('matrix-react-sdk/lib/controllers/atoms/RoomAvatar') var RoomAvatarController = require('matrix-react-sdk/lib/controllers/atoms/RoomAvatar')

View file

@ -0,0 +1,34 @@
/*
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';
var React = require('react');
module.exports = React.createClass({
displayName: 'Spinner',
render: function() {
var w = this.props.w || 32;
var h = this.props.h || 32;
var imgClass = this.props.imgClassName || "";
return (
<div>
<img src="img/spinner.gif" width={w} height={h} className={imgClass}/>
</div>
);
}
});

View file

@ -18,7 +18,6 @@ limitations under the License.
var React = require('react'); var React = require('react');
var sdk = require('matrix-react-sdk')
var TextForEvent = require('matrix-react-sdk/lib/TextForEvent'); var TextForEvent = require('matrix-react-sdk/lib/TextForEvent');
module.exports = React.createClass({ module.exports = React.createClass({

View file

@ -69,8 +69,6 @@ module.exports = React.createClass({
var SenderProfile = sdk.getComponent('molecules.SenderProfile'); var SenderProfile = sdk.getComponent('molecules.SenderProfile');
var MemberAvatar = sdk.getComponent('atoms.MemberAvatar'); var MemberAvatar = sdk.getComponent('atoms.MemberAvatar');
var UnknownMessageTile = sdk.getComponent('molecules.UnknownMessageTile');
var content = this.props.mxEvent.getContent(); var content = this.props.mxEvent.getContent();
var msgtype = content.msgtype; var msgtype = content.msgtype;

View file

@ -17,6 +17,7 @@ limitations under the License.
'use strict'; 'use strict';
var React = require('react'); var React = require('react');
var Loader = require("../atoms/Spinner");
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var MemberInfoController = require('matrix-react-sdk/lib/controllers/molecules/MemberInfo') var MemberInfoController = require('matrix-react-sdk/lib/controllers/molecules/MemberInfo')
@ -26,7 +27,7 @@ module.exports = React.createClass({
mixins: [MemberInfoController], mixins: [MemberInfoController],
render: function() { render: function() {
var interactButton, kickButton, banButton, muteButton, giveModButton; var interactButton, kickButton, banButton, muteButton, giveModButton, spinner;
if (this.props.member.userId === MatrixClientPeg.get().credentials.userId) { if (this.props.member.userId === MatrixClientPeg.get().credentials.userId) {
interactButton = <div className="mx_ContextualMenu_field" onClick={this.onLeaveClick}>Leave room</div>; interactButton = <div className="mx_ContextualMenu_field" onClick={this.onLeaveClick}>Leave room</div>;
} }
@ -34,6 +35,10 @@ module.exports = React.createClass({
interactButton = <div className="mx_ContextualMenu_field" onClick={this.onChatClick}>Start chat</div>; interactButton = <div className="mx_ContextualMenu_field" onClick={this.onChatClick}>Start chat</div>;
} }
if (this.state.creatingRoom) {
spinner = <Loader imgClassName="mx_ContextualMenu_spinner"/>;
}
if (this.state.can.kick) { if (this.state.can.kick) {
kickButton = <div className="mx_ContextualMenu_field" onClick={this.onKick}> kickButton = <div className="mx_ContextualMenu_field" onClick={this.onKick}>
Kick Kick
@ -64,6 +69,7 @@ module.exports = React.createClass({
{kickButton} {kickButton}
{banButton} {banButton}
{giveModButton} {giveModButton}
{spinner}
</div> </div>
); );
} }

View file

@ -17,12 +17,10 @@ limitations under the License.
'use strict'; 'use strict';
var React = require('react'); var React = require('react');
var classNames = require("classnames");
var sdk = require('matrix-react-sdk') var sdk = require('matrix-react-sdk')
var MessageTileController = require('matrix-react-sdk/lib/controllers/molecules/MessageTile') var MessageTileController = require('matrix-react-sdk/lib/controllers/molecules/MessageTile')
var ContextualMenu = require('../../../../ContextualMenu');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'MessageTile', displayName: 'MessageTile',

View file

@ -39,7 +39,7 @@ module.exports = React.createClass({
}, },
onFullscreenClick: function() { onFullscreenClick: function() {
dis.dispatch({action: 'video_fullscreen'}, true); dis.dispatch({action: 'video_fullscreen', fullscreen: true}, true);
}, },
render: function() { render: function() {
@ -61,7 +61,7 @@ module.exports = React.createClass({
var call_buttons; var call_buttons;
var zoom_button; var zoom_button;
if (this.state && this.state.call_state != 'ended') { if (this.state && this.state.call_state != 'ended') {
var muteVideoButton; //var muteVideoButton;
var activeCall = ( var activeCall = (
CallHandler.getCallForRoom(this.props.room.roomId) CallHandler.getCallForRoom(this.props.room.roomId)
); );

View file

@ -31,24 +31,28 @@ module.exports = React.createClass({
}, },
render: function() { render: function() {
if (!this.state.incomingCall || !this.state.incomingCall.roomId) {
return ( // NB: This block MUST have a "key" so React doesn't clobber the elements
<div> // between in-call / not-in-call.
<audio ref="ringAudio" loop> var audioBlock = (
<audio ref="ringAudio" key="voip_ring_audio" loop>
<source src="media/ring.ogg" type="audio/ogg" /> <source src="media/ring.ogg" type="audio/ogg" />
<source src="media/ring.mp3" type="audio/mpeg" /> <source src="media/ring.mp3" type="audio/mpeg" />
</audio> </audio>
);
if (!this.state.incomingCall || !this.state.incomingCall.roomId) {
return (
<div>
{audioBlock}
</div> </div>
); );
} }
var caller = MatrixClientPeg.get().getRoom(this.state.incomingCall.roomId).name; var caller = MatrixClientPeg.get().getRoom(this.state.incomingCall.roomId).name;
return ( return (
<div className="mx_IncomingCallBox"> <div className="mx_IncomingCallBox">
{audioBlock}
<img className="mx_IncomingCallBox_chevron" src="img/chevron-left.png" width="9" height="16" /> <img className="mx_IncomingCallBox_chevron" src="img/chevron-left.png" width="9" height="16" />
<audio ref="ringAudio" loop>
<source src="media/ring.ogg" type="audio/ogg" />
<source src="media/ring.mp3" type="audio/mpeg" />
</audio>
<div className="mx_IncomingCallBox_title"> <div className="mx_IncomingCallBox_title">
Incoming { this.state.incomingCall ? this.state.incomingCall.type : '' } call from { caller } Incoming { this.state.incomingCall ? this.state.incomingCall.type : '' } call from { caller }
</div> </div>

View file

@ -51,8 +51,26 @@ module.exports = React.createClass({
return; return;
} }
var element = this.container.getDOMNode(); var element = this.container.getDOMNode();
var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullscreen; if (payload.fullscreen) {
var requestMethod = (
element.requestFullScreen ||
element.webkitRequestFullScreen ||
element.mozRequestFullScreen ||
element.msRequestFullscreen
);
requestMethod.call(element); requestMethod.call(element);
}
else {
var exitMethod = (
document.exitFullscreen ||
document.mozCancelFullScreen ||
document.webkitExitFullscreen ||
document.msExitFullscreen
);
if (exitMethod) {
exitMethod.call(document);
}
}
break; break;
} }
}, },