Merge branch 'vector' of github.com:matrix-org/matrix-react-sdk into erikj/room_editing

This commit is contained in:
Erik Johnston 2015-07-20 16:31:02 +01:00
commit 1b6ca2b0ee
21 changed files with 195 additions and 15 deletions

View File

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<title>vector</title>
<link href='https://fonts.googleapis.com/css?family=Lato:300,400,700' rel='stylesheet' type='text/css'>
<link href='fonts/Lato.css' rel='stylesheet' type='text/css'>
</head>
<body style="height: 100%;">
<audio id="ringbackAudio" loop>

View File

@ -68,5 +68,15 @@ html {
max-width: 500px;
z-index: -100;
position: relative;
top: 100px;
top: 200px;
}
.mx_ErrorDialogTitle {
background-color: #d2322d;
min-height: 16px;
padding: 15px;
border-bottom: 1px solid #e5e5e5;
font-weight: bold;
line-height: 1.4;
color: #fff;
}

View File

@ -22,7 +22,7 @@ limitations under the License.
position: absolute;
width: 200px;
margin-left: -295px;
margin-top: -12px;
margin-top: 0px;
z-index: 1000;
padding: 6px;
}
@ -34,6 +34,17 @@ limitations under the License.
top: 0px;
}
/*
* a hacky shim to extend the hitmask of the overlay to overlap
* better with the main menu itself
*/
.mx_MemberInfo_shim {
position: absolute;
left: 212px;
width: 40px;
height: 100%;
}
.mx_MemberInfo_avatar {
padding: 6px;
}
@ -44,7 +55,6 @@ limitations under the License.
.mx_MemberInfo_field {
padding: 6px;
font-weight: bold;
}
.mx_MemberInfo_button {

48
skins/base/fonts/Lato.css Normal file
View File

@ -0,0 +1,48 @@
/* latin-ext */
@font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 300;
src: local('Lato Light'), local('Lato-Light'), url(IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2) format('woff2');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 300;
src: local('Lato Light'), local('Lato-Light'), url(22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
/* latin-ext */
@font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 400;
src: local('Lato Regular'), local('Lato-Regular'), url(8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2) format('woff2');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 400;
src: local('Lato Regular'), local('Lato-Regular'), url(MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
/* latin-ext */
@font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 700;
src: local('Lato Bold'), local('Lato-Bold'), url(rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2) format('woff2');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 700;
src: local('Lato Bold'), local('Lato-Bold'), url(MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}

View File

@ -25,6 +25,16 @@ module.exports = React.createClass({
displayName: 'MemberInfo',
mixins: [MemberInfoController],
componentDidMount: function() {
var self = this;
var memberInfo = this.getDOMNode();
var memberListScroll = document.getElementsByClassName("mx_MemberList_border")[0];
if (memberListScroll) {
memberInfo.style.top = (memberInfo.parentElement.offsetTop - memberListScroll.scrollTop) + "px";
}
},
getDuration: function(time) {
if (!time) return;
var t = parseInt(time / 1000);
@ -61,6 +71,7 @@ module.exports = React.createClass({
return (
<div className="mx_MemberInfo">
<img className="mx_MemberInfo_chevron" src="img/chevron-right.png" width="9" height="16" />
<div className="mx_MemberInfo_shim"></div>
<div className="mx_MemberInfo_avatar">
<img className="mx_MemberInfo_avatarImg"
src={ this.props.member ? MatrixClientPeg.get().getAvatarUrlForMember(this.props.member, 128, 128, "crop") : null }

View File

@ -0,0 +1,71 @@
/*
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';
/*
* Usage:
* Modal.createDialog(ErrorDialog, {
* title: "some text", (default: "Error")
* description: "some more text",
* button: "Button Text",
* onClose: someFunction,
* focus: true|false (default: true)
* });
*/
var React = require('react');
module.exports = React.createClass({
displayName: 'ErrorDialog',
// can't use getDefaultProps, see Modal.js
componentWillMount: function() {
if (!this.props.title) {
this.props.title = "Error";
}
if (!this.props.description) {
this.props.description = "An error has occurred.";
}
if (!this.props.button) {
this.props.button = "OK";
}
if (this.props.focus === undefined) {
this.props.focus = true;
}
if (!this.props.onClose) {
var self = this;
this.props.onClose = function() {
self.props.onFinished();
};
}
},
render: function() {
return (
<div className="mx_ErrorDialog">
<div className="mx_ErrorDialogTitle">
{this.props.title}
</div>
{this.props.description}<br />
<button onClick={this.props.onClose} autoFocus={this.props.focus}>
{this.props.button}
</button>
</div>
);
}
});

View File

@ -30,6 +30,18 @@ module.exports = React.createClass({
displayName: 'MemberList',
mixins: [MemberListController],
// FIXME: combine this more nicely with the MemberInfo positioning stuff...
onMemberListScroll: function(ev) {
if (this.refs.memberListScroll) {
var memberListScroll = this.refs.memberListScroll.getDOMNode();
// offset the current MemberInfo bubble
var memberInfo = document.getElementsByClassName("mx_MemberInfo")[0];
if (memberInfo) {
memberInfo.style.top = (memberInfo.parentElement.offsetTop - memberListScroll.scrollTop) + "px";
}
}
},
makeMemberTiles: function() {
var self = this;
return Object.keys(self.state.memberDict).map(function(userId) {
@ -71,7 +83,7 @@ module.exports = React.createClass({
<div className="mx_MemberList_chevron">
<img src="img/chevron.png" width="24" height="13"/>
</div>
<div className="mx_MemberList_border">
<div className="mx_MemberList_border" ref="memberListScroll" onScroll={ this.onMemberListScroll }>
<h2>Members</h2>
<div className="mx_MemberList_wrapper">
{this.makeMemberTiles()}

View File

@ -25,7 +25,7 @@ var ChangePassword = ComponentBroker.get('molecules/ChangePassword');
var LogoutPrompt = ComponentBroker.get('organisms/LogoutPrompt');
var Loader = require("react-loader");
var Modal = require("../../../../src/Modal")
var Modal = require("../../../../src/Modal");
module.exports = React.createClass({
displayName: 'UserSettings',

View File

@ -54,6 +54,9 @@ limitations under the License.
*/
var MatrixClientPeg = require("./MatrixClientPeg");
var Modal = require("./Modal");
var ComponentBroker = require('./ComponentBroker');
var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog");
var Matrix = require("matrix-js-sdk");
var dis = require("./dispatcher");
@ -154,7 +157,12 @@ dis.register(function(payload) {
console.error("Room %s does not exist.", payload.room_id);
return;
}
if (room.getJoinedMembers().length !== 2) {
var members = room.getJoinedMembers();
if (members.length !== 2) {
var text = members.length === 1 ? "yourself." : "more than 2 people.";
Modal.createDialog(ErrorDialog, {
description: "You cannot place a call with " + text
});
console.error(
"Fail: There are %s joined members in this room, not 2.",
room.getJoinedMembers().length

View File

@ -110,4 +110,5 @@ require('../skins/base/views/molecules/voip/MCallAnswerTile');
require('../skins/base/views/molecules/voip/MCallHangupTile');
require('../skins/base/views/molecules/EventAsTextTile');
require('../skins/base/views/molecules/MemberInfo');
require('../skins/base/views/organisms/ErrorDialog');
}

View File

@ -44,6 +44,8 @@ module.exports = {
if (props && props.onFinished) props.onFinished.apply(arguments);
};
// 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">

View File

@ -100,22 +100,18 @@ var commands = {
else {
// attempt to join this alias.
return success(
MatrixClientPeg.get().joinRoom(room_alias).done(
MatrixClientPeg.get().joinRoom(room_alias).then(
function(room) {
dis.dispatch({
action: 'view_room',
room_id: room.roomId
});
}, function(err) {
console.error(
"Failed to join room: %s", JSON.stringify(err)
);
})
);
}
}
}
return reject("Usage: /join <room_alias> [NOT IMPLEMENTED]");
return reject("Usage: /join <room_alias>");
},
// Kick a user from the room with an optional reason

View File

@ -18,6 +18,9 @@ limitations under the License.
var MatrixClientPeg = require("../../MatrixClientPeg");
var SlashCommands = require("../../SlashCommands");
var Modal = require("../../Modal");
var ComponentBroker = require('../../ComponentBroker');
var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog");
var dis = require("../../dispatcher");
var KeyCode = {
@ -196,10 +199,18 @@ module.exports = {
console.log("Command success.");
}, function(err) {
console.error("Command failure: %s", err);
Modal.createDialog(ErrorDialog, {
title: "Server Error",
description: err.message
});
});
}
else if (cmd.error) {
console.error(cmd.error);
Modal.createDialog(ErrorDialog, {
title: "Command Error",
description: cmd.error
});
}
return;
}