Merge branch 'develop' into kegan/guest-access

This commit is contained in:
Kegan Dougal 2016-01-07 13:21:06 +00:00
commit c64f36c81b
83 changed files with 491 additions and 138 deletions

2
header
View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.
@ -18,6 +18,7 @@ var MatrixClientPeg = require("./MatrixClientPeg");
var MatrixTools = require("./MatrixTools");
var dis = require("./dispatcher");
var encryption = require("./encryption");
var Tinter = require("./Tinter");
var reject = function(msg) {
return {
@ -42,6 +43,12 @@ var commands = {
return reject("Usage: /nick <display_name>");
},
// Takes an #rrggbb colourcode and retints the UI (just for debugging)
tint: function(room_id, args) {
Tinter.tint(args);
return success();
},
encrypt: function(room_id, args) {
if (args == "on") {
var client = MatrixClientPeg.get();

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

197
src/Tinter.js Normal file
View file

@ -0,0 +1,197 @@
/*
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.
*/
var dis = require("./dispatcher");
// FIXME: these vars should be bundled up and attached to
// module.exports otherwise this will break when included by both
// react-sdk and apps layered on top.
// The colour keys to be replaced as referred to in SVGs
var keyRgb = [
"rgb(118, 207, 166)", // Vector Green
"rgb(234, 245, 240)", // Vector Light Green
"rgba(118, 207, 166, 0.2)", // BottomLeftMenu overlay (20% Vector Green)
];
// Some algebra workings for calculating the tint % of Vector Green & Light Green
// x * 118 + (1 - x) * 255 = 234
// x * 118 + 255 - 255 * x = 234
// x * 118 - x * 255 = 234 - 255
// (255 - 118) x = 255 - 234
// x = (255 - 234) / (255 - 118) = 0.16
// The colour keys to be replaced as referred to in SVGs
var keyHex = [
"#76CFA6", // Vector Green
"#EAF5F0", // Vector Light Green
"#D3EFE1", // BottomLeftMenu overlay (20% Vector Green overlaid on Vector Light Green)
];
// cache of our replacement colours
// defaults to our keys.
var colors = [
keyHex[0],
keyHex[1],
keyHex[2],
];
var cssFixups = [
// {
// style: a style object that should be fixed up taken from a stylesheet
// attr: name of the attribute to be clobbered, e.g. 'color'
// index: ordinal of primary, secondary or tertiary
// }
];
// CSS attributes to be fixed up
var cssAttrs = [
"color",
"backgroundColor",
"borderColor",
];
var svgAttrs = [
"fill",
"stroke",
];
var cached = false;
function calcCssFixups() {
for (var i = 0; i < document.styleSheets.length; i++) {
var ss = document.styleSheets[i];
for (var j = 0; j < ss.cssRules.length; j++) {
var rule = ss.cssRules[j];
if (!rule.style) continue;
for (var k = 0; k < cssAttrs.length; k++) {
var attr = cssAttrs[k];
for (var l = 0; l < keyRgb.length; l++) {
if (rule.style[attr] === keyRgb[l]) {
cssFixups.push({
style: rule.style,
attr: attr,
index: l,
});
}
}
}
}
}
}
function applyCssFixups() {
for (var i = 0; i < cssFixups.length; i++) {
var cssFixup = cssFixups[i];
cssFixup.style[cssFixup.attr] = colors[cssFixup.index];
}
}
function hexToRgb(color) {
if (color[0] === '#') color = color.slice(1);
if (color.length === 3) {
color = color[0] + color[0] +
color[1] + color[1] +
color[2] + color[2];
}
var val = parseInt(color, 16);
var r = (val >> 16) & 255;
var g = (val >> 8) & 255;
var b = val & 255;
return [r, g, b];
}
function rgbToHex(rgb) {
var val = (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
return '#' + (0x1000000 + val).toString(16).slice(1)
}
module.exports = {
tint: function(primaryColor, secondaryColor, tertiaryColor) {
if (!cached) {
calcCssFixups();
cached = true;
}
if (!secondaryColor) {
var x = 0.16; // average weighting factor calculated from vector green & light green
var rgb = hexToRgb(primaryColor);
rgb[0] = x * rgb[0] + (1 - x) * 255;
rgb[1] = x * rgb[1] + (1 - x) * 255;
rgb[2] = x * rgb[2] + (1 - x) * 255;
secondaryColor = rgbToHex(rgb);
}
if (!tertiaryColor) {
var x = 0.19;
var rgb1 = hexToRgb(primaryColor);
var rgb2 = hexToRgb(secondaryColor);
rgb1[0] = x * rgb1[0] + (1 - x) * rgb2[0];
rgb1[1] = x * rgb1[1] + (1 - x) * rgb2[1];
rgb1[2] = x * rgb1[2] + (1 - x) * rgb2[2];
tertiaryColor = rgbToHex(rgb1);
}
colors = [primaryColor, secondaryColor, tertiaryColor];
// go through manually fixing up the stylesheets.
applyCssFixups();
// tell all the SVGs to go fix themselves up
dis.dispatch({ action: 'tint_update' });
},
// XXX: we could just move this all into TintableSvg, but as it's so similar
// to the CSS fixup stuff in Tinter (just that the fixups are stored in TintableSvg)
// keeping it here for now.
calcSvgFixups: function(svgs) {
// go through manually fixing up SVG colours.
// we could do this by stylesheets, but keeping the stylesheets
// updated would be a PITA, so just brute-force search for the
// key colour; cache the element and apply.
var fixups = [];
for (var i = 0; i < svgs.length; i++) {
var svgDoc = svgs[i].contentDocument;
if (!svgDoc) continue;
var tags = svgDoc.getElementsByTagName("*");
for (var j = 0; j < tags.length; j++) {
var tag = tags[j];
for (var k = 0; k < svgAttrs.length; k++) {
var attr = svgAttrs[k];
for (var l = 0; l < keyHex.length; l++) {
if (tag.getAttribute(attr) && tag.getAttribute(attr).toUpperCase() === keyHex[l]) {
fixups.push({
node: tag,
attr: attr,
index: l,
});
}
}
}
}
}
return fixups;
},
applySvgFixups: function(fixups) {
for (var i = 0; i < fixups.length; i++) {
var svgFixup = fixups[i];
svgFixup.node.setAttribute(svgFixup.attr, colors[svgFixup.index]);
}
},
};

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.
@ -23,14 +23,14 @@ limitations under the License.
module.exports.components = {};
module.exports.components['structures.CreateRoom'] = require('./components/structures/CreateRoom');
module.exports.components['structures.login.Login'] = require('./components/structures/login/Login');
module.exports.components['structures.login.PostRegistration'] = require('./components/structures/login/PostRegistration');
module.exports.components['structures.login.Registration'] = require('./components/structures/login/Registration');
module.exports.components['structures.MatrixChat'] = require('./components/structures/MatrixChat');
module.exports.components['structures.RoomView'] = require('./components/structures/RoomView');
module.exports.components['structures.ScrollPanel'] = require('./components/structures/ScrollPanel');
module.exports.components['structures.UploadBar'] = require('./components/structures/UploadBar');
module.exports.components['structures.UserSettings'] = require('./components/structures/UserSettings');
module.exports.components['structures.login.Login'] = require('./components/structures/login/Login');
module.exports.components['structures.login.PostRegistration'] = require('./components/structures/login/PostRegistration');
module.exports.components['structures.login.Registration'] = require('./components/structures/login/Registration');
module.exports.components['views.avatars.MemberAvatar'] = require('./components/views/avatars/MemberAvatar');
module.exports.components['views.avatars.RoomAvatar'] = require('./components/views/avatars/RoomAvatar');
module.exports.components['views.create_room.CreateRoomButton'] = require('./components/views/create_room/CreateRoomButton');
@ -41,6 +41,7 @@ module.exports.components['views.dialogs.LogoutPrompt'] = require('./components/
module.exports.components['views.dialogs.QuestionDialog'] = require('./components/views/dialogs/QuestionDialog');
module.exports.components['views.elements.EditableText'] = require('./components/views/elements/EditableText');
module.exports.components['views.elements.ProgressBar'] = require('./components/views/elements/ProgressBar');
module.exports.components['views.elements.TintableSvg'] = require('./components/views/elements/TintableSvg');
module.exports.components['views.elements.UserSelector'] = require('./components/views/elements/UserSelector');
module.exports.components['views.login.CaptchaForm'] = require('./components/views/login/CaptchaForm');
module.exports.components['views.login.CasLogin'] = require('./components/views/login/CasLogin');
@ -50,10 +51,10 @@ module.exports.components['views.login.LoginHeader'] = require('./components/vie
module.exports.components['views.login.PasswordLogin'] = require('./components/views/login/PasswordLogin');
module.exports.components['views.login.RegistrationForm'] = require('./components/views/login/RegistrationForm');
module.exports.components['views.login.ServerConfig'] = require('./components/views/login/ServerConfig');
module.exports.components['views.messages.MessageEvent'] = require('./components/views/messages/MessageEvent');
module.exports.components['views.messages.MFileBody'] = require('./components/views/messages/MFileBody');
module.exports.components['views.messages.MImageBody'] = require('./components/views/messages/MImageBody');
module.exports.components['views.messages.MVideoBody'] = require('./components/views/messages/MVideoBody');
module.exports.components['views.messages.MessageEvent'] = require('./components/views/messages/MessageEvent');
module.exports.components['views.messages.TextualBody'] = require('./components/views/messages/TextualBody');
module.exports.components['views.messages.TextualEvent'] = require('./components/views/messages/TextualEvent');
module.exports.components['views.messages.UnknownBody'] = require('./components/views/messages/UnknownBody');
@ -66,6 +67,7 @@ module.exports.components['views.rooms.RoomHeader'] = require('./components/view
module.exports.components['views.rooms.RoomList'] = require('./components/views/rooms/RoomList');
module.exports.components['views.rooms.RoomSettings'] = require('./components/views/rooms/RoomSettings');
module.exports.components['views.rooms.RoomTile'] = require('./components/views/rooms/RoomTile');
module.exports.components['views.rooms.SearchResultTile'] = require('./components/views/rooms/SearchResultTile');
module.exports.components['views.rooms.TabCompleteBar'] = require('./components/views/rooms/TabCompleteBar');
module.exports.components['views.settings.ChangeAvatar'] = require('./components/views/settings/ChangeAvatar');
module.exports.components['views.settings.ChangeDisplayName'] = require('./components/views/settings/ChangeDisplayName');

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.
@ -574,8 +574,8 @@ module.exports = React.createClass({
getSearchResultTiles: function() {
var DateSeparator = sdk.getComponent('messages.DateSeparator');
var EventTile = sdk.getComponent('rooms.EventTile');
var SearchResultTile = sdk.getComponent('rooms.SearchResultTile');
var cli = MatrixClientPeg.get();
// XXX: todo: merge overlapping results somehow?
@ -615,33 +615,27 @@ module.exports = React.createClass({
continue;
}
var eventId = mxEv.getId();
if (this.state.searchScope === 'All') {
var roomId = mxEv.getRoomId();
if(roomId != lastRoomId) {
ret.push(<li key={eventId + "-room"}><h1>Room: { cli.getRoom(roomId).name }</h1></li>);
var room = cli.getRoom(roomId);
// XXX: if we've left the room, we might not know about
// it. We should tell the js sdk to go and find out about
// it. But that's not an issue currently, as synapse only
// returns results for rooms we're joined to.
var roomName = room ? room.name : "Unknown room "+roomId;
ret.push(<li key={mxEv.getId() + "-room"}>
<h1>Room: { roomName }</h1>
</li>);
lastRoomId = roomId;
}
}
var ts1 = mxEv.getTs();
ret.push(<li key={ts1 + "-search"}><DateSeparator ts={ts1}/></li>); // Rank: {resultList[i].rank}
var timeline = result.context.getTimeline();
for (var j = 0; j < timeline.length; j++) {
var ev = timeline[j];
var highlights;
var contextual = (j != result.context.getOurEventIndex());
if (!contextual) {
highlights = this.state.searchHighlights;
}
if (EventTile.haveTileForEvent(ev)) {
ret.push(<li key={eventId+"+"+j} data-scroll-token={eventId+"+"+j}>
<EventTile mxEvent={ev} contextual={contextual} highlights={highlights} />
</li>);
}
}
ret.push(<SearchResultTile key={mxEv.getId()}
searchResult={result}
searchHighlights={this.state.searchHighlights}/>);
}
return ret;
},
@ -656,6 +650,7 @@ module.exports = React.createClass({
var prevEvent = null; // the last event we showed
var readReceiptEventId = this.state.room.getEventReadUpTo(MatrixClientPeg.get().credentials.userId);
var startIdx = Math.max(0, this.state.room.timeline.length - this.state.messageCap);
for (var i = startIdx; i < this.state.room.timeline.length; i++) {
var mxEv = this.state.room.timeline[i];
@ -706,6 +701,10 @@ module.exports = React.createClass({
</li>
);
if (eventId == readReceiptEventId) {
ret.push(<hr className="mx_RoomView_myReadMarker" />);
}
prevEvent = mxEv;
}
@ -1083,6 +1082,7 @@ module.exports = React.createClass({
var RoomSettings = sdk.getComponent("rooms.RoomSettings");
var SearchBar = sdk.getComponent("rooms.SearchBar");
var ScrollPanel = sdk.getComponent("structures.ScrollPanel");
var TintableSvg = sdk.getComponent("elements.TintableSvg");
if (!this.state.room) {
if (this.props.roomId) {
@ -1157,7 +1157,7 @@ module.exports = React.createClass({
if (this.state.syncState === "ERROR") {
statusBar = (
<div className="mx_RoomView_connectionLostBar">
<img src="img/warning.svg" width="24" height="23" alt="/!\ "/>
<img src="img/warning.svg" width="24" height="23" title="/!\ " alt="/!\ "/>
<div className="mx_RoomView_connectionLostBar_textArea">
<div className="mx_RoomView_connectionLostBar_title">
Connectivity to the server has been lost.
@ -1176,8 +1176,8 @@ module.exports = React.createClass({
<div className="mx_RoomView_tabCompleteImage">...</div>
<div className="mx_RoomView_tabCompleteWrapper">
<TabCompleteBar entries={this.tabComplete.peek(6)} />
<div className="mx_RoomView_tabCompleteEol">
<img src="img/eol.svg" width="22" height="16" alt="->|"/>
<div className="mx_RoomView_tabCompleteEol" title="->|">
<TintableSvg src="img/eol.svg" width="22" height="16"/>
Auto-complete
</div>
</div>
@ -1187,7 +1187,7 @@ module.exports = React.createClass({
else if (this.state.hasUnsentMessages) {
statusBar = (
<div className="mx_RoomView_connectionLostBar">
<img src="img/warning.svg" width="24" height="23" alt="/!\ "/>
<img src="img/warning.svg" width="24" height="23" title="/!\ " alt="/!\ "/>
<div className="mx_RoomView_connectionLostBar_textArea">
<div className="mx_RoomView_connectionLostBar_title">
Some of your messages have not been sent.
@ -1250,8 +1250,8 @@ module.exports = React.createClass({
var fileDropTarget = null;
if (this.state.draggingFile) {
fileDropTarget = <div className="mx_RoomView_fileDropTarget">
<div className="mx_RoomView_fileDropTargetLabel">
<img src="img/upload-big.svg" width="45" height="59" alt="Drop File Here"/><br/>
<div className="mx_RoomView_fileDropTargetLabel" title="Drop File Here">
<TintableSvg src="img/upload-big.svg" width="45" height="59"/><br/>
Drop File Here
</div>
</div>;
@ -1288,25 +1288,29 @@ module.exports = React.createClass({
if (call.type === "video") {
zoomButton = (
<div className="mx_RoomView_voipButton" onClick={this.onFullscreenClick}>
<img src="img/fullscreen.svg" title="Fill screen" alt="Fill screen" width="29" height="22" style={{ marginTop: 1, marginRight: 4 }}/>
<div className="mx_RoomView_voipButton" onClick={this.onFullscreenClick} title="Fill screen">
<TintableSvg src="img/fullscreen.svg" width="29" height="22" style={{ marginTop: 1, marginRight: 4 }}/>
</div>
);
videoMuteButton =
<div className="mx_RoomView_voipButton" onClick={this.onMuteVideoClick}>
<img src={call.isLocalVideoMuted() ? "img/video-unmute.svg" : "img/video-mute.svg"} width="31" height="27"/>
<img src={call.isLocalVideoMuted() ? "img/video-unmute.svg" : "img/video-mute.svg"}
alt={call.isLocalVideoMuted() ? "Click to unmute video" : "Click to mute video"}
width="31" height="27"/>
</div>
}
voiceMuteButton =
<div className="mx_RoomView_voipButton" onClick={this.onMuteAudioClick}>
<img src={call.isMicrophoneMuted() ? "img/voice-unmute.svg" : "img/voice-mute.svg"} width="21" height="26"/>
<img src={call.isMicrophoneMuted() ? "img/voice-unmute.svg" : "img/voice-mute.svg"}
alt={call.isMicrophoneMuted() ? "Click to unmute audio" : "Click to mute audio"}
width="21" height="26"/>
</div>
if (!statusBar) {
statusBar =
<div className="mx_RoomView_callBar">
<img src="img/sound-indicator.svg" width="23" height="20" alt=""/>
<img src="img/sound-indicator.svg" width="23" height="20"/>
<b>Active call</b>
</div>;
}
@ -1317,7 +1321,7 @@ module.exports = React.createClass({
{ videoMuteButton }
{ zoomButton }
{ statusBar }
<img className="mx_RoomView_voipChevron" src="img/voip-chevron.svg" width="22" height="17"/>
<TintableSvg className="mx_RoomView_voipChevron" src="img/voip-chevron.svg" width="22" height="17"/>
</div>
}

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -0,0 +1,69 @@
/*
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');
var ReactDOM = require("react-dom");
var dis = require("../../../dispatcher");
var Tinter = require("../../../Tinter");
module.exports = React.createClass({
displayName: 'TintableSvg',
propTypes: {
src: React.PropTypes.string.isRequired,
width: React.PropTypes.string.isRequired,
height: React.PropTypes.string.isRequired,
className: React.PropTypes.string,
},
componentWillMount: function() {
this.fixups = [];
this.dispatcherRef = dis.register(this.onAction);
},
componentDidMount: function() {
// we can't use onLoad on object due to https://github.com/facebook/react/pull/5781
// so handle it with pure DOM instead
ReactDOM.findDOMNode(this).addEventListener('load', this.onLoad);
},
componentWillUnmount: function() {
ReactDOM.findDOMNode(this).removeEventListener('load', this.onLoad);
dis.unregister(this.dispatcherRef);
},
onAction: function(payload) {
if (payload.action !== 'tint_update') return;
Tinter.applySvgFixups(this.fixups);
},
onLoad: function(event) {
this.fixups = Tinter.calcSvgFixups([event.target]);
Tinter.applySvgFixups(this.fixups);
},
render: function() {
return (
<object className={ "mx_TintableSvg " + this.props.className }
type="image/svg+xml"
data={ this.props.src }
width={ this.props.width }
height={ this.props.height }/>
);
}
});

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.
@ -19,6 +19,8 @@ limitations under the License.
var React = require('react');
var filesize = require('filesize');
var MatrixClientPeg = require('../../../MatrixClientPeg');
var sdk = require('../../../index');
var dis = require("../../../dispatcher");
module.exports = React.createClass({
displayName: 'MFileBody',
@ -52,12 +54,14 @@ module.exports = React.createClass({
var httpUrl = cli.mxcUrlToHttp(content.url);
var text = this.presentableTextForFile(content);
var TintableSvg = sdk.getComponent("elements.TintableSvg");
if (httpUrl) {
return (
<span className="mx_MFileBody">
<div className="mx_MImageBody_download">
<a href={cli.mxcUrlToHttp(content.url)} target="_blank">
<img src="img/download.png" width="10" height="12"/>
<TintableSvg src="img/download.svg" width="12" height="14"/>
Download {text}
</a>
</div>

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.
@ -22,6 +22,7 @@ var filesize = require('filesize');
var MatrixClientPeg = require('../../../MatrixClientPeg');
var Modal = require('../../../Modal');
var sdk = require('../../../index');
var dis = require("../../../dispatcher");
module.exports = React.createClass({
displayName: 'MImageBody',
@ -97,6 +98,7 @@ module.exports = React.createClass({
},
render: function() {
var TintableSvg = sdk.getComponent("elements.TintableSvg");
var content = this.props.mxEvent.getContent();
var cli = MatrixClientPeg.get();
@ -118,7 +120,7 @@ module.exports = React.createClass({
</a>
<div className="mx_MImageBody_download">
<a href={cli.mxcUrlToHttp(content.url)} target="_blank">
<img src="img/download.png" width="10" height="12"/>
<TintableSvg src="img/download.svg" width="12" height="14"/>
Download {content.body} ({ content.info && content.info.size ? filesize(content.info.size) : "Unknown size" })
</a>
</div>

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.
@ -461,6 +461,7 @@ module.exports = React.createClass({
var me = this.props.room.getMember(MatrixClientPeg.get().credentials.userId);
var uploadInputStyle = {display: 'none'};
var MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
var TintableSvg = sdk.getComponent("elements.TintableSvg");
var callButton, videoCallButton, hangupButton;
var call = CallHandler.getCallForRoom(this.props.room.roomId);
@ -473,12 +474,12 @@ module.exports = React.createClass({
}
else {
callButton =
<div className="mx_MessageComposer_voicecall" onClick={this.onVoiceCallClick}>
<img src="img/voice.svg" alt="Voice call" title="Voice call" width="16" height="26"/>
<div className="mx_MessageComposer_voicecall" onClick={this.onVoiceCallClick} title="Voice call">
<TintableSvg src="img/voice.svg" width="16" height="26"/>
</div>
videoCallButton =
<div className="mx_MessageComposer_videocall" onClick={this.onCallClick}>
<img src="img/call.svg" alt="Video call" title="Video call" width="30" height="22"/>
<div className="mx_MessageComposer_videocall" onClick={this.onCallClick} title="Video call">
<TintableSvg src="img/call.svg" width="30" height="22"/>
</div>
}
@ -492,8 +493,8 @@ module.exports = React.createClass({
<div className="mx_MessageComposer_input" onClick={ this.onInputClick }>
<textarea ref="textarea" rows="1" onKeyDown={this.onKeyDown} onKeyUp={this.onKeyUp} placeholder="Type a message..." />
</div>
<div className="mx_MessageComposer_upload" onClick={this.onUploadClick}>
<img src="img/upload.svg" alt="Upload file" title="Upload file" width="19" height="24"/>
<div className="mx_MessageComposer_upload" onClick={this.onUploadClick} title="Upload file">
<TintableSvg src="img/upload.svg" width="19" height="24"/>
<input type="file" style={uploadInputStyle} ref="uploadInput" onChange={this.onUploadFileSelected} />
</div>
{ hangupButton }

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.
@ -66,10 +66,11 @@ module.exports = React.createClass({
getRoomName: function() {
return this.refs.name_edit.value;
},
render: function() {
var EditableText = sdk.getComponent("elements.EditableText");
var RoomAvatar = sdk.getComponent('avatars.RoomAvatar');
var TintableSvg = sdk.getComponent("elements.TintableSvg");
var header;
if (this.props.simpleHeader) {
@ -118,8 +119,8 @@ module.exports = React.createClass({
<div className="mx_RoomHeader_name" onClick={this.props.onSettingsClick}>
<div className="mx_RoomHeader_nametext" title={ this.props.room.name }>{ this.props.room.name }</div>
{ searchStatus }
<div className="mx_RoomHeader_settingsButton">
<img src="img/settings.svg" width="12" height="12"/>
<div className="mx_RoomHeader_settingsButton" title="Settings">
<TintableSvg src="img/settings.svg" width="12" height="12"/>
</div>
</div>
if (topic) topic_el = <div className="mx_RoomHeader_topic" title={topic.getContent().topic}>{ topic.getContent().topic }</div>;
@ -135,18 +136,16 @@ module.exports = React.createClass({
var leave_button;
if (this.props.onLeaveClick) {
leave_button =
<div className="mx_RoomHeader_button mx_RoomHeader_leaveButton">
<img src="img/leave.svg" title="Leave room" alt="Leave room"
width="26" height="20" onClick={this.props.onLeaveClick}/>
<div className="mx_RoomHeader_button mx_RoomHeader_leaveButton" onClick={this.props.onLeaveClick} title="Leave room">
<TintableSvg src="img/leave.svg" width="26" height="20"/>
</div>;
}
var forget_button;
if (this.props.onForgetClick) {
forget_button =
<div className="mx_RoomHeader_button mx_RoomHeader_leaveButton">
<img src="img/leave.svg" title="Forget room" alt="Forget room"
width="26" height="20" onClick={this.props.onForgetClick}/>
<div className="mx_RoomHeader_button mx_RoomHeader_leaveButton" onClick={this.props.onForgetClick} title="Forget room">
<TintableSvg src="img/leave.svg" width="26" height="20"/>
</div>;
}
@ -166,8 +165,8 @@ module.exports = React.createClass({
<div className="mx_RoomHeader_rightRow">
{ forget_button }
{ leave_button }
<div className="mx_RoomHeader_button">
<img src="img/search.svg" title="Search" alt="Search" width="21" height="19" onClick={this.props.onSearchClick}/>
<div className="mx_RoomHeader_button" onClick={this.props.onSearchClick} title="Search">
<TintableSvg src="img/search.svg" width="21" height="19"/>
</div>
</div>
</div>

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -0,0 +1,64 @@
/*
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');
var sdk = require('../../../index');
module.exports = React.createClass({
displayName: 'SearchResult',
propTypes: {
// a matrix-js-sdk SearchResult containing the details of this result
searchResult: React.PropTypes.object.isRequired,
// a list of strings to be highlighted in the results
searchHighlights: React.PropTypes.array,
// callback to be called when the user selects this result
onSelect: React.PropTypes.func,
},
render: function() {
var DateSeparator = sdk.getComponent('messages.DateSeparator');
var EventTile = sdk.getComponent('rooms.EventTile');
var result = this.props.searchResult;
var mxEv = result.context.getEvent();
var eventId = mxEv.getId();
var ts1 = mxEv.getTs();
var ret = [<DateSeparator key={ts1 + "-search"} ts={ts1}/>];
var timeline = result.context.getTimeline();
for (var j = 0; j < timeline.length; j++) {
var ev = timeline[j];
var highlights;
var contextual = (j != result.context.getOurEventIndex());
if (!contextual) {
highlights = this.props.searchHighlights;
}
if (EventTile.haveTileForEvent(ev)) {
ret.push(<EventTile key={eventId+"+"+j} mxEvent={ev} contextual={contextual} highlights={highlights}
onHighlightClick={this.props.onSelect}/>)
}
}
return (
<li data-scroll-token={eventId+"+"+j}>
{ret}
</li>);
},
});

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.
@ -25,8 +25,12 @@ var dis = require('../../../dispatcher');
module.exports = React.createClass({
displayName: 'VideoView',
componentWillMount: function() {
dis.register(this.onAction);
componentDidMount: function() {
this.dispatcherRef = dis.register(this.onAction);
},
componentWillUnmount: function() {
dis.unregister(this.dispatcherRef);
},
getRemoteVideoElement: function() {

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
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.