Merge branch 'develop' into matthew/settings

pull/384/head
Matthew Hodgson 2015-12-18 00:36:46 +00:00
commit a7b9e54594
172 changed files with 1068 additions and 6058 deletions

2
.gitignore vendored
View File

@ -4,4 +4,4 @@ lib
.DS_Store .DS_Store
key.pem key.pem
cert.pem cert.pem
build vector/components.css

View File

@ -36,9 +36,10 @@ about them:
2. `cd matrix-react-sdk` 2. `cd matrix-react-sdk`
3. `git checkout develop` 3. `git checkout develop`
4. `npm install` 4. `npm install`
5. `npm start` (to start the dev rebuilder) 5. `npm run build`
6. `cd ../vector-web` 6. `npm start` (to start the dev rebuilder)
7. Link the react sdk package into the example: 7. `cd ../vector-web`
8. Link the react sdk package into the example:
`npm link path/to/your/react/sdk` `npm link path/to/your/react/sdk`
Similarly, you may need to `npm link path/to/your/js/sdk` in your `matrix-react-sdk` Similarly, you may need to `npm link path/to/your/js/sdk` in your `matrix-react-sdk`
@ -53,6 +54,34 @@ about "Cannot resolve module 'source-map-loader'" due to shortcomings in webpack
Deployment Deployment
========== ==========
Just run `npm build` and then mount the `vector` directory on your webserver to Just run `npm run build` and then mount the `vector` directory on your webserver to
actually serve up the app, which is entirely static content. actually serve up the app, which is entirely static content.
Enabling encryption
===================
End-to-end encryption in Vector and Matrix is not yet considered ready for
day-to-day use; it is experimental and should be considered only as a
proof-of-concept. See https://matrix.org/jira/browse/SPEC-162 for an overview
of the current progress.
To build a version of vector with support for end-to-end encryption, install
the olm module with `npm i https://matrix.org/packages/npm/olm/olm-0.1.0.tgz`
before running `npm start`. The olm library will be detected and used if
available.
To enable encryption for a room, type
```
/encrypt on
```
in the message bar in that room. Vector will then generate a set of keys, and
encrypt all outgoing messages in that room. (Note that other people in that
room will send messages in the clear unless they also `/encrypt on`.)
Note that historical encrypted messages cannot currently be decoded - history
is therefore lost when the page is reloaded.
There is currently no visual indication of whether encryption is enabled for a
room, or whether a particular message was encrypted.

View File

@ -9,46 +9,51 @@
}, },
"license": "Apache-2.0", "license": "Apache-2.0",
"style": "bundle.css", "style": "bundle.css",
"matrix-react-parent": "matrix-react-sdk",
"scripts": { "scripts": {
"reskindex": "reskindex vector -h src/skins/vector/header", "reskindex": "reskindex -h src/header",
"build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js", "build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js",
"build:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/bundle.css -c uglifycss --no-watch", "build:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css --no-watch",
"build:compile": "babel --source-maps -d lib src", "build:compile": "babel --source-maps -d lib src",
"build:bundle": "NODE_ENV=production webpack -p lib/vector/index.js vector/bundle.js", "build:bundle": "NODE_ENV=production webpack -p lib/vector/index.js vector/bundle.js",
"build": "npm run build:css && npm run build:compile && npm run build:bundle", "build": "npm run build:css && npm run build:compile && npm run build:bundle",
"start:js": "webpack -w src/vector/index.js vector/bundle.js", "start:js": "webpack -w src/vector/index.js vector/bundle.js",
"start:skins:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/bundle.css", "start:skins:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css",
"//cache": "Note the -c 1 below due to https://code.google.com/p/chromium/issues/detail?id=508270", "//cache": "Note the -c 1 below due to https://code.google.com/p/chromium/issues/detail?id=508270",
"start": "parallelshell \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"", "start": "parallelshell \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
"clean": "rimraf lib vector/bundle.css vector/bundle.js vector/bundle.js.map", "clean": "rimraf lib vector/bundle.css vector/bundle.js vector/bundle.js.map vector/webpack.css*",
"prepublish": "npm run build:css && npm run build:compile" "prepublish": "npm run build:css && npm run build:compile"
}, },
"dependencies": { "dependencies": {
"classnames": "^2.1.2", "classnames": "^2.1.2",
"extract-text-webpack-plugin": "^0.9.1",
"filesize": "^3.1.2", "filesize": "^3.1.2",
"flux": "~2.0.3", "flux": "~2.0.3",
"gemini-scrollbar": "^1.3.0",
"gfm.css": "^1.1.1",
"highlight.js": "^9.0.0",
"linkifyjs": "^2.0.0-beta.4", "linkifyjs": "^2.0.0-beta.4",
"matrix-js-sdk": "^0.3.0", "matrix-js-sdk": "https://github.com/matrix-org/matrix-js-sdk.git#develop",
"matrix-react-sdk": "^0.0.2", "matrix-react-sdk": "https://github.com/matrix-org/matrix-react-sdk.git#develop",
"modernizr": "^3.1.0", "modernizr": "^3.1.0",
"q": "^1.4.1", "q": "^1.4.1",
"react": "^0.14.2", "react": "^0.14.2",
"react-dnd": "^2.0.2", "react-dnd": "^2.0.2",
"react-dnd-html5-backend": "^2.0.0", "react-dnd-html5-backend": "^2.0.0",
"react-dom": "^0.14.2", "react-dom": "^0.14.2",
"react-gemini-scrollbar": "^2.0.1", "react-gemini-scrollbar": "^2.0.1"
"sanitize-html": "^1.0.0"
}, },
"devDependencies": { "devDependencies": {
"babel": "^5.8.23", "babel": "^5.8.23",
"babel-core": "^5.8.25", "babel-core": "^5.8.25",
"babel-loader": "^5.3.2", "babel-loader": "^5.3.2",
"catw": "^1.0.1", "catw": "^1.0.1",
"css-raw-loader": "^0.1.1",
"http-server": "^0.8.4", "http-server": "^0.8.4",
"json-loader": "^0.5.3", "json-loader": "^0.5.3",
"parallelshell": "^1.2.0", "parallelshell": "^1.2.0",
"rimraf": "^2.4.3", "rimraf": "^2.4.3",
"source-map-loader": "^0.1.5", "source-map-loader": "^0.1.5",
"uglifycss": "0.0.15" "webpack": "^1.12.6"
} }
} }

View File

@ -1,53 +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';
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
module.exports = {
avatarUrlForMember: function(member, width, height, resizeMethod) {
var url = member.getAvatarUrl(
MatrixClientPeg.get().getHomeserverUrl(),
width,
height,
resizeMethod
);
if (!url) {
// member can be null here currently since on invites, the JS SDK
// does not have enough info to build a RoomMember object for
// the inviter.
url = this.defaultAvatarUrlForString(member ? member.userId : '');
}
return url;
},
defaultAvatarUrlForString: function(s) {
var total = 0;
for (var i = 0; i < s.length; ++i) {
total += s.charCodeAt(i);
}
switch (total % 3) {
case 0:
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9QjNbxSKP4eagAFnTseHFErFYLBaLxWKxWCwWi8Vi8cX4CzAABSwCRWJw31gAAAAASUVORK5CYII=";
case 1:
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9chOaxgCP4eagAFk9seHFErFYLBaLxWKxWCwWi8Vi8cX4CzAAtKMCks/JG8MAAAAASUVORK5CYII=";
case 2:
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9YzNayQCP4eagADldseHFErFYLBaLxWKxWCwWi8Vi8cX4CzAAyiACeHwPiu4AAAAASUVORK5CYII=";
}
}
}

View File

@ -1,82 +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';
var React = require('react');
var ReactDOM = require('react-dom');
// Shamelessly ripped off Modal.js. There's probably a better way
// of doing reusable widgets like dialog boxes & menus where we go and
// pass in a custom control as the actual body.
module.exports = {
ContextualMenuContainerId: "mx_ContextualMenu_Container",
getOrCreateContainer: function() {
var container = document.getElementById(this.ContextualMenuContainerId);
if (!container) {
container = document.createElement("div");
container.id = this.ContextualMenuContainerId;
document.body.appendChild(container);
}
return container;
},
createMenu: function (Element, props) {
var self = this;
var closeMenu = function() {
React.unmountComponentAtNode(self.getOrCreateContainer());
if (props && props.onFinished) props.onFinished.apply(null, arguments);
};
var position = {
top: props.top - 20,
};
var chevron = null;
if (props.left) {
chevron = <img className="mx_ContextualMenu_chevron_left" src="img/chevron-left.png" width="9" height="16" />
position.left = props.left + 8;
} else {
chevron = <img className="mx_ContextualMenu_chevron_right" src="img/chevron-right.png" width="9" height="16" />
position.right = props.right + 8;
}
var className = 'mx_ContextualMenu_wrapper';
// FIXME: If a menu uses getDefaultProps it clobbers the onFinished
// property set here so you can't close the menu from a button click!
var menu = (
<div className={className}>
<div className="mx_ContextualMenu" style={position}>
{chevron}
<Element {...props} onFinished={closeMenu}/>
</div>
<div className="mx_ContextualMenu_background" onClick={closeMenu}></div>
</div>
);
ReactDOM.render(menu, this.getOrCreateContainer());
return {close: closeMenu};
},
};

View File

@ -1,45 +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';
var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
module.exports = {
formatDate: function(date) {
// date.toLocaleTimeString is completely system dependent.
// just go 24h for now
function pad(n) {
return (n < 10 ? '0' : '') + n;
}
var now = new Date();
if (date.toDateString() === now.toDateString()) {
return pad(date.getHours()) + ':' + pad(date.getMinutes());
}
else if (now.getTime() - date.getTime() < 6 * 24 * 60 * 60 * 1000) {
return days[date.getDay()] + " " + pad(date.getHours()) + ':' + pad(date.getMinutes());
}
else if (now.getFullYear() === date.getFullYear()) {
return days[date.getDay()] + ", " + months[date.getMonth()] + " " + (date.getDay()+1) + " " + pad(date.getHours()) + ':' + pad(date.getMinutes());
}
else {
return days[date.getDay()] + ", " + months[date.getMonth()] + " " + (date.getDay()+1) + " " + date.getFullYear() + " " + pad(date.getHours()) + ':' + pad(date.getMinutes());
}
}
}

View File

@ -1,40 +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.
*/
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var dis = require('matrix-react-sdk/lib/dispatcher');
module.exports = {
resend: function(event) {
MatrixClientPeg.get().resendEvent(
event, MatrixClientPeg.get().getRoom(event.getRoomId())
).done(function() {
dis.dispatch({
action: 'message_sent',
event: event
});
}, function() {
dis.dispatch({
action: 'message_send_failed',
event: event
});
});
dis.dispatch({
action: 'message_resend_started',
event: event
});
},
};

View File

@ -85,15 +85,15 @@ ConferenceCall.prototype._getConferenceUserRoom = function() {
}; };
/** /**
* Check if this room member is in fact a conference bot. * Check if this user ID is in fact a conference bot.
* @param {RoomMember} The room member to check * @param {string} userId The user ID to check.
* @return {boolean} True if it is a conference bot. * @return {boolean} True if it is a conference bot.
*/ */
module.exports.isConferenceUser = function(roomMember) { module.exports.isConferenceUser = function(userId) {
if (roomMember.userId.indexOf("@" + USER_PREFIX) !== 0) { if (userId.indexOf("@" + USER_PREFIX) !== 0) {
return false; return false;
} }
var base64part = roomMember.userId.split(":")[0].substring(1 + USER_PREFIX.length); var base64part = userId.split(":")[0].substring(1 + USER_PREFIX.length);
if (base64part) { if (base64part) {
var decoded = new Buffer(base64part, "base64").toString(); var decoded = new Buffer(base64part, "base64").toString();
// ! $STUFF : $STUFF // ! $STUFF : $STUFF

47
src/component-index.js Normal file
View File

@ -0,0 +1,47 @@
/*
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.
*/
/*
* THIS FILE IS AUTO-GENERATED
* You can edit it you like, but your changes will be overwritten,
* so you'd just be trying to swim upstream like a salmon.
* You are not a salmon.
*/
module.exports.components = require('matrix-react-sdk/lib/component-index').components;
module.exports.components['structures.BottomLeftMenu'] = require('./components/structures/BottomLeftMenu');
module.exports.components['structures.CompatibilityPage'] = require('./components/structures/CompatibilityPage');
module.exports.components['structures.LeftPanel'] = require('./components/structures/LeftPanel');
module.exports.components['structures.RightPanel'] = require('./components/structures/RightPanel');
module.exports.components['structures.RoomDirectory'] = require('./components/structures/RoomDirectory');
module.exports.components['structures.RoomSubList'] = require('./components/structures/RoomSubList');
module.exports.components['structures.ViewSource'] = require('./components/structures/ViewSource');
module.exports.components['views.elements.ImageView'] = require('./components/views/elements/ImageView');
module.exports.components['views.elements.Spinner'] = require('./components/views/elements/Spinner');
module.exports.components['views.globals.MatrixToolbar'] = require('./components/views/globals/MatrixToolbar');
module.exports.components['views.login.CustomServerDialog'] = require('./components/views/login/VectorCustomServerDialog');
module.exports.components['views.login.LoginFooter'] = require('./components/views/login/VectorLoginFooter');
module.exports.components['views.login.LoginHeader'] = require('./components/views/login/VectorLoginHeader');
module.exports.components['views.messages.DateSeparator'] = require('./components/views/messages/DateSeparator');
module.exports.components['views.messages.MessageTimestamp'] = require('./components/views/messages/MessageTimestamp');
module.exports.components['views.messages.SenderProfile'] = require('./components/views/messages/SenderProfile');
module.exports.components['views.rooms.BottomLeftMenuTile'] = require('./components/views/rooms/BottomLeftMenuTile');
module.exports.components['views.rooms.MessageContextMenu'] = require('./components/views/rooms/MessageContextMenu');
module.exports.components['views.rooms.RoomDNDView'] = require('./components/views/rooms/RoomDNDView');
module.exports.components['views.rooms.RoomDropTarget'] = require('./components/views/rooms/RoomDropTarget');
module.exports.components['views.rooms.RoomTooltip'] = require('./components/views/rooms/RoomTooltip');
module.exports.components['views.rooms.SearchBar'] = require('./components/views/rooms/SearchBar');

View File

@ -40,13 +40,13 @@ module.exports = React.createClass({
return <div className="mx_RoomTile_name">{name}</div> return <div className="mx_RoomTile_name">{name}</div>
} }
else if (this.state.hover) { else if (this.state.hover) {
var RoomTooltip = sdk.getComponent("molecules.RoomTooltip"); var RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
return <RoomTooltip name={name}/>; return <RoomTooltip name={name}/>;
} }
}, },
render: function() { render: function() {
var BottomLeftMenuTile = sdk.getComponent('molecules.BottomLeftMenuTile'); var BottomLeftMenuTile = sdk.getComponent('rooms.BottomLeftMenuTile');
return ( return (
<div className="mx_BottomLeftMenu"> <div className="mx_BottomLeftMenu">
<div className="mx_BottomLeftMenu_options"> <div className="mx_BottomLeftMenu_options">

View File

@ -22,6 +22,7 @@ var HTML5Backend = require('react-dnd-html5-backend');
var sdk = require('matrix-react-sdk') var sdk = require('matrix-react-sdk')
var dis = require('matrix-react-sdk/lib/dispatcher'); var dis = require('matrix-react-sdk/lib/dispatcher');
var VectorConferenceHandler = require('../../VectorConferenceHandler');
var CallHandler = require("matrix-react-sdk/lib/CallHandler"); var CallHandler = require("matrix-react-sdk/lib/CallHandler");
var LeftPanel = React.createClass({ var LeftPanel = React.createClass({
@ -84,9 +85,9 @@ var LeftPanel = React.createClass({
}, },
render: function() { render: function() {
var RoomList = sdk.getComponent('organisms.RoomList'); var RoomList = sdk.getComponent('rooms.RoomList');
var BottomLeftMenu = sdk.getComponent('molecules.BottomLeftMenu'); var BottomLeftMenu = sdk.getComponent('structures.BottomLeftMenu');
var IncomingCallBox = sdk.getComponent('molecules.voip.IncomingCallBox'); var IncomingCallBox = sdk.getComponent('voip.IncomingCallBox');
var collapseButton; var collapseButton;
var classes = "mx_LeftPanel"; var classes = "mx_LeftPanel";
@ -100,8 +101,12 @@ var LeftPanel = React.createClass({
var callPreview; var callPreview;
if (this.state.showCallElement) { if (this.state.showCallElement) {
var CallView = sdk.getComponent('molecules.voip.CallView'); var CallView = sdk.getComponent('voip.CallView');
callPreview = <CallView className="mx_LeftPanel_callView" onClick={this.onCallViewClick} /> callPreview = (
<CallView
className="mx_LeftPanel_callView" onClick={this.onCallViewClick}
ConferenceHandler={VectorConferenceHandler} />
);
} }
return ( return (
@ -109,7 +114,10 @@ var LeftPanel = React.createClass({
{ collapseButton } { collapseButton }
<IncomingCallBox /> <IncomingCallBox />
{ callPreview } { callPreview }
<RoomList selectedRoom={this.props.selectedRoom} collapsed={this.props.collapsed}/> <RoomList
selectedRoom={this.props.selectedRoom}
collapsed={this.props.collapsed}
ConferenceHandler={VectorConferenceHandler} />
<BottomLeftMenu collapsed={this.props.collapsed}/> <BottomLeftMenu collapsed={this.props.collapsed}/>
</aside> </aside>
); );

View File

@ -68,6 +68,11 @@ module.exports = React.createClass({
if (this.state.phase == this.Phase.MemberList && member.roomId === this.props.roomId) { if (this.state.phase == this.Phase.MemberList && member.roomId === this.props.roomId) {
this.forceUpdate(); this.forceUpdate();
} }
else if (this.state.phase === this.Phase.MemberInfo && member.roomId === this.props.roomId &&
member.userId === this.state.member.userId) {
// refresh the member info (e.g. new power level)
this.forceUpdate();
}
}, },
onAction: function(payload) { onAction: function(payload) {
@ -94,7 +99,7 @@ module.exports = React.createClass({
}, },
render: function() { render: function() {
var MemberList = sdk.getComponent('organisms.MemberList'); var MemberList = sdk.getComponent('rooms.MemberList');
var buttonGroup; var buttonGroup;
var panel; var panel;
@ -122,12 +127,12 @@ module.exports = React.createClass({
buttonGroup = buttonGroup =
<div className="mx_RightPanel_headerButtonGroup"> <div className="mx_RightPanel_headerButtonGroup">
<div className="mx_RightPanel_headerButton" onClick={ this.onMemberListButtonClick }> <div className="mx_RightPanel_headerButton" onClick={ this.onMemberListButtonClick }>
<img src="img/members.png" width="17" height="22" title="Members" alt="Members"/> <img src="img/members.svg" width="17" height="22" title="Members" alt="Members"/>
{ membersBadge } { membersBadge }
{ membersHighlight } { membersHighlight }
</div> </div>
<div className="mx_RightPanel_headerButton mx_RightPanel_filebutton"> <div className="mx_RightPanel_headerButton mx_RightPanel_filebutton">
<img src="img/files.png" width="17" height="22" title="Files" alt="Files"/> <img src="img/files.svg" width="17" height="22" title="Files" alt="Files"/>
{ filesHighlight } { filesHighlight }
</div> </div>
</div>; </div>;
@ -137,7 +142,7 @@ module.exports = React.createClass({
panel = <MemberList roomId={this.props.roomId} key={this.props.roomId} /> panel = <MemberList roomId={this.props.roomId} key={this.props.roomId} />
} }
else if(this.state.phase == this.Phase.MemberInfo) { else if(this.state.phase == this.Phase.MemberInfo) {
var MemberInfo = sdk.getComponent('molecules.MemberInfo'); var MemberInfo = sdk.getComponent('rooms.MemberInfo');
panel = <MemberInfo roomId={this.props.roomId} member={this.state.member} key={this.props.roomId} /> panel = <MemberInfo roomId={this.props.roomId} member={this.state.member} key={this.props.roomId} />
} }
} }

View File

@ -40,7 +40,7 @@ module.exports = React.createClass({
if (err) { if (err) {
self.setState({ loading: false }); self.setState({ loading: false });
console.error("Failed to get publicRooms: %s", JSON.stringify(err)); console.error("Failed to get publicRooms: %s", JSON.stringify(err));
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog"); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, { Modal.createDialog(ErrorDialog, {
title: "Failed to get public room list", title: "Failed to get public room list",
description: err.message description: err.message
@ -67,7 +67,7 @@ module.exports = React.createClass({
}); });
}, function(err) { }, function(err) {
console.error("Failed to join room: %s", JSON.stringify(err)); console.error("Failed to join room: %s", JSON.stringify(err));
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog"); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, { Modal.createDialog(ErrorDialog, {
title: "Failed to join room", title: "Failed to join room",
description: err.message description: err.message
@ -119,7 +119,7 @@ module.exports = React.createClass({
render: function() { render: function() {
if (this.state.loading) { if (this.state.loading) {
var Loader = sdk.getComponent("atoms.Spinner"); var Loader = sdk.getComponent("elements.Spinner");
return ( return (
<div className="mx_RoomDirectory"> <div className="mx_RoomDirectory">
<Loader /> <Loader />
@ -127,7 +127,7 @@ module.exports = React.createClass({
); );
} }
var RoomHeader = sdk.getComponent('molecules.RoomHeader'); var RoomHeader = sdk.getComponent('rooms.RoomHeader');
return ( return (
<div className="mx_RoomDirectory"> <div className="mx_RoomDirectory">
<RoomHeader simpleHeader="Public Rooms" /> <RoomHeader simpleHeader="Public Rooms" />

View File

@ -20,6 +20,7 @@ var React = require('react');
var DropTarget = require('react-dnd').DropTarget; var DropTarget = require('react-dnd').DropTarget;
var sdk = require('matrix-react-sdk') var sdk = require('matrix-react-sdk')
var dis = require('matrix-react-sdk/lib/dispatcher'); var dis = require('matrix-react-sdk/lib/dispatcher');
var UnreadStatus = require('matrix-react-sdk/lib/UnreadStatus');
// turn this on for drop & drag console debugging galore // turn this on for drop & drag console debugging galore
var debug = false; var debug = false;
@ -88,10 +89,20 @@ var RoomSubList = React.createClass({
}, },
tsOfNewestEvent: function(room) { tsOfNewestEvent: function(room) {
if (room.timeline.length) { for (var i = room.timeline.length - 1; i >= 0; --i) {
return room.timeline[room.timeline.length - 1].getTs(); var ev = room.timeline[i];
// logic copied from RoomList.js for when we do/don't highlight
if (UnreadStatus.eventTriggersUnreadCount(ev)) {
return ev.getTs();
} }
else { }
// we might only have events that don't trigger the unread indicator,
// in which case use the oldest event even if normally it wouldn't count.
// This is better than just assuming the last event was forever ago.
if (room.timeline.length) {
return room.timeline[0].getTs();
} else {
return Number.MAX_SAFE_INTEGER; return Number.MAX_SAFE_INTEGER;
} }
}, },
@ -215,7 +226,7 @@ var RoomSubList = React.createClass({
makeRoomTiles: function() { makeRoomTiles: function() {
var self = this; var self = this;
var RoomTile = sdk.getComponent("molecules.RoomTile"); var RoomTile = sdk.getComponent("rooms.RoomTile");
return this.state.sortedList.map(function(room) { return this.state.sortedList.map(function(room) {
var selected = room.roomId == self.props.selectedRoom; var selected = room.roomId == self.props.selectedRoom;
// XXX: is it evil to pass in self as a prop to RoomTile? // XXX: is it evil to pass in self as a prop to RoomTile?
@ -235,7 +246,7 @@ var RoomSubList = React.createClass({
render: function() { render: function() {
var connectDropTarget = this.props.connectDropTarget; var connectDropTarget = this.props.connectDropTarget;
var RoomDropTarget = sdk.getComponent('molecules.RoomDropTarget'); var RoomDropTarget = sdk.getComponent('rooms.RoomDropTarget');
var label = this.props.collapsed ? null : this.props.label; var label = this.props.collapsed ? null : this.props.label;
@ -265,7 +276,7 @@ var RoomSubList = React.createClass({
return connectDropTarget( return connectDropTarget(
<div> <div>
<h2 onClick={ this.onClick } className="mx_RoomSubList_label">{ this.props.collapsed ? '' : this.props.label } <h2 onClick={ this.onClick } className="mx_RoomSubList_label">{ this.props.collapsed ? '' : this.props.label }
<img className="mx_RoomSubList_chevron" src={ this.state.hidden ? "img/list-open.png" : "img/list-close.png" } width="10" height="10"/> <img className="mx_RoomSubList_chevron" src={ this.state.hidden ? "img/list-open.svg" : "img/list-close.svg" } width="10" height="10"/>
</h2> </h2>
{ subList } { subList }
</div> </div>

View File

@ -20,7 +20,7 @@ var React = require('react');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var DateUtils = require('../../../../DateUtils'); var DateUtils = require('matrix-react-sdk/lib/DateUtils');
var filesize = require('filesize'); var filesize = require('filesize');
module.exports = React.createClass({ module.exports = React.createClass({
@ -30,7 +30,8 @@ module.exports = React.createClass({
onFinished: React.PropTypes.func.isRequired onFinished: React.PropTypes.func.isRequired
}, },
// XXX: keyboard shortcuts for managing dialogs should be done by the modal dialog base class somehow, surely... // XXX: keyboard shortcuts for managing dialogs should be done by the modal
// dialog base class somehow, surely...
componentDidMount: function() { componentDidMount: function() {
document.addEventListener("keydown", this.onKeyDown); document.addEventListener("keydown", this.onKeyDown);
}, },
@ -54,7 +55,7 @@ module.exports = React.createClass({
).done(function() { ).done(function() {
if (self.props.onFinished) self.props.onFinished(); if (self.props.onFinished) self.props.onFinished();
}, function(e) { }, function(e) {
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog"); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
// display error message stating you couldn't delete this. // display error message stating you couldn't delete this.
var code = e.errcode || e.statusCode; var code = e.errcode || e.statusCode;
Modal.createDialog(ErrorDialog, { Modal.createDialog(ErrorDialog, {
@ -104,6 +105,11 @@ module.exports = React.createClass({
res = ", " + style.width + "x" + style.height + "px"; res = ", " + style.width + "x" + style.height + "px";
} }
var size;
if (this.props.mxEvent.getContent().info && this.props.mxEvent.getContent().info.size) {
size = filesize(this.props.mxEvent.getContent().info.size);
}
return ( return (
<div className="mx_ImageView"> <div className="mx_ImageView">
<div className="mx_ImageView_lhs"> <div className="mx_ImageView_lhs">
@ -123,7 +129,7 @@ module.exports = React.createClass({
<a className="mx_ImageView_link" href={ this.props.src } target="_blank"> <a className="mx_ImageView_link" href={ this.props.src } target="_blank">
<div className="mx_ImageView_download"> <div className="mx_ImageView_download">
Download this file<br/> Download this file<br/>
<span className="mx_ImageView_size">({ filesize(this.props.mxEvent.getContent().info.size) }{ res })</span> <span className="mx_ImageView_size">{ size } { res }</span>
</div> </div>
</a> </a>
<div className="mx_ImageView_button"> <div className="mx_ImageView_button">

View File

@ -17,30 +17,28 @@ limitations under the License.
'use strict'; 'use strict';
var React = require('react'); var React = require('react');
var Notifier = require("matrix-react-sdk/lib/Notifier");
var sdk = require('matrix-react-sdk') var sdk = require('matrix-react-sdk')
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'MatrixToolbar', displayName: 'MatrixToolbar',
hideToolbar: function() { hideToolbar: function() {
var Notifier = sdk.getComponent('organisms.Notifier');
Notifier.setToolbarHidden(true); Notifier.setToolbarHidden(true);
}, },
onClick: function() { onClick: function() {
var Notifier = sdk.getComponent('organisms.Notifier');
Notifier.setEnabled(true); Notifier.setEnabled(true);
}, },
render: function() { render: function() {
return ( return (
<div className="mx_MatrixToolbar"> <div className="mx_MatrixToolbar">
<img className="mx_MatrixToolbar_warning" src="img/warning.png" width="28" height="28" alt="/!\"/> <img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="/!\"/>
<div> <div>
You are not receiving desktop notifications. <a className="mx_MatrixToolbar_link" onClick={ this.onClick }>Enable them now</a> You are not receiving desktop notifications. <a className="mx_MatrixToolbar_link" onClick={ this.onClick }>Enable them now</a>
</div> </div>
<div className="mx_MatrixToolbar_close"><img src="img/cancel-black2.png" width="23" height="23" onClick={ this.hideToolbar } /></div> <div className="mx_MatrixToolbar_close"><img src="img/cancel.svg" width="18" height="18" onClick={ this.hideToolbar } /></div>
</div> </div>
); );
} }

View File

@ -14,38 +14,37 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
'use strict'; var React = require("react");
/*
* 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');
var ErrorDialogController = require('matrix-react-sdk/lib/controllers/organisms/ErrorDialog')
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'ErrorDialog', displayName: 'VectorCustomServerDialog',
mixins: [ErrorDialogController], statics: {
replaces: 'CustomServerDialog',
},
render: function() { render: function() {
return ( return (
<div className="mx_ErrorDialog"> <div className="mx_ErrorDialog">
<div className="mx_ErrorDialogTitle"> <div className="mx_ErrorDialogTitle">
{this.props.title} Custom Server Options
</div> </div>
<div className="mx_Dialog_content"> <div className="mx_Dialog_content">
{this.props.description} <span>
You can use the custom server options to log into other Matrix
servers by specifying a different Home server URL.
<br/>
This allows you to use Vector with an existing Matrix account on
a different Home server.
<br/>
<br/>
You can also set a custom Identity server but this will affect
people&#39;s ability to find you if you use a server in a group other
than the main Matrix.org group.
</span>
</div> </div>
<div className="mx_Dialog_buttons"> <div className="mx_Dialog_buttons">
<button onClick={this.props.onFinished} autoFocus={this.props.focus}> <button onClick={this.props.onFinished} autoFocus={true}>
{this.props.button} Dismiss
</button> </button>
</div> </div>
</div> </div>

View File

@ -18,26 +18,20 @@ limitations under the License.
var React = require('react'); var React = require('react');
var TextForEvent = require('matrix-react-sdk/lib/TextForEvent');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'EventAsTextTile', displayName: 'VectorLoginFooter',
statics: { statics: {
needsSenderProfile: function() { replaces: 'LoginFooter',
return false;
}
}, },
render: function() { render: function() {
var text = TextForEvent.textForEvent(this.props.mxEvent);
if (text == null || text.length == 0) return null;
return ( return (
<div className="mx_EventAsTextTile"> <div className="mx_Login_links">
{TextForEvent.textForEvent(this.props.mxEvent)} <a href="https://medium.com/@Vector">blog</a>&nbsp;&nbsp;&middot;&nbsp;&nbsp;
<a href="https://twitter.com/@VectorCo">twitter</a>&nbsp;&nbsp;&middot;&nbsp;&nbsp;
<a href="https://github.com/vector-im/vector-web">github</a>&nbsp;&nbsp;&middot;&nbsp;&nbsp;
<a href="https://matrix.org">powered by Matrix</a>
</div> </div>
); );
}, }
}); });

View File

@ -19,13 +19,16 @@ limitations under the License.
var React = require('react'); var React = require('react');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'VideoFeed', displayName: 'VectorLoginHeader',
statics: {
replaces: 'LoginHeader',
},
render: function() { render: function() {
return ( return (
<video> <div className="mx_Login_logo">
</video> <img src="img/logo.png" width="249" height="78" alt="vector"/>
</div>
); );
}, }
}); });

View File

@ -17,7 +17,7 @@ limitations under the License.
'use strict'; 'use strict';
var React = require('react'); var React = require('react');
var DateUtils = require('../../../../DateUtils'); var DateUtils = require('matrix-react-sdk/lib/DateUtils');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'MessageTimestamp', displayName: 'MessageTimestamp',

View File

@ -18,19 +18,20 @@ limitations under the License.
var React = require('react'); var React = require('react');
var MEmoteTileController = require('matrix-react-sdk/lib/controllers/molecules/MEmoteTile')
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'MEmoteTile', displayName: 'SenderProfile',
mixins: [MEmoteTileController],
render: function() { render: function() {
var mxEvent = this.props.mxEvent; var mxEvent = this.props.mxEvent;
var content = mxEvent.getContent();
var name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender(); var name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
var msgtype = mxEvent.getContent().msgtype;
if (msgtype && msgtype == 'm.emote') {
name = ''; // emote message must include the name so don't duplicate it
}
return ( return (
<span ref="content" className="mx_MEmoteTile mx_MessageTile_content"> <span className="mx_SenderProfile">
* {name} {content.body} {name} { this.props.aux }
</span> </span>
); );
}, },

View File

@ -41,7 +41,7 @@ module.exports = React.createClass({
label = <div className="mx_RoomTile_name">{ this.props.label }</div>; label = <div className="mx_RoomTile_name">{ this.props.label }</div>;
} }
else if (this.state.hover) { else if (this.state.hover) {
var RoomTooltip = sdk.getComponent("molecules.RoomTooltip"); var RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
label = <RoomTooltip bottom={ true } label={ this.props.label }/>; label = <RoomTooltip bottom={ true } label={ this.props.label }/>;
} }

View File

@ -22,7 +22,7 @@ var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var dis = require('matrix-react-sdk/lib/dispatcher'); var dis = require('matrix-react-sdk/lib/dispatcher');
var sdk = require('matrix-react-sdk') var sdk = require('matrix-react-sdk')
var Modal = require('matrix-react-sdk/lib/Modal'); var Modal = require('matrix-react-sdk/lib/Modal');
var Resend = require("../../../../Resend"); var Resend = require("matrix-react-sdk/lib/Resend");
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'MessageContextMenu', displayName: 'MessageContextMenu',
@ -33,7 +33,7 @@ module.exports = React.createClass({
}, },
onViewSourceClick: function() { onViewSourceClick: function() {
var ViewSource = sdk.getComponent('organisms.ViewSource'); var ViewSource = sdk.getComponent('structures.ViewSource');
Modal.createDialog(ViewSource, { Modal.createDialog(ViewSource, {
mxEvent: this.props.mxEvent mxEvent: this.props.mxEvent
}); });
@ -46,7 +46,7 @@ module.exports = React.createClass({
).done(function() { ).done(function() {
// message should disappear by itself // message should disappear by itself
}, function(e) { }, function(e) {
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog"); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
// display error message stating you couldn't delete this. // display error message stating you couldn't delete this.
var code = e.errcode || e.statusCode; var code = e.errcode || e.statusCode;
Modal.createDialog(ErrorDialog, { Modal.createDialog(ErrorDialog, {
@ -57,25 +57,42 @@ module.exports = React.createClass({
if (this.props.onFinished) this.props.onFinished(); if (this.props.onFinished) this.props.onFinished();
}, },
onCancelSendClick: function() {
Resend.removeFromQueue(this.props.mxEvent);
if (this.props.onFinished) this.props.onFinished();
},
render: function() { render: function() {
var eventStatus = this.props.mxEvent.status;
var resendButton; var resendButton;
var viewSourceButton; var viewSourceButton;
var redactButton; var redactButton;
var cancelButton;
if (this.props.mxEvent.status == 'not_sent') { if (eventStatus === 'not_sent') {
resendButton = ( resendButton = (
<div className="mx_ContextualMenu_field" onClick={this.onResendClick}> <div className="mx_ContextualMenu_field" onClick={this.onResendClick}>
Resend Resend
</div> </div>
); );
} }
else {
if (!eventStatus) { // sent
redactButton = ( redactButton = (
<div className="mx_ContextualMenu_field" onClick={this.onRedactClick}> <div className="mx_ContextualMenu_field" onClick={this.onRedactClick}>
Redact Redact
</div> </div>
); );
} }
if (eventStatus === "queued" || eventStatus === "not_sent") {
cancelButton = (
<div className="mx_ContextualMenu_field" onClick={this.onCancelSendClick}>
Cancel Sending
</div>
);
}
viewSourceButton = ( viewSourceButton = (
<div className="mx_ContextualMenu_field" onClick={this.onViewSourceClick}> <div className="mx_ContextualMenu_field" onClick={this.onViewSourceClick}>
View Source View Source
@ -86,6 +103,7 @@ module.exports = React.createClass({
<div> <div>
{resendButton} {resendButton}
{redactButton} {redactButton}
{cancelButton}
{viewSourceButton} {viewSourceButton}
</div> </div>
); );

View File

@ -19,13 +19,11 @@ limitations under the License.
var React = require('react'); var React = require('react');
var DragSource = require('react-dnd').DragSource; var DragSource = require('react-dnd').DragSource;
var DropTarget = require('react-dnd').DropTarget; var DropTarget = require('react-dnd').DropTarget;
var classNames = require('classnames');
var RoomTileController = require('matrix-react-sdk/lib/controllers/molecules/RoomTile')
var dis = require("matrix-react-sdk/lib/dispatcher");
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var sdk = require('matrix-react-sdk');
var sdk = require('matrix-react-sdk') var RoomTile = require('matrix-react-sdk/lib/components/views/rooms/RoomTile');
/** /**
* Specifies the drag source contract. * Specifies the drag source contract.
@ -69,7 +67,7 @@ var roomTileSource = {
if (monitor.didDrop() && item.targetList.props.editable) { if (monitor.didDrop() && item.targetList.props.editable) {
// if we moved lists, remove the old tag // if we moved lists, remove the old tag
if (item.targetList !== item.originalList) { if (item.targetList !== item.originalList && item.originalList.props.tagName) {
// commented out attempts to set a spinner on our target component as component is actually // commented out attempts to set a spinner on our target component as component is actually
// the original source component being dragged, not our target. To fix we just need to // the original source component being dragged, not our target. To fix we just need to
// move all of this to endDrop in the target instead. FIXME later. // move all of this to endDrop in the target instead. FIXME later.
@ -78,7 +76,7 @@ var roomTileSource = {
MatrixClientPeg.get().deleteRoomTag(item.room.roomId, item.originalList.props.tagName).finally(function() { MatrixClientPeg.get().deleteRoomTag(item.room.roomId, item.originalList.props.tagName).finally(function() {
//component.state.set({ spinner: component.state.spinner-- }); //component.state.set({ spinner: component.state.spinner-- });
}).fail(function(err) { }).fail(function(err) {
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog"); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, { Modal.createDialog(ErrorDialog, {
title: "Failed to remove tag " + item.originalList.props.tagName + " from room", title: "Failed to remove tag " + item.originalList.props.tagName + " from room",
description: err.toString() description: err.toString()
@ -97,7 +95,7 @@ var roomTileSource = {
MatrixClientPeg.get().setRoomTag(item.room.roomId, item.targetList.props.tagName, newOrder).finally(function() { MatrixClientPeg.get().setRoomTag(item.room.roomId, item.targetList.props.tagName, newOrder).finally(function() {
//component.state.set({ spinner: component.state.spinner-- }); //component.state.set({ spinner: component.state.spinner-- });
}).fail(function(err) { }).fail(function(err) {
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog"); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, { Modal.createDialog(ErrorDialog, {
title: "Failed to add tag " + item.targetList.props.tagName + " to room", title: "Failed to add tag " + item.targetList.props.tagName + " to room",
description: err.toString() description: err.toString()
@ -183,117 +181,6 @@ var roomTileTarget = {
}, },
}; };
var RoomTile = React.createClass({
displayName: 'RoomTile',
mixins: [RoomTileController],
propTypes: {
connectDragSource: React.PropTypes.func.isRequired,
connectDropTarget: React.PropTypes.func.isRequired,
isDragging: React.PropTypes.bool.isRequired,
room: React.PropTypes.object.isRequired,
collapsed: React.PropTypes.bool.isRequired,
selected: React.PropTypes.bool.isRequired,
unread: React.PropTypes.bool.isRequired,
highlight: React.PropTypes.bool.isRequired,
isInvite: React.PropTypes.bool.isRequired,
roomSubList: React.PropTypes.object.isRequired,
},
getInitialState: function() {
return( { hover : false });
},
onMouseEnter: function() {
this.setState( { hover : true });
},
onMouseLeave: function() {
this.setState( { hover : false });
},
render: function() {
// if (this.props.clientOffset) {
// //console.log("room " + this.props.room.roomId + " has dropTarget clientOffset " + this.props.clientOffset.x + "," + this.props.clientOffset.y);
// }
/*
if (this.props.room._dragging) {
var RoomDropTarget = sdk.getComponent("molecules.RoomDropTarget");
return <RoomDropTarget placeholder={true}/>;
}
*/
var myUserId = MatrixClientPeg.get().credentials.userId;
var me = this.props.room.currentState.members[myUserId];
var classes = classNames({
'mx_RoomTile': true,
'mx_RoomTile_selected': this.props.selected,
'mx_RoomTile_unread': this.props.unread,
'mx_RoomTile_highlight': this.props.highlight,
'mx_RoomTile_invited': (me && me.membership == 'invite'),
});
var name;
if (this.props.isInvite) {
name = this.props.room.getMember(myUserId).events.member.getSender();
}
else {
// XXX: We should never display raw room IDs, but sometimes the room name js sdk gives is undefined
name = this.props.room.name || this.props.room.roomId;
}
name = name.replace(":", ":\u200b"); // add a zero-width space to allow linewrapping after the colon
var badge;
if (this.props.highlight) {
badge = <div className="mx_RoomTile_badge"/>;
}
/*
if (this.props.highlight) {
badge = <div className="mx_RoomTile_badge">!</div>;
}
else if (this.props.unread) {
badge = <div className="mx_RoomTile_badge">1</div>;
}
var nameCell;
if (badge) {
nameCell = <div className="mx_RoomTile_nameBadge"><div className="mx_RoomTile_name">{name}</div><div className="mx_RoomTile_badgeCell">{badge}</div></div>;
}
else {
nameCell = <div className="mx_RoomTile_name">{name}</div>;
}
*/
var label;
if (!this.props.collapsed) {
var className = 'mx_RoomTile_name' + (this.props.isInvite ? ' mx_RoomTile_invite' : '');
label = <div className={ className }>{name}</div>;
}
else if (this.state.hover) {
var RoomTooltip = sdk.getComponent("molecules.RoomTooltip");
label = <RoomTooltip room={this.props.room}/>;
}
var RoomAvatar = sdk.getComponent('atoms.RoomAvatar');
// These props are injected by React DnD,
// as defined by your `collect` function above:
var isDragging = this.props.isDragging;
var connectDragSource = this.props.connectDragSource;
var connectDropTarget = this.props.connectDropTarget;
return connectDragSource(connectDropTarget(
<div className={classes} onClick={this.onClick} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
<div className="mx_RoomTile_avatar">
<RoomAvatar room={this.props.room} width="24" height="24" />
{ badge }
</div>
{ label }
</div>
));
}
});
// Export the wrapped version, inlining the 'collect' functions // Export the wrapped version, inlining the 'collect' functions
// to more closely resemble the ES7 // to more closely resemble the ES7
module.exports = module.exports =
@ -314,3 +201,5 @@ DragSource('RoomTile', roomTileSource, function(connect, monitor) {
isDragging: monitor.isDragging() isDragging: monitor.isDragging()
}; };
})(RoomTile)); })(RoomTile));
module.exports.replaces = 'RoomTile';

View File

@ -19,6 +19,7 @@ limitations under the License.
var React = require('react'); var React = require('react');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var sdk = require('matrix-react-sdk'); var sdk = require('matrix-react-sdk');
var classNames = require('classnames');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'SearchBar', displayName: 'SearchBar',
@ -39,17 +40,29 @@ module.exports = React.createClass({
onSearchChange: function(e) { onSearchChange: function(e) {
if (e.keyCode === 13) { // on enter... if (e.keyCode === 13) { // on enter...
this.props.onSearch(this.refs.search_term.value, this.state.scope); this.onSearch();
}
if (e.keyCode === 27) { // escape...
this.props.onCancelClick();
} }
}, },
onSearch: function() {
this.props.onSearch(this.refs.search_term.value, this.state.scope);
},
render: function() { render: function() {
var searchButtonClasses = classNames({ mx_SearchBar_searchButton : true, mx_SearchBar_searching: this.props.searchInProgress });
var thisRoomClasses = classNames({ mx_SearchBar_button : true, mx_SearchBar_unselected : this.state.scope !== 'Room' });
var allRoomsClasses = classNames({ mx_SearchBar_button : true, mx_SearchBar_unselected : this.state.scope !== 'All' });
return ( return (
<div className="mx_SearchBar"> <div className="mx_SearchBar">
<input ref="search_term" className="mx_SearchBar_input" type="text" autoFocus={true} placeholder="Search..." onKeyDown={this.onSearchChange}/> <input ref="search_term" className="mx_SearchBar_input" type="text" autoFocus={true} placeholder="Search..." onKeyDown={this.onSearchChange}/>
<div className={"mx_SearchBar_button" + (this.state.scope !== 'Room' ? " mx_SearchBar_unselected" : "")} onClick={this.onThisRoomClick}>This Room</div> <div className={ searchButtonClasses } onClick={this.onSearch}><img src="img/search-button.svg" width="37" height="37" alt="Search"/></div>
<div className={"mx_SearchBar_button" + (this.state.scope !== 'All' ? " mx_SearchBar_unselected" : "")} onClick={this.onAllRoomsClick}>All Rooms</div> <div className={ thisRoomClasses } onClick={this.onThisRoomClick}>This Room</div>
<img className="mx_SearchBar_cancel" src="img/cancel-black.png" width="18" height="18" onClick={this.props.onCancelClick} /> <div className={ allRoomsClasses } onClick={this.onAllRoomsClick}>All Rooms</div>
<img className="mx_SearchBar_cancel" src="img/cancel.svg" width="18" height="18" onClick={this.props.onCancelClick} />
</div> </div>
); );
} }

View File

@ -1,97 +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';
var dis = require("matrix-react-sdk/lib/dispatcher");
var CallHandler = require("matrix-react-sdk/lib/CallHandler");
var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
var VectorConferenceHandler = require('../../../modules/VectorConferenceHandler');
/*
* State vars:
* this.state.call = MatrixCall|null
*
* Props:
* this.props.room = Room (JS SDK)
*
* Internal state:
* this._trackedRoom = (either from props.room or programatically set)
*/
module.exports = {
componentDidMount: function() {
this.dispatcherRef = dis.register(this.onAction);
this._trackedRoom = null;
if (this.props.room) {
this._trackedRoom = this.props.room;
this.showCall(this._trackedRoom.roomId);
}
else {
var call = CallHandler.getAnyActiveCall();
if (call) {
console.log(
"Global CallView is now tracking active call in room %s",
call.roomId
);
this._trackedRoom = MatrixClientPeg.get().getRoom(call.roomId);
this.showCall(call.roomId);
}
}
},
componentWillUnmount: function() {
dis.unregister(this.dispatcherRef);
},
onAction: function(payload) {
// don't filter out payloads for room IDs other than props.room because
// we may be interested in the conf 1:1 room
if (payload.action !== 'call_state' || !payload.room_id) {
return;
}
this.showCall(payload.room_id);
},
showCall: function(roomId) {
var call = (
CallHandler.getCallForRoom(roomId) ||
VectorConferenceHandler.getConferenceCallForRoom(roomId)
);
if (call) {
call.setLocalVideoElement(this.getVideoView().getLocalVideoElement());
call.setRemoteVideoElement(this.getVideoView().getRemoteVideoElement());
// give a separate element for audio stream playback - both for voice calls
// and for the voice stream of screen captures
call.setRemoteAudioElement(this.getVideoView().getRemoteAudioElement());
}
if (call && call.type === "video" && call.state !== 'ended') {
// if this call is a conf call, don't display local video as the
// conference will have us in it
this.getVideoView().getLocalVideoElement().style.display = (
call.confUserId ? "none" : "initial"
);
this.getVideoView().getRemoteVideoElement().style.display = "initial";
}
else {
this.getVideoView().getLocalVideoElement().style.display = "none";
this.getVideoView().getRemoteVideoElement().style.display = "none";
dis.dispatch({action: 'video_fullscreen', fullscreen: false});
}
}
};

View File

@ -1,201 +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';
var React = require("react");
var ReactDOM = require("react-dom");
var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
var RoomListSorter = require("matrix-react-sdk/lib/RoomListSorter");
var dis = require("matrix-react-sdk/lib/dispatcher");
var sdk = require('matrix-react-sdk');
var VectorConferenceHandler = require("../../modules/VectorConferenceHandler");
var HIDE_CONFERENCE_CHANS = true;
module.exports = {
getInitialState: function() {
return {
activityMap: null,
lists: {},
}
},
componentWillMount: function() {
var cli = MatrixClientPeg.get();
cli.on("Room", this.onRoom);
cli.on("Room.timeline", this.onRoomTimeline);
cli.on("Room.name", this.onRoomName);
cli.on("Room.tags", this.onRoomTags);
cli.on("RoomState.events", this.onRoomStateEvents);
cli.on("RoomMember.name", this.onRoomMemberName);
var s = this.getRoomLists();
s.activityMap = {};
this.setState(s);
},
componentDidMount: function() {
this.dispatcherRef = dis.register(this.onAction);
},
onAction: function(payload) {
switch (payload.action) {
case 'view_tooltip':
this.tooltip = payload.tooltip;
this._repositionTooltip();
if (this.tooltip) this.tooltip.style.display = 'block';
break
}
},
componentWillUnmount: function() {
dis.unregister(this.dispatcherRef);
if (MatrixClientPeg.get()) {
MatrixClientPeg.get().removeListener("Room", this.onRoom);
MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
MatrixClientPeg.get().removeListener("Room.name", this.onRoomName);
MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents);
}
},
componentWillReceiveProps: function(newProps) {
this.state.activityMap[newProps.selectedRoom] = undefined;
this.setState({
activityMap: this.state.activityMap
});
},
onRoom: function(room) {
this.refreshRoomList();
},
onRoomTimeline: function(ev, room, toStartOfTimeline) {
if (toStartOfTimeline) return;
var newState = this.getRoomLists();
if (
room.roomId != this.props.selectedRoom &&
ev.getSender() != MatrixClientPeg.get().credentials.userId)
{
var hl = 1;
var actions = MatrixClientPeg.get().getPushActionsForEvent(ev);
if (actions && actions.tweaks && actions.tweaks.highlight) {
hl = 2;
}
// obviously this won't deep copy but this shouldn't be necessary
var amap = this.state.activityMap;
amap[room.roomId] = Math.max(amap[room.roomId] || 0, hl);
newState.activityMap = amap;
}
this.setState(newState);
},
onRoomName: function(room) {
this.refreshRoomList();
},
onRoomTags: function(event, room) {
this.refreshRoomList();
},
onRoomStateEvents: function(ev, state) {
setTimeout(this.refreshRoomList, 0);
},
onRoomMemberName: function(ev, member) {
setTimeout(this.refreshRoomList, 0);
},
refreshRoomList: function() {
// TODO: rather than bluntly regenerating and re-sorting everything
// every time we see any kind of room change from the JS SDK
// we could do incremental updates on our copy of the state
// based on the room which has actually changed. This would stop
// us re-rendering all the sublists every time anything changes anywhere
// in the state of the client.
this.setState(this.getRoomLists());
},
getRoomLists: function() {
var s = { lists: {} };
s.lists["m.invite"] = [];
s.lists["m.favourite"] = [];
s.lists["m.recent"] = [];
s.lists["m.lowpriority"] = [];
s.lists["m.archived"] = [];
MatrixClientPeg.get().getRooms().forEach(function(room) {
var me = room.getMember(MatrixClientPeg.get().credentials.userId);
if (me && me.membership == "invite") {
s.lists["m.invite"].push(room);
}
else {
var shouldShowRoom = (
me && (me.membership == "join")
);
// hiding conf rooms only ever toggles shouldShowRoom to false
if (shouldShowRoom && HIDE_CONFERENCE_CHANS) {
// we want to hide the 1:1 conf<->user room and not the group chat
var joinedMembers = room.getJoinedMembers();
if (joinedMembers.length === 2) {
var otherMember = joinedMembers.filter(function(m) {
return m.userId !== me.userId
})[0];
if (VectorConferenceHandler.isConferenceUser(otherMember)) {
// console.log("Hiding conference 1:1 room %s", room.roomId);
shouldShowRoom = false;
}
}
}
if (shouldShowRoom) {
var tagNames = Object.keys(room.tags);
if (tagNames.length) {
for (var i = 0; i < tagNames.length; i++) {
var tagName = tagNames[i];
s.lists[tagName] = s.lists[tagName] || [];
s.lists[tagNames[i]].push(room);
}
}
else {
s.lists["m.recent"].push(room);
}
}
}
});
//console.log("calculated new roomLists; m.recent = " + s.lists["m.recent"]);
// we actually apply the sorting to this when receiving the prop in RoomSubLists.
return s;
},
_repositionTooltip: function(e) {
if (this.tooltip && this.tooltip.parentElement) {
var scroll = ReactDOM.findDOMNode(this);
this.tooltip.style.top = (scroll.parentElement.offsetTop + this.tooltip.parentElement.offsetTop - scroll.children[2].scrollTop) + "px";
}
},
};

View File

@ -1,628 +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.
*/
var Matrix = require("matrix-js-sdk");
var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
var React = require("react");
var ReactDOM = require("react-dom");
var q = require("q");
var ContentMessages = require("matrix-react-sdk/lib//ContentMessages");
var WhoIsTyping = require("matrix-react-sdk/lib/WhoIsTyping");
var Modal = require("matrix-react-sdk/lib/Modal");
var sdk = require('matrix-react-sdk/lib/index');
var CallHandler = require('matrix-react-sdk/lib/CallHandler');
var VectorConferenceHandler = require('../../modules/VectorConferenceHandler');
var Resend = require("../../Resend");
var dis = require("matrix-react-sdk/lib/dispatcher");
var PAGINATE_SIZE = 20;
var INITIAL_SIZE = 20;
module.exports = {
getInitialState: function() {
var room = this.props.roomId ? MatrixClientPeg.get().getRoom(this.props.roomId) : null;
return {
room: room,
messageCap: INITIAL_SIZE,
editingRoomSettings: false,
uploadingRoomSettings: false,
numUnreadMessages: 0,
draggingFile: false,
searching: false,
searchResults: null,
syncState: MatrixClientPeg.get().getSyncState(),
hasUnsentMessages: this._hasUnsentMessages(room)
}
},
componentWillMount: function() {
this.dispatcherRef = dis.register(this.onAction);
MatrixClientPeg.get().on("Room.timeline", this.onRoomTimeline);
MatrixClientPeg.get().on("Room.name", this.onRoomName);
MatrixClientPeg.get().on("RoomMember.typing", this.onRoomMemberTyping);
MatrixClientPeg.get().on("RoomState.members", this.onRoomStateMember);
MatrixClientPeg.get().on("sync", this.onSyncStateChange);
this.atBottom = true;
},
componentWillUnmount: function() {
if (this.refs.messagePanel) {
var messagePanel = ReactDOM.findDOMNode(this.refs.messagePanel);
messagePanel.removeEventListener('drop', this.onDrop);
messagePanel.removeEventListener('dragover', this.onDragOver);
messagePanel.removeEventListener('dragleave', this.onDragLeaveOrEnd);
messagePanel.removeEventListener('dragend', this.onDragLeaveOrEnd);
}
dis.unregister(this.dispatcherRef);
if (MatrixClientPeg.get()) {
MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
MatrixClientPeg.get().removeListener("Room.name", this.onRoomName);
MatrixClientPeg.get().removeListener("RoomMember.typing", this.onRoomMemberTyping);
MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember);
MatrixClientPeg.get().removeListener("sync", this.onSyncStateChange);
}
},
onAction: function(payload) {
switch (payload.action) {
case 'message_send_failed':
case 'message_sent':
this.setState({
hasUnsentMessages: this._hasUnsentMessages(this.state.room)
});
case 'message_resend_started':
this.setState({
room: MatrixClientPeg.get().getRoom(this.props.roomId)
});
this.forceUpdate();
break;
case 'notifier_enabled':
this.forceUpdate();
break;
case 'call_state':
if (CallHandler.getCallForRoom(this.props.roomId)) {
// Call state has changed so we may be loading video elements
// which will obscure the message log.
// scroll to bottom
var scrollNode = this._getScrollNode();
if (scrollNode) {
scrollNode.scrollTop = scrollNode.scrollHeight;
}
}
// possibly remove the conf call notification if we're now in
// the conf
this._updateConfCallNotification();
break;
}
},
_getScrollNode: function() {
var panel = ReactDOM.findDOMNode(this.refs.messagePanel);
if (!panel) return null;
if (panel.classList.contains('gm-prevented')) {
return panel;
} else {
return panel.children[2]; // XXX: Fragile!
}
},
onSyncStateChange: function(state) {
this.setState({
syncState: state
});
},
// MatrixRoom still showing the messages from the old room?
// Set the key to the room_id. Sadly you can no longer get at
// the key from inside the component, or we'd check this in code.
/*componentWillReceiveProps: function(props) {
},*/
onRoomTimeline: function(ev, room, toStartOfTimeline) {
if (!this.isMounted()) return;
// ignore anything that comes in whilst paginating: we get one
// event for each new matrix event so this would cause a huge
// number of UI updates. Just update the UI when the paginate
// call returns.
if (this.state.paginating) return;
// no point handling anything while we're waiting for the join to finish:
// we'll only be showing a spinner.
if (this.state.joining) return;
if (room.roomId != this.props.roomId) return;
var scrollNode = this._getScrollNode();
if (scrollNode) {
this.atBottom = (
scrollNode.scrollHeight - scrollNode.scrollTop <=
(scrollNode.clientHeight + 150) // 150?
);
}
var currentUnread = this.state.numUnreadMessages;
if (!toStartOfTimeline &&
(ev.getSender() !== MatrixClientPeg.get().credentials.userId)) {
// update unread count when scrolled up
if (this.atBottom) {
currentUnread = 0;
}
else {
currentUnread += 1;
}
}
this.setState({
room: MatrixClientPeg.get().getRoom(this.props.roomId),
numUnreadMessages: currentUnread
});
if (toStartOfTimeline && !this.state.paginating) {
this.fillSpace();
}
},
onRoomName: function(room) {
if (room.roomId == this.props.roomId) {
this.setState({
room: room
});
}
},
onRoomMemberTyping: function(ev, member) {
this.forceUpdate();
},
onRoomStateMember: function(ev, state, member) {
if (member.roomId !== this.props.roomId ||
member.userId !== VectorConferenceHandler.getConferenceUserIdForRoom(member.roomId)) {
return;
}
this._updateConfCallNotification();
},
_hasUnsentMessages: function(room) {
return this._getUnsentMessages(room).length > 0;
},
_getUnsentMessages: function(room) {
if (!room) { return []; }
// TODO: It would be nice if the JS SDK provided nicer constant-time
// constructs rather than O(N) (N=num msgs) on this.
return room.timeline.filter(function(ev) {
return ev.status === Matrix.EventStatus.NOT_SENT;
});
},
_updateConfCallNotification: function() {
var room = MatrixClientPeg.get().getRoom(this.props.roomId);
if (!room) return;
var confMember = room.getMember(
VectorConferenceHandler.getConferenceUserIdForRoom(this.props.roomId)
);
if (!confMember) {
return;
}
var confCall = VectorConferenceHandler.getConferenceCallForRoom(confMember.roomId);
// A conf call notification should be displayed if there is an ongoing
// conf call but this cilent isn't a part of it.
this.setState({
displayConfCallNotification: (
(!confCall || confCall.call_state === "ended") &&
confMember.membership === "join"
)
});
},
componentDidMount: function() {
if (this.refs.messagePanel) {
var messagePanel = ReactDOM.findDOMNode(this.refs.messagePanel);
messagePanel.addEventListener('drop', this.onDrop);
messagePanel.addEventListener('dragover', this.onDragOver);
messagePanel.addEventListener('dragleave', this.onDragLeaveOrEnd);
messagePanel.addEventListener('dragend', this.onDragLeaveOrEnd);
var messageWrapperScroll = this._getScrollNode();
messageWrapperScroll.scrollTop = messageWrapperScroll.scrollHeight;
this.fillSpace();
}
this._updateConfCallNotification();
},
componentDidUpdate: function() {
if (!this.refs.messagePanel) return;
var messageWrapperScroll = this._getScrollNode();
if (this.state.paginating && !this.waiting_for_paginate) {
var heightGained = messageWrapperScroll.scrollHeight - this.oldScrollHeight;
messageWrapperScroll.scrollTop += heightGained;
this.oldScrollHeight = undefined;
if (!this.fillSpace()) {
this.setState({paginating: false});
}
} else if (this.atBottom) {
messageWrapperScroll.scrollTop = messageWrapperScroll.scrollHeight;
if (this.state.numUnreadMessages !== 0) {
this.setState({numUnreadMessages: 0});
}
}
},
fillSpace: function() {
if (!this.refs.messagePanel) return;
var messageWrapperScroll = this._getScrollNode();
if (messageWrapperScroll.scrollTop < messageWrapperScroll.clientHeight && this.state.room.oldState.paginationToken) {
this.setState({paginating: true});
this.oldScrollHeight = messageWrapperScroll.scrollHeight;
if (this.state.messageCap < this.state.room.timeline.length) {
this.waiting_for_paginate = false;
var cap = Math.min(this.state.messageCap + PAGINATE_SIZE, this.state.room.timeline.length);
this.setState({messageCap: cap, paginating: true});
} else {
this.waiting_for_paginate = true;
var cap = this.state.messageCap + PAGINATE_SIZE;
this.setState({messageCap: cap, paginating: true});
var self = this;
MatrixClientPeg.get().scrollback(this.state.room, PAGINATE_SIZE).finally(function() {
self.waiting_for_paginate = false;
if (self.isMounted()) {
self.setState({
room: MatrixClientPeg.get().getRoom(self.props.roomId)
});
}
// wait and set paginating to false when the component updates
});
}
return true;
}
return false;
},
onResendAllClick: function() {
var eventsToResend = this._getUnsentMessages(this.state.room);
eventsToResend.forEach(function(event) {
Resend.resend(event);
});
},
onJoinButtonClicked: function(ev) {
var self = this;
MatrixClientPeg.get().joinRoom(this.props.roomId).then(function() {
self.setState({
joining: false,
room: MatrixClientPeg.get().getRoom(self.props.roomId)
});
}, function(error) {
self.setState({
joining: false,
joinError: error
});
});
this.setState({
joining: true
});
},
onMessageListScroll: function(ev) {
if (this.refs.messagePanel) {
var messageWrapperScroll = this._getScrollNode();
var wasAtBottom = this.atBottom;
this.atBottom = messageWrapperScroll.scrollHeight - messageWrapperScroll.scrollTop <= messageWrapperScroll.clientHeight + 1;
if (this.atBottom && !wasAtBottom) {
this.forceUpdate(); // remove unread msg count
}
}
if (!this.state.paginating) this.fillSpace();
},
onDragOver: function(ev) {
ev.stopPropagation();
ev.preventDefault();
ev.dataTransfer.dropEffect = 'none';
var items = ev.dataTransfer.items;
if (items.length == 1) {
if (items[0].kind == 'file') {
this.setState({ draggingFile : true });
ev.dataTransfer.dropEffect = 'copy';
}
}
},
onDrop: function(ev) {
ev.stopPropagation();
ev.preventDefault();
this.setState({ draggingFile : false });
var files = ev.dataTransfer.files;
if (files.length == 1) {
this.uploadFile(files[0]);
}
},
onDragLeaveOrEnd: function(ev) {
ev.stopPropagation();
ev.preventDefault();
this.setState({ draggingFile : false });
},
uploadFile: function(file) {
this.setState({
upload: {
fileName: file.name,
uploadedBytes: 0,
totalBytes: file.size
}
});
var self = this;
ContentMessages.sendContentToRoom(
file, this.props.roomId, MatrixClientPeg.get()
).progress(function(ev) {
//console.log("Upload: "+ev.loaded+" / "+ev.total);
self.setState({
upload: {
fileName: file.name,
uploadedBytes: ev.loaded,
totalBytes: ev.total
}
});
}).finally(function() {
self.setState({
upload: undefined
});
}).done(undefined, function(error) {
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to upload file",
description: error.toString()
});
});
},
getWhoIsTypingString: function() {
return WhoIsTyping.whoIsTypingString(this.state.room);
},
onSearch: function(term, scope) {
var filter;
if (scope === "Room") { // FIXME: should be enum
filter = {
// XXX: it's unintuitive that the filter for searching doesn't have the same shape as the v2 filter API :(
rooms: [
this.props.roomId
]
};
}
var self = this;
MatrixClientPeg.get().search({
body: {
search_categories: {
room_events: {
search_term: term,
filter: filter,
order_by: "recent",
event_context: {
before_limit: 1,
after_limit: 1,
}
}
}
}
}).then(function(data) {
self.setState({
searchTerm: term,
searchResults: data,
});
}, function(error) {
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Search failed",
description: error.toString()
});
});
},
getEventTiles: function() {
var DateSeparator = sdk.getComponent('molecules.DateSeparator');
var ret = [];
var count = 0;
var EventTile = sdk.getComponent('molecules.EventTile');
if (this.state.searchResults) {
// XXX: this dance is foul, due to the results API not returning sorted results
var results = this.state.searchResults.search_categories.room_events.results;
var eventIds = Object.keys(results);
// XXX: todo: merge overlapping results somehow?
// XXX: why doesn't searching on name work?
var resultList = eventIds.map(function(key) { return results[key]; }); // .sort(function(a, b) { b.rank - a.rank });
for (var i = 0; i < resultList.length; i++) {
var ts1 = resultList[i].result.origin_server_ts;
ret.push(<li key={ts1 + "-search"}><DateSeparator ts={ts1}/></li>); // Rank: {resultList[i].rank}
var mxEv = new Matrix.MatrixEvent(resultList[i].result);
if (resultList[i].context.events_before[0]) {
var mxEv2 = new Matrix.MatrixEvent(resultList[i].context.events_before[0]);
if (EventTile.haveTileForEvent(mxEv2)) {
ret.push(<li key={mxEv.getId() + "-1"}><EventTile mxEvent={mxEv2} contextual={true} /></li>);
}
}
if (EventTile.haveTileForEvent(mxEv)) {
ret.push(<li key={mxEv.getId() + "+0"}><EventTile mxEvent={mxEv} searchTerm={this.state.searchTerm}/></li>);
}
if (resultList[i].context.events_after[0]) {
var mxEv2 = new Matrix.MatrixEvent(resultList[i].context.events_after[0]);
if (EventTile.haveTileForEvent(mxEv2)) {
ret.push(<li key={mxEv.getId() + "+1"}><EventTile mxEvent={mxEv2} contextual={true} /></li>);
}
}
}
return ret;
}
for (var i = this.state.room.timeline.length-1; i >= 0 && count < this.state.messageCap; --i) {
var mxEv = this.state.room.timeline[i];
if (!EventTile.haveTileForEvent(mxEv)) {
continue;
}
var continuation = false;
var last = false;
var dateSeparator = null;
if (i == this.state.room.timeline.length - 1) {
last = true;
}
if (i > 0 && count < this.state.messageCap - 1) {
if (this.state.room.timeline[i].sender &&
this.state.room.timeline[i - 1].sender &&
(this.state.room.timeline[i].sender.userId ===
this.state.room.timeline[i - 1].sender.userId) &&
(this.state.room.timeline[i].getType() ==
this.state.room.timeline[i - 1].getType())
)
{
continuation = true;
}
var ts0 = this.state.room.timeline[i - 1].getTs();
var ts1 = this.state.room.timeline[i].getTs();
if (new Date(ts0).toDateString() !== new Date(ts1).toDateString()) {
dateSeparator = <DateSeparator key={ts1} ts={ts1}/>;
continuation = false;
}
}
if (i === 1) { // n.b. 1, not 0, as the 0th event is an m.room.create and so doesn't show on the timeline
var ts1 = this.state.room.timeline[i].getTs();
dateSeparator = <li key={ts1}><DateSeparator ts={ts1}/></li>;
continuation = false;
}
ret.unshift(
<li key={mxEv.getId()}><EventTile mxEvent={mxEv} continuation={continuation} last={last}/></li>
);
if (dateSeparator) {
ret.unshift(dateSeparator);
}
++count;
}
return ret;
},
uploadNewState: function(new_name, new_topic, new_join_rule, new_history_visibility, new_power_levels) {
var old_name = this.state.room.name;
var old_topic = this.state.room.currentState.getStateEvents('m.room.topic', '');
if (old_topic) {
old_topic = old_topic.getContent().topic;
} else {
old_topic = "";
}
var old_join_rule = this.state.room.currentState.getStateEvents('m.room.join_rules', '');
if (old_join_rule) {
old_join_rule = old_join_rule.getContent().join_rule;
} else {
old_join_rule = "invite";
}
var old_history_visibility = this.state.room.currentState.getStateEvents('m.room.history_visibility', '');
if (old_history_visibility) {
old_history_visibility = old_history_visibility.getContent().history_visibility;
} else {
old_history_visibility = "shared";
}
var deferreds = [];
if (old_name != new_name && new_name != undefined && new_name) {
deferreds.push(
MatrixClientPeg.get().setRoomName(this.state.room.roomId, new_name)
);
}
if (old_topic != new_topic && new_topic != undefined) {
deferreds.push(
MatrixClientPeg.get().setRoomTopic(this.state.room.roomId, new_topic)
);
}
if (old_join_rule != new_join_rule && new_join_rule != undefined) {
deferreds.push(
MatrixClientPeg.get().sendStateEvent(
this.state.room.roomId, "m.room.join_rules", {
join_rule: new_join_rule,
}, ""
)
);
}
if (old_history_visibility != new_history_visibility && new_history_visibility != undefined) {
deferreds.push(
MatrixClientPeg.get().sendStateEvent(
this.state.room.roomId, "m.room.history_visibility", {
history_visibility: new_history_visibility,
}, ""
)
);
}
if (new_power_levels) {
deferreds.push(
MatrixClientPeg.get().sendStateEvent(
this.state.room.roomId, "m.room.power_levels", new_power_levels, ""
)
);
}
if (deferreds.length) {
var self = this;
q.all(deferreds).fail(function(err) {
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to set state",
description: err.toString()
});
}).finally(function() {
self.setState({
uploadingRoomSettings: false,
});
});
} else {
this.setState({
editingRoomSettings: false,
uploadingRoomSettings: false,
});
}
}
};

View File

@ -1,58 +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';
var extend = require('matrix-react-sdk/lib/extend');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var BaseRegisterController = require('matrix-react-sdk/lib/controllers/templates/Register.js');
var RegisterController = {};
extend(RegisterController, BaseRegisterController);
RegisterController.onRegistered = function(user_id, access_token) {
MatrixClientPeg.replaceUsingAccessToken(
this.state.hs_url, this.state.is_url, user_id, access_token
);
this.setState({
step: 'profile',
busy: true
});
var self = this;
var cli = MatrixClientPeg.get();
cli.getProfileInfo(cli.credentials.userId).done(function(result) {
self.setState({
avatarUrl: result.avatar_url,
busy: false
});
},
function(err) {
console.err(err);
self.setState({
busy: false
});
});
};
RegisterController.onAccountReady = function() {
if (this.props.onLoggedIn) {
this.props.onLoggedIn();
}
};
module.exports = RegisterController;

View File

@ -0,0 +1,44 @@
.mx_UploadBar {
position: relative;
}
.mx_UploadBar_uploadProgressOuter {
height: 4px;
margin-left: 63px;
margin-top: -1px;
}
.mx_UploadBar_uploadProgressInner {
background-color: #76cfa6;
height: 4px;
}
.mx_UploadBar_uploadFilename {
margin-top: 5px;
margin-left: 65px;
opacity: 0.5;
color: #4a4a4a;
}
.mx_UploadBar_uploadIcon {
float: left;
margin-top: 1px;
margin-left: 14px;
}
.mx_UploadBar_uploadCancel {
float: right;
margin-top: 5px;
margin-right: 10px;
position: relative;
opacity: 0.6;
cursor: pointer;
z-index: 1;
}
.mx_UploadBar_uploadBytes {
float: right;
margin-top: 5px;
margin-right: 30px;
color: #76cfa6;
}

View File

@ -87,13 +87,13 @@ limitations under the License.
} }
.mx_ImageView_name { .mx_ImageView_name {
font-size: 20px; font-size: 18px;
margin-bottom: 6px; margin-bottom: 6px;
pointer-events: all; pointer-events: all;
} }
.mx_ImageView_metadata { .mx_ImageView_metadata {
font-size: 16px; font-size: 15px;
opacity: 0.5; opacity: 0.5;
pointer-events: all; pointer-events: all;
} }
@ -105,13 +105,13 @@ limitations under the License.
margin-bottom: 6px; margin-bottom: 6px;
border-radius: 5px; border-radius: 5px;
background-color: #454545; background-color: #454545;
font-size: 16px; font-size: 14px;
padding: 9px; padding: 9px;
border: 1px solid #fff; border: 1px solid #fff;
} }
.mx_ImageView_size { .mx_ImageView_size {
font-size: 12px; font-size: 11px;
} }
.mx_ImageView_link { .mx_ImageView_link {
@ -121,7 +121,7 @@ limitations under the License.
.mx_ImageView_button { .mx_ImageView_button {
pointer-events: all; pointer-events: all;
font-size: 16px; font-size: 15px;
opacity: 0.5; opacity: 0.5;
margin-top: 18px; margin-top: 18px;
cursor: pointer; cursor: pointer;

View File

@ -20,11 +20,14 @@ limitations under the License.
.mx_MemberAvatar_initial { .mx_MemberAvatar_initial {
position: absolute; position: absolute;
z-index: 1;
color: #fff; color: #fff;
text-align: center; text-align: center;
speak: none; speak: none;
pointer-events: none;
} }
.mx_MemberAvatar_image { .mx_MemberAvatar_image {
border-radius: 20px; border-radius: 20px;
vertical-align: top;
} }

View File

@ -15,6 +15,7 @@ limitations under the License.
*/ */
.mx_RoomAvatar { .mx_RoomAvatar {
vertical-align: middle;
} }
.mx_RoomAvatar_initial { .mx_RoomAvatar_initial {
@ -23,4 +24,5 @@ limitations under the License.
text-align: center; text-align: center;
font-weight: normal ! important; font-weight: normal ! important;
speak: none; speak: none;
pointer-events: none;
} }

View File

@ -22,8 +22,13 @@ html {
} }
body { body {
font-family: 'Myriad Pro', Helvetica, Arial, Sans-Serif; /* Open Sans lacks combining diacritics, so these will fall through
font-size: 16px; to the next font. Helevetica's diacritics however do not combine
nicely with Open Sans (on OSX, at least) and result in a huge
horizontal mess. Arial empirically gets it right, hence prioritising
Arial here. */
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
font-size: 15px;
color: #454545; color: #454545;
border: 0px; border: 0px;
margin: 0px; margin: 0px;
@ -36,7 +41,7 @@ div.error {
h2 { h2 {
color: #454545; color: #454545;
font-weight: 400; font-weight: 400;
font-size: 20px; font-size: 18px;
margin-top: 16px; margin-top: 16px;
margin-bottom: 16px; margin-bottom: 16px;
} }
@ -47,6 +52,12 @@ a:visited {
color: #76cfa6; color: #76cfa6;
} }
input[type=text]:focus, textarea:focus, .mx_RoomSettings textarea:focus {
border: 1px solid #76CFA6;
outline: none;
box-shadow: none;
}
/* XXX: critical hack to GeminiScrollbar to allow them to work in FF 42 and Chrome 48. /* XXX: critical hack to GeminiScrollbar to allow them to work in FF 42 and Chrome 48.
Stop the scrollbar view from pushing out the container's overall sizing, which causes Stop the scrollbar view from pushing out the container's overall sizing, which causes
flexbox to adapt to the new size and cause the view to keep growing. flexbox to adapt to the new size and cause the view to keep growing.
@ -99,19 +110,9 @@ a:visited {
margin: 0 auto; margin: 0 auto;
} }
.mx_Dialog_background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000;
opacity: 0.2;
z-index: 4000;
}
.mx_Dialog_wrapper { .mx_Dialog_wrapper {
position: fixed; position: fixed;
z-index: 4000;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
@ -134,12 +135,22 @@ a:visited {
text-align: center; text-align: center;
z-index: 4010; z-index: 4010;
font-weight: 300; font-weight: 300;
font-size: 16px; font-size: 15px;
position: relative; position: relative;
border-radius: 8px; border-radius: 8px;
max-width: 80%; max-width: 80%;
} }
.mx_Dialog_background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000;
opacity: 0.2;
}
.mx_Dialog_lightbox .mx_Dialog_background { .mx_Dialog_lightbox .mx_Dialog_background {
opacity: 0.85; opacity: 0.85;
} }
@ -167,7 +178,7 @@ a:visited {
height: 36px; height: 36px;
border-radius: 36px; border-radius: 36px;
font-weight: 400; font-weight: 400;
font-size: 16px; font-size: 15px;
color: #fff; color: #fff;
background-color: #76cfa6; background-color: #76cfa6;
margin-left: 8px; margin-left: 8px;
@ -182,6 +193,6 @@ a:visited {
padding: 12px; padding: 12px;
border-bottom: 1px solid #a4a4a4; border-bottom: 1px solid #a4a4a4;
font-weight: bold; font-weight: bold;
font-size: 20px; font-size: 18px;
line-height: 1.4; line-height: 1.4;
} }

View File

@ -1 +0,0 @@
../../../../node_modules/react-gemini-scrollbar/node_modules/gemini-scrollbar/gemini-scrollbar.css

View File

@ -16,4 +16,5 @@ limitations under the License.
.mx_EventAsTextTile { .mx_EventAsTextTile {
opacity: 0.5; opacity: 0.5;
overflow-y: hidden;
} }

View File

@ -25,8 +25,10 @@ limitations under the License.
padding-left: 18px; padding-left: 18px;
padding-right: 12px; padding-right: 12px;
margin-left: -73px; margin-left: -73px;
margin-top: -4px; margin-top: -2px;
float: left; float: left;
position: relative;
top: 0px;
} }
.mx_EventTile_avatar img { .mx_EventTile_avatar img {
@ -41,15 +43,15 @@ limitations under the License.
.mx_EventTile .mx_SenderProfile { .mx_EventTile .mx_SenderProfile {
color: #454545; color: #454545;
opacity: 0.5; opacity: 0.5;
font-size: 14px; font-size: 13px;
margin-bottom: 4px; margin-bottom: 4px;
display: block; display: block;
overflow-y: hidden;
} }
.mx_EventTile .mx_MessageTimestamp { .mx_EventTile .mx_MessageTimestamp {
color: #acacac; color: #acacac;
font-size: 12px; font-size: 11px;
float: right;
} }
.mx_EventTile_line { .mx_EventTile_line {
@ -64,8 +66,39 @@ limitations under the License.
.mx_MessageTile_content { .mx_MessageTile_content {
display: block; display: block;
margin-right: 100px; margin-right: 100px;
overflow-y: hidden;
} }
/* Various markdown overrides */
.mx_MessageTile_content .markdown-body {
font-family: inherit ! important;
white-space: normal ! important;
line-height: inherit ! important;
color: inherit;
font-size: 15px;
}
.mx_MessageTile_content .markdown-body h1,
.mx_MessageTile_content .markdown-body h2,
.mx_MessageTile_content .markdown-body h3,
.mx_MessageTile_content .markdown-body h4,
.mx_MessageTile_content .markdown-body h5,
.mx_MessageTile_content .markdown-body h6
{
font-family: inherit ! important;
}
.mx_MessageTile_content .markdown-body a {
color: #76cfa6;
}
.mx_MessageTile_content .markdown-body .hljs {
display: inherit ! important;
}
/* end of overrides */
.mx_MessageTile_searchHighlight { .mx_MessageTile_searchHighlight {
background-color: #76cfa6; background-color: #76cfa6;
color: #fff; color: #fff;
@ -78,10 +111,12 @@ limitations under the License.
} }
.mx_EventTile_notSent { .mx_EventTile_notSent {
color: #ddd; color: #f44;
} }
.mx_EventTile_highlight { .mx_EventTile_highlight,
.mx_EventTile_highlight .markdown-body
{
color: #FF0064; color: #FF0064;
} }
@ -91,10 +126,18 @@ limitations under the License.
.mx_EventTile_msgOption { .mx_EventTile_msgOption {
float: right; float: right;
text-align: right;
z-index: 1;
position: relative;
width: 90px;
margin-right: 10px;
margin-top: -6px;
} }
.mx_MessageTimestamp { .mx_MessageTimestamp {
display: block;
visibility: hidden; visibility: hidden;
text-align: right;
} }
.mx_EventTile_last .mx_MessageTimestamp { .mx_EventTile_last .mx_MessageTimestamp {
@ -107,8 +150,7 @@ limitations under the License.
.mx_EventTile_editButton { .mx_EventTile_editButton {
position: absolute; position: absolute;
right: 1px; display: inline-block;
top: 15px;
visibility: hidden; visibility: hidden;
} }
@ -123,3 +165,21 @@ limitations under the License.
.mx_EventTile.menu .mx_MessageTimestamp { .mx_EventTile.menu .mx_MessageTimestamp {
visibility: visible; visibility: visible;
} }
.mx_EventTile_readAvatars {
position: relative;
display: inline-block;
width: 14px;
height: 14px;
}
.mx_EventTile_readAvatars .mx_MemberAvatar {
position: absolute;
display: inline-block;
}
.mx_EventTile_readAvatarRemainder {
color: #acacac;
font-size: 11px;
position: absolute;
}

View File

@ -15,5 +15,6 @@ limitations under the License.
*/ */
.mx_MNoticeTile { .mx_MNoticeTile {
white-space: pre-wrap;
opacity: 0.6; opacity: 0.6;
} }

View File

@ -37,8 +37,10 @@ limitations under the License.
} }
.mx_MemberInfo_profileField { .mx_MemberInfo_profileField {
opacity: 0.6; font-color: #999999;
font-size: 14px; font-size: 13px;
position: relative;
background-color: #fff;
} }
.mx_MemberInfo_buttons { .mx_MemberInfo_buttons {
@ -49,7 +51,7 @@ limitations under the License.
cursor: pointer; cursor: pointer;
width: 100px; width: 100px;
text-align: center; text-align: center;
font-size: 12px; font-size: 11px;
background-color: #888; background-color: #888;
color: #fff; color: #fff;
font-weight: bold; font-weight: bold;

View File

@ -25,8 +25,8 @@ limitations under the License.
display: table-cell; display: table-cell;
padding-left: 3px; padding-left: 3px;
padding-right: 12px; padding-right: 12px;
padding-top: 2px; padding-top: 4px;
padding-bottom: 0px; padding-bottom: 4px;
vertical-align: middle; vertical-align: middle;
width: 36px; width: 36px;
height: 36px; height: 36px;
@ -55,13 +55,13 @@ limitations under the License.
} }
.mx_MemberTile_userId { .mx_MemberTile_userId {
font-size: 14px; font-size: 13px;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.mx_MemberTile_presence { .mx_MemberTile_presence {
font-size: 12px; font-size: 11px;
opacity: 0.5; opacity: 0.5;
} }
@ -98,10 +98,6 @@ limitations under the License.
opacity: 0.25; opacity: 0.25;
} }
.mx_MemberTile_zalgo {
font-family: Helvetica, Arial, Sans-Serif;
}
.mx_MemberTile:hover .mx_MessageTimestamp { .mx_MemberTile:hover .mx_MessageTimestamp {
display: block; display: block;
} }

View File

@ -59,7 +59,7 @@ limitations under the License.
box-shadow: none; box-shadow: none;
/* needed for FF */ /* needed for FF */
font-family: 'Myriad Pro', Helvetica, Arial, Sans-Serif; font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
} }
/* hack for FF as vertical alignment of custom placeholder text is broken */ /* hack for FF as vertical alignment of custom placeholder text is broken */
@ -72,7 +72,9 @@ limitations under the License.
} }
.mx_MessageComposer_upload, .mx_MessageComposer_upload,
.mx_MessageComposer_call { .mx_MessageComposer_hangup,
.mx_MessageComposer_voicecall,
.mx_MessageComposer_videocall {
display: table-cell; display: table-cell;
vertical-align: middle; vertical-align: middle;
padding-left: 10px; padding-left: 10px;
@ -80,7 +82,12 @@ limitations under the License.
cursor: pointer; cursor: pointer;
} }
.mx_MessageComposer_call { .mx_MessageComposer_videocall {
padding-right: 10px;
padding-top: 4px;
}
.mx_MessageComposer_voicecall {
padding-right: 10px; padding-right: 10px;
padding-top: 4px; padding-top: 4px;
} }

View File

@ -15,7 +15,7 @@ limitations under the License.
*/ */
.mx_RoomDropTarget { .mx_RoomDropTarget {
font-size: 14px; font-size: 13px;
margin-left: 10px; margin-left: 10px;
margin-right: 15px; margin-right: 15px;
padding-top: 5px; padding-top: 5px;

View File

@ -23,6 +23,9 @@ limitations under the License.
height: 83px; height: 83px;
border-bottom: 1px solid #eeeeee; border-bottom: 1px solid #eeeeee;
-webkit-align-items: center;
align-items: center;
display: -webkit-box; display: -webkit-box;
display: -moz-box; display: -moz-box;
display: -ms-flexbox; display: -ms-flexbox;
@ -31,8 +34,6 @@ limitations under the License.
} }
.mx_RoomHeader_leftRow { .mx_RoomHeader_leftRow {
height: 48px;
margin-top: 18px;
margin-left: -2px; margin-left: -2px;
-webkit-box-ordinal-group: 1; -webkit-box-ordinal-group: 1;
@ -47,7 +48,6 @@ limitations under the License.
.mx_RoomHeader_textButton { .mx_RoomHeader_textButton {
height: 48px; height: 48px;
margin-top: 18px;
background-color: #76cfa6; background-color: #76cfa6;
border-radius: 48px; border-radius: 48px;
margin-right: 8px; margin-right: 8px;
@ -72,7 +72,7 @@ limitations under the License.
} }
.mx_RoomHeader_rightRow { .mx_RoomHeader_rightRow {
margin-top: 32px; margin-top: 4px;
background-color: #fff; background-color: #fff;
-webkit-box-ordinal-group: 3; -webkit-box-ordinal-group: 3;
@ -84,14 +84,14 @@ limitations under the License.
.mx_RoomHeader_info { .mx_RoomHeader_info {
display: table-cell; display: table-cell;
height: 48px; /* height: 48px; */
vertical-align: middle; vertical-align: middle;
} }
.mx_RoomHeader_simpleHeader { .mx_RoomHeader_simpleHeader {
line-height: 83px; line-height: 83px;
color: #454545; color: #454545;
font-size: 24px; font-size: 22px;
font-weight: bold; font-weight: bold;
overflow: hidden; overflow: hidden;
margin-left: 63px; margin-left: 63px;
@ -110,11 +110,13 @@ limitations under the License.
cursor: pointer; cursor: pointer;
vertical-align: middle; vertical-align: middle;
height: 28px; height: 28px;
overflow: hidden;
color: #454545; color: #454545;
font-weight: bold; font-weight: bold;
font-size: 24px; font-size: 22px;
padding-left: 19px; padding-left: 19px;
padding-right: 16px; padding-right: 16px;
/* why isn't text-overflow working? */
text-overflow: ellipsis; text-overflow: ellipsis;
} }
@ -122,6 +124,13 @@ limitations under the License.
display: inline-block; display: inline-block;
} }
.mx_RoomHeader_searchStatus {
display: inline-block;
font-weight: normal;
overflow-y: hidden;
opacity: 0.6;
}
.mx_RoomHeader_settingsButton { .mx_RoomHeader_settingsButton {
display: inline-block; display: inline-block;
visibility: hidden; visibility: hidden;
@ -130,14 +139,24 @@ limitations under the License.
left: 4px; left: 4px;
} }
.mx_RoomHeader_name:hover { .mx_RoomHeader_leftRow:hover .mx_RoomHeader_name {
color: #76cfa6; color: #76cfa6;
} }
.mx_RoomHeader_name:hover .mx_RoomHeader_settingsButton { .mx_RoomHeader_leftRow:hover .mx_RoomHeader_settingsButton {
visibility: visible; visibility: visible;
} }
.mx_RoomHeader_leaveButton {
visibility: hidden;
margin-top: -1px;
}
.mx_RoomHeader_wrapper:hover .mx_RoomHeader_leaveButton {
visibility: visible;
}
.mx_RoomHeader_nameEditing { .mx_RoomHeader_nameEditing {
padding-left: 8px; padding-left: 8px;
padding-right: 16px; padding-right: 16px;
@ -149,7 +168,7 @@ limitations under the License.
width: 260px; width: 260px;
border: 1px solid #c7c7c7; border: 1px solid #c7c7c7;
font-weight: 300; font-weight: 300;
font-size: 14px; font-size: 13px;
padding: 9px; padding: 9px;
} }
@ -160,7 +179,7 @@ limitations under the License.
.mx_RoomHeader_topic { .mx_RoomHeader_topic {
vertical-align: bottom; vertical-align: bottom;
float: left; float: left;
max-height: 38px; max-height: 42px;
color: #454545; color: #454545;
font-weight: 300; font-weight: 300;
padding-left: 19px; padding-left: 19px;

View File

@ -39,7 +39,7 @@ limitations under the License.
border-radius: 3px; border-radius: 3px;
border: 1px solid #c7c7c7; border: 1px solid #c7c7c7;
font-weight: 300; font-weight: 300;
font-size: 14px; font-size: 13px;
padding: 9px; padding: 9px;
margin-top: 6px; margin-top: 6px;
} }
@ -59,7 +59,7 @@ limitations under the License.
height: 36px; height: 36px;
border-radius: 36px; border-radius: 36px;
font-weight: 400; font-weight: 400;
font-size: 16px; font-size: 15px;
color: #fff; color: #fff;
background-color: #76cfa6; background-color: #76cfa6;
width: auto; width: auto;

View File

@ -18,19 +18,19 @@ limitations under the License.
cursor: pointer; cursor: pointer;
/* This fixes wrapping of long room names, but breaks drag & drop previews */ /* This fixes wrapping of long room names, but breaks drag & drop previews */
/* display: table-row; */ /* display: table-row; */
font-size: 14px; font-size: 13px;
} }
.mx_RoomTile_avatar { .mx_RoomTile_avatar {
display: table-cell; display: table-cell;
padding-right: 8px; padding-right: 8px;
padding-top: 4px; padding-top: 6px;
padding-bottom: 2px; padding-bottom: 6px;
padding-left: 18px; padding-left: 18px;
vertical-align: middle;
width: 24px; width: 24px;
height: 24px; height: 24px;
position: relative; position: relative;
vertical-align: middle;
} }
.mx_RoomTile_avatar img { .mx_RoomTile_avatar img {
@ -48,7 +48,8 @@ limitations under the License.
} }
.mx_RoomTile_invite { .mx_RoomTile_invite {
color: rgba(69, 69, 69, 0.5); /* color: rgba(69, 69, 69, 0.5);
*/
} }
.collapsed .mx_RoomTile_name { .collapsed .mx_RoomTile_name {
@ -112,6 +113,10 @@ limitations under the License.
color: #76cfa6 ! important; color: #76cfa6 ! important;
} }
.mx_RoomTile_highlight .mx_RoomTile_name {
color: #ff0064 ! important;
}
.mx_RoomTile.mx_RoomTile_selected .mx_RoomTile_name { .mx_RoomTile.mx_RoomTile_selected .mx_RoomTile_name {
background: url('img/selected.png'); background: url('img/selected.png');
background-repeat: no-repeat; background-repeat: no-repeat;

View File

@ -21,24 +21,43 @@ limitations under the License.
align-items: center; align-items: center;
} }
.mx_SearchBar input { .mx_SearchBar_input {
display: inline block; display: inline block;
border-radius: 3px; border-radius: 3px 0px 0px 3px;
border: 1px solid #f0f0f0; border: 1px solid #f0f0f0;
font-size: 16px; font-size: 15px;
padding: 9px; padding: 9px;
padding-left: 11px; padding-left: 11px;
margin-right: 17px;
width: auto; width: auto;
flex: 1 1 0; flex: 1 1 0;
} }
.mx_SearchBar_searchButton {
cursor: pointer;
margin-right: 10px;
width: 37px;
height: 37px;
border-radius: 0px 3px 3px 0px;
background-color: #76CFA6;
}
@keyframes pulsate {
0% { opacity: 1.0; }
50% { opacity: 0.25; }
100% { opacity: 1.0; }
}
.mx_SearchBar_searching img {
animation: pulsate 0.75s ease-out;
animation-iteration-count: infinite;
}
.mx_SearchBar_button { .mx_SearchBar_button {
display: inline; display: inline;
border: 0px; border: 0px;
border-radius: 36px; border-radius: 36px;
font-weight: 400; font-weight: 400;
font-size: 16px; font-size: 15px;
color: #fff; color: #fff;
background-color: #76cfa6; background-color: #76cfa6;
width: auto; width: auto;

View File

@ -13,8 +13,3 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
.mx_SenderProfile_zalgo {
font-family: Helvetica, Arial, Sans-Serif;
display: table-row ! important;
}

View File

@ -25,7 +25,7 @@ limitations under the License.
.mx_ServerConfig_help:link { .mx_ServerConfig_help:link {
opacity: 0.8; opacity: 0.8;
font-size: 14px; font-size: 13px;
font-weight: 300; font-weight: 300;
color: #4a4a4a; color: #4a4a4a;
} }

View File

@ -26,7 +26,7 @@ limitations under the License.
border-radius: 3px; border-radius: 3px;
border: 1px solid #c7c7c7; border: 1px solid #c7c7c7;
font-weight: 300; font-weight: 300;
font-size: 14px; font-size: 13px;
padding: 9px; padding: 9px;
margin-top: 6px; margin-top: 6px;
} }

View File

@ -69,11 +69,12 @@ limitations under the License.
} }
.mx_LeftPanel .mx_BottomLeftMenu .mx_BottomLeftMenu_options { .mx_LeftPanel .mx_BottomLeftMenu .mx_BottomLeftMenu_options {
margin-top: 17px; margin-top: 15px;
width: 100%; width: 100%;
} }
.mx_LeftPanel .mx_BottomLeftMenu img { .mx_LeftPanel .mx_BottomLeftMenu img {
border-radius: 0px; border-radius: 0px;
background-color: transparent; background-color: transparent;
vertical-align: middle;
} }

View File

@ -45,13 +45,13 @@ limitations under the License.
} }
.mx_MemberList_invite { .mx_MemberList_invite {
font-family: 'Myriad Pro', Helvetica, Arial, Sans-Serif; font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
border-radius: 3px; border-radius: 3px;
border: 1px solid #f0f0f0; border: 1px solid #f0f0f0;
padding: 9px; padding: 9px;
color: #454545; color: #454545;
margin-left: 3px; margin-left: 3px;
font-size: 16px; font-size: 15px;
margin-bottom: 8px; margin-bottom: 8px;
width: 180px; width: 180px;
} }
@ -69,7 +69,7 @@ limitations under the License.
text-transform: uppercase; text-transform: uppercase;
color: #3d3b39; color: #3d3b39;
font-weight: 600; font-weight: 600;
font-size: 14px; font-size: 13px;
padding-left: 3px; padding-left: 3px;
padding-right: 12px; padding-right: 12px;
margin-top: 8px; margin-top: 8px;

View File

@ -66,7 +66,7 @@ limitations under the License.
.mx_RightPanel_headerButton_badge { .mx_RightPanel_headerButton_badge {
position: absolute; position: absolute;
top: 5px; top: 4px;
left: 28px; left: 28px;
font-size: 12px; font-size: 12px;
background-color: #76cfa6; background-color: #76cfa6;
@ -75,7 +75,7 @@ limitations under the License.
border-radius: 20px; border-radius: 20px;
padding-left: 4px; padding-left: 4px;
padding-right: 4px; padding-right: 4px;
padding-top: 2px; padding-top: 0px;
} }
.mx_RightPanel .mx_MemberList, .mx_RightPanel .mx_MemberList,

View File

@ -50,7 +50,7 @@ limitations under the License.
border-radius: 3px; border-radius: 3px;
border: 1px solid #c7c7c7; border: 1px solid #c7c7c7;
font-weight: 300; font-weight: 300;
font-size: 14px; font-size: 13px;
padding: 9px; padding: 9px;
margin-top: 12px; margin-top: 12px;
margin-bottom: 12px; margin-bottom: 12px;
@ -70,7 +70,7 @@ limitations under the License.
.mx_RoomDirectory_table th { .mx_RoomDirectory_table th {
font-weight: 400; font-weight: 400;
font-size: 12px; font-size: 11px;
} }
.mx_RoomDirectory_table tbody { .mx_RoomDirectory_table tbody {
@ -79,7 +79,6 @@ limitations under the License.
.mx_RoomDirectory_table td { .mx_RoomDirectory_table td {
font-weight: 300; font-weight: 300;
font-size: 16px;
overflow-x: hidden; overflow-x: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
@ -90,7 +89,7 @@ limitations under the License.
.mx_RoomDirectory_table .mx_RoomDirectory_topic { .mx_RoomDirectory_table .mx_RoomDirectory_topic {
font-weight: 400; font-weight: 400;
font-size: 12px; font-size: 11px;
} }
.mx_RoomDirectory_table td, .mx_RoomDirectory_table td,

View File

@ -25,3 +25,10 @@ limitations under the License.
padding-left: 12px; padding-left: 12px;
padding-right: 12px; padding-right: 12px;
} }
/* Evil hacky override until Chrome fixes drop and drag table cells
and we can correctly fix horizontal wrapping in the sidebar again */
.mx_RoomList_scrollbar .gm-scroll-view {
overflow-x: hidden ! important;
overflow-y: scroll ! important;
}

View File

@ -29,7 +29,7 @@ limitations under the License.
text-transform: uppercase; text-transform: uppercase;
color: #3d3b39; color: #3d3b39;
font-weight: 600; font-weight: 600;
font-size: 14px; font-size: 13px;
padding-left: 12px; padding-left: 12px;
padding-right: 12px; padding-right: 12px;
margin-top: 8px; margin-top: 8px;

View File

@ -170,10 +170,35 @@ limitations under the License.
.mx_RoomView_statusAreaBox_line { .mx_RoomView_statusAreaBox_line {
border-top: 1px solid #eee; border-top: 1px solid #eee;
margin-left: 63px;
height: 1px; height: 1px;
} }
.mx_RoomView_inCall .mx_RoomView_statusAreaBox_line {
border-top: 1px hidden;
}
.mx_RoomView_inCall .mx_MessageComposer_wrapper {
border-top: 2px hidden;
}
.mx_RoomView_inCall .mx_RoomView_statusAreaBox {
background-color: #76CFA6;
color: #fff;
position: relative;
}
.mx_RoomView_voipChevron {
position: absolute;
bottom: -10px;
right: 11px;
}
.mx_RoomView_voipButton {
float: right;
margin-right: 13px;
cursor: pointer;
}
.mx_RoomView_unreadMessagesBar { .mx_RoomView_unreadMessagesBar {
color: #ff0064; color: #ff0064;
cursor: pointer; cursor: pointer;
@ -186,6 +211,16 @@ limitations under the License.
vertical-align: middle; vertical-align: middle;
} }
.mx_RoomView_callBar {
margin-top: 5px;
}
.mx_RoomView_callBar img {
padding-left: 13px;
padding-right: 30px;
vertical-align: middle;
}
.mx_RoomView_connectionLostBar { .mx_RoomView_connectionLostBar {
margin-top: 19px; margin-top: 19px;
height: 58px; height: 58px;
@ -204,7 +239,7 @@ limitations under the License.
.mx_RoomView_connectionLostBar_desc { .mx_RoomView_connectionLostBar_desc {
color: #454545; color: #454545;
font-size: 14px; font-size: 13px;
opacity: 0.5; opacity: 0.5;
} }
@ -215,8 +250,8 @@ limitations under the License.
} }
.mx_RoomView_typingBar { .mx_RoomView_typingBar {
margin-top: 10px; margin-top: 6px;
margin-left: 63px; margin-left: 65px;
color: #4a4a4a; color: #4a4a4a;
opacity: 0.5; opacity: 0.5;
} }
@ -228,6 +263,11 @@ limitations under the License.
float: left; float: left;
} }
.mx_RoomView_typingText {
overflow-y: hidden;
display: block;
}
.mx_RoomView .mx_MessageComposer { .mx_RoomView .mx_MessageComposer {
-webkit-box-ordinal-group: 5; -webkit-box-ordinal-group: 5;
-moz-box-ordinal-group: 5; -moz-box-ordinal-group: 5;
@ -241,43 +281,6 @@ limitations under the License.
margin-right: 2px; margin-right: 2px;
} }
.mx_RoomView_uploadProgressOuter {
height: 4px;
margin-left: 63px;
margin-top: -1px;
}
.mx_RoomView_uploadProgressInner {
background-color: #76cfa6;
height: 4px;
}
.mx_RoomView_uploadFilename {
margin-top: 5px;
margin-left: 65px;
opacity: 0.5;
color: #4a4a4a;
}
.mx_RoomView_uploadIcon {
float: left;
margin-top: 1px;
margin-left: 14px;
}
.mx_RoomView_uploadCancel {
float: right;
margin-top: 5px;
margin-right: 10px;
}
.mx_RoomView_uploadBytes {
float: right;
margin-top: 5px;
margin-right: 30px;
color: #76cfa6;
}
.mx_RoomView_ongoingConfCallNotification { .mx_RoomView_ongoingConfCallNotification {
width: 100%; width: 100%;
text-align: center; text-align: center;

View File

@ -14,6 +14,18 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
.mx_MatrixChat_splash {
position: relative;
height: 100%;
}
.mx_MatrixChat_splashButtons {
text-align: center;
width: 100%;
position: absolute;
bottom: 30px;
}
.mx_MatrixChat_wrapper { .mx_MatrixChat_wrapper {
display: -webkit-box; display: -webkit-box;
display: -moz-box; display: -moz-box;

View File

@ -55,7 +55,7 @@ limitations under the License.
border-radius: 3px; border-radius: 3px;
border: 1px solid #c7c7c7; border: 1px solid #c7c7c7;
font-weight: 300; font-weight: 300;
font-size: 14px; font-size: 13px;
padding: 9px; padding: 9px;
margin-bottom: 14px; margin-bottom: 14px;
} }
@ -68,12 +68,12 @@ limitations under the License.
height: 40px; height: 40px;
border: 0px; border: 0px;
background-color: #76cfa6; background-color: #76cfa6;
font-size: 16px; font-size: 15px;
color: #fff; color: #fff;
} }
.mx_Login_label { .mx_Login_label {
font-size: 14px; font-size: 13px;
opacity: 0.8; opacity: 0.8;
} }
@ -85,7 +85,7 @@ limitations under the License.
display: block; display: block;
text-align: center; text-align: center;
width: 100%; width: 100%;
font-size: 14px; font-size: 13px;
opacity: 0.8; opacity: 0.8;
} }
@ -97,7 +97,7 @@ limitations under the License.
display: block; display: block;
text-align: center; text-align: center;
width: 100%; width: 100%;
font-size: 14px; font-size: 13px;
opacity: 0.8; opacity: 0.8;
} }

View File

@ -0,0 +1,12 @@
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: local('Open Sans'), local('OpenSans'), url(u-WUoqrET9fUeobQW7jkRaCWcynf_cDxXwCLxiixG1c.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 700;
src: local('Open Sans Bold'), local('OpenSans-Bold'), url(k3k702ZOKiLJc3WVjuplzNqQynqKV_9Plp7mupa0S4g.ttf) format('truetype');
}

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="30px" height="22px" viewBox="-1 -1 30 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: bin/sketchtool 1.4 (305) - http://www.bohemiancoding.com/sketch -->
<title>icons_video</title>
<desc>Created with bin/sketchtool.</desc>
<defs></defs>
<g id="02-Chat" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="02_13-Chat-member-profile" sketch:type="MSArtboardGroup" transform="translate(-910.000000, -723.000000)" stroke="#76CFA6">
<g id="icons_video" sketch:type="MSLayerGroup" transform="translate(910.000000, 722.000000)">
<g id="Rectangle-20-+-Path-16" transform="translate(0.000000, 0.464286)" sketch:type="MSShapeGroup">
<rect id="Rectangle-20" fill="#FFFFFF" x="0" y="0.535714286" width="20" height="20" rx="4"></rect>
<path d="M20.75,10.6964286 C20.75,14.0446429 24.188247,15.7371974 24.188247,15.7371974 C25.5057636,16.651593 26.5738219,16.0843085 26.5738219,14.4868066 L26.5738219,6.90605053 C26.5738219,5.30108314 25.4784055,4.70120148 24.188247,5.65565975 C24.188247,5.65565975 20.75,7.34821429 20.75,10.6964286 Z" id="Path-16"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.2 (15857) - http://www.bohemiancoding.com/sketch -->
<title>Slice 1</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<path d="M9.74464309,-3.02908503 L8.14106175,-3.02908503 L8.14106175,8.19448443 L-3.03028759,8.19448443 L-3.03028759,9.7978515 L8.14106175,9.7978515 L8.14106175,20.9685098 L9.74464309,20.9685098 L9.74464309,9.7978515 L20.9697124,9.7978515 L20.9697124,8.19448443 L9.74464309,8.19448443 L9.74464309,-3.02908503" id="Fill-108" opacity="0.9" fill="#454545" sketch:type="MSShapeGroup" transform="translate(8.969712, 8.969712) rotate(-315.000000) translate(-8.969712, -8.969712) "></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="17px" height="22px" viewBox="0 0 17 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: bin/sketchtool 1.4 (305) - http://www.bohemiancoding.com/sketch -->
<title>icons_browse_files</title>
<desc>Created with bin/sketchtool.</desc>
<defs></defs>
<g id="02-Chat" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="02_13-Chat-member-profile" sketch:type="MSArtboardGroup" transform="translate(-1025.000000, -33.000000)">
<g id="icons_browse_files" sketch:type="MSLayerGroup" transform="translate(1025.000000, 32.000000)">
<g id="Rectangle-5-+-Rectangle-6-Copy" transform="translate(0.000000, 1.000000)" sketch:type="MSShapeGroup">
<path d="M0,4.00955791 C0,1.79514022 1.78163126,0 3.99825563,0 L9.59161955,0 C9.59161955,0 16.3225806,6.49234232 16.3225806,6.49234232 L16.3225806,18.0063928 C16.3225806,20.2120012 14.5290874,22 12.3296282,22 L3.99295243,22 C1.7877057,22 0,20.1996477 0,17.9904421 L0,4.00955791 Z" id="Rectangle-5" stroke="#76CFA6"></path>
<path d="M15.6804916,7.49527496 L11.5273266,7.49527496 C10.3308881,7.49527496 9.3609831,6.52527676 9.3609831,5.3289315 L9.3609831,1.88544393 L15.6804916,7.49527496 Z" id="Rectangle-6-Copy" fill="#FFFFFF"></path>
<path d="M16.3225806,7.09677419 L11.4129801,7.09677419 C10.2050375,7.09677419 9.22580645,6.11744908 9.22580645,4.90960051 L9.22580645,0" id="Rectangle-6" stroke="#76CFA6"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="29px" height="22px" viewBox="-1 -1 29 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.4 (17249) - http://www.bohemiancoding.com/sketch -->
<title>Zoom</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="05-Voice-and-video" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="05_2-Video-call" sketch:type="MSArtboardGroup" transform="translate(-824.000000, -667.000000)">
<g id="Zoom" sketch:type="MSLayerGroup" transform="translate(824.000000, 667.000000)">
<rect id="Rectangle-20" stroke="#FFFFFF" sketch:type="MSShapeGroup" x="0" y="0" width="27" height="20" rx="4"></rect>
<rect id="Rectangle-20" stroke="#FFFFFF" sketch:type="MSShapeGroup" x="6" y="2" width="15" height="11" rx="4"></rect>
<g id="Line-+-Triangle-3" transform="translate(4.474874, 15.181981) rotate(-45.000000) translate(-4.474874, -15.181981) translate(0.974874, 13.181981)" sketch:type="MSShapeGroup">
<path d="M6.53553391,2 L3,2" id="Line" stroke="#FFFFFF" stroke-linecap="square"></path>
<path d="M3.26960678,3.51960678 L0.269606781,2.01960678 L3.26960678,0.519606781 L3.26960678,3.51960678 Z" id="Triangle-3" fill="#FFFFFF"></path>
</g>
<g id="Line-+-Triangle-3-Copy" transform="translate(22.681981, 15.181981) scale(-1, 1) rotate(-45.000000) translate(-22.681981, -15.181981) translate(19.181981, 13.181981)" sketch:type="MSShapeGroup">
<path d="M6.53553391,2 L3,2" id="Line" stroke="#FFFFFF" stroke-linecap="square"></path>
<path d="M3.375,0.5 L3.375,3.5 L0.375,2 L3.375,0.5 Z" id="Triangle-3" fill="#FFFFFF"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="25px" height="26px" viewBox="-1 -1 25 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.3 (16618) - http://www.bohemiancoding.com/sketch -->
<title>Fill 72 + Path 98</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="05-Voice-and-video" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="05_2-Video-call" sketch:type="MSArtboardGroup" transform="translate(-910.000000, -719.000000)" stroke="#FF0064">
<g id="Fill-72-+-Path-98" sketch:type="MSLayerGroup" transform="translate(910.000000, 719.000000)">
<path d="M17.8404444,24 C15.8137778,24 10.8875556,21.408 6.75022222,15.8448889 C2.88088889,10.6413333 1,6.88222222 1,4.35244444 C1,2.36088889 2.37511111,1.41022222 3.11422222,0.9 L3.29644444,0.772888889 C4.11288889,0.188888889 5.38222222,0 5.86888889,0 C6.72222222,0 7.08177778,0.499555556 7.29955556,0.935111111 C7.48488889,1.30311111 9.01777778,4.59511111 9.17288889,5.00444444 C9.41111111,5.63377778 9.33288889,6.55111111 8.596,7.07822222 L8.46622222,7.16844444 C8.10044444,7.42222222 7.42,7.89333333 7.32577778,8.46622222 C7.28,8.74488889 7.37333333,9.03644444 7.61111111,9.35688889 C8.79777778,10.956 12.5862222,15.6506667 13.2693333,16.2884444 C13.8044444,16.7884444 14.4826667,16.8595556 14.9444444,16.4702222 C15.4222222,16.0675556 15.6342222,15.8297778 15.6364444,15.8271111 L15.6857778,15.7795556 C15.7257778,15.7457778 16.0991111,15.4497778 16.7093333,15.4497778 C17.1497778,15.4497778 17.5973333,15.6017778 18.04,15.9008889 C19.1884444,16.6768889 21.7808889,18.4106667 21.7808889,18.4106667 L21.8226667,18.4426667 C22.1542222,18.7266667 22.6333333,19.5453333 22.0751111,20.6106667 C21.496,21.7168889 19.6986667,24 17.8404444,24 L17.8404444,24 Z" id="Fill-72" sketch:type="MSShapeGroup"></path>
<path d="M19.8035085,4 L0,22.8035085" id="Path-98" sketch:type="MSShapeGroup"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-1 -1 20 26"
xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#76CFA6;}
.st1{fill:#76CFA6;}
</style>
<g id="Page-1" sketch:type="MSPage">
<g id="Exit-Copy-6" sketch:type="MSLayerGroup">
<path id="Rectangle-140_1_" sketch:type="MSShapeGroup" class="st0" d="M4.4,0.5h7.5c2.2,0,4,1.8,4,4v14c0,2.2-1.8,4-4,4H4.4
c-2.2,0-4-1.8-4-4v-14C0.4,2.3,2.2,0.5,4.4,0.5z"/>
<g id="Rectangle-140_2_">
<g>
<path class="st1" d="M12,23H4.5C2,23,0,21,0,18.5v-14C0,2,2,0,4.5,0H12c2.5,0,4.5,2,4.5,4.5v14C16.4,21,14.4,23,12,23z M4.4,1
C2.5,1,0.9,2.6,0.9,4.5v14c0,1.9,1.6,3.5,3.5,3.5h7.5c1.9,0,3.5-1.6,3.5-3.5v-14c0-1.9-1.6-3.5-3.5-3.5H4.4z"/>
<g>
<path class="st0" d="M3.2,20.6l8.3-1.8c1.1-0.2,2-1,2-1.7V5.7c0-0.7-0.9-1.4-2-1.7L3.2,2.2"/>
</g>
</g>
</g>
<circle id="Oval-605" sketch:type="MSShapeGroup" class="st1" cx="10.7" cy="11.1" r="1">
</circle>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.2 (15857) - http://www.bohemiancoding.com/sketch -->
<title>Slice 1</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<path d="M0,5 L20,5 L10,15 L0,5 Z" id="Triangle-1" fill="#76CFA6" sketch:type="MSShapeGroup" transform="translate(10.000000, 10.000000) rotate(-90.000000) translate(-10.000000, -10.000000) "></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 748 B

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.2 (15857) - http://www.bohemiancoding.com/sketch -->
<title>Slice 1</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<path d="M0,5 L20,5 L10,15 L0,5 Z" id="Triangle-1" fill="#76CFA6" sketch:type="MSShapeGroup"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 650 B

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="17px" height="22px" viewBox="0 0 17 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: bin/sketchtool 1.4 (305) - http://www.bohemiancoding.com/sketch -->
<title>icons_people</title>
<desc>Created with bin/sketchtool.</desc>
<defs></defs>
<g id="02-Chat" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="02_13-Chat-member-profile" sketch:type="MSArtboardGroup" transform="translate(-978.000000, -32.000000)" fill="#76CFA6">
<g id="icons_people" sketch:type="MSLayerGroup" transform="translate(978.000000, 32.000000)">
<path d="M7.79396172,11.1845854 C10.8910264,11.1845854 13.4110283,8.6755122 13.4110283,5.59121951 C13.4110283,2.50853659 10.8910264,0 7.79396172,0 C4.69851351,0 2.18012797,2.50853659 2.18012797,5.59121951 C2.18012797,8.6755122 4.69851351,11.1845854 7.79396172,11.1845854 L7.79396172,11.1845854 Z M7.79396172,0.804878049 C10.4454327,0.804878049 12.6028173,2.95229268 12.6028173,5.59121951 C12.6028173,8.2317561 10.4454327,10.3797073 7.79396172,10.3797073 C5.14410719,10.3797073 2.98833899,8.2317561 2.98833899,5.59121951 C2.98833899,2.95229268 5.14410719,0.804878049 7.79396172,0.804878049 L7.79396172,0.804878049 Z M0.885806936,21.4634146 C1.33849039,19.4978231 2.46183493,15.4298815 3.13651101,14.4663415 C4.32835286,12.76 6.45287023,12.8072195 6.48358225,12.8034634 L9.03699027,12.8013171 C9.06393064,12.7980976 11.7369539,12.5421463 12.9228689,14.5377073 C12.9320286,14.5532683 12.9422659,14.5682927 12.9535809,14.5827805 C13.6376414,15.4425239 14.755176,19.1307382 15.2598605,21.1908293 L15.2598605,21.1908293 L14.9096797,21.1908293 L1.53746094,21.1908293 L1.15172387,21.1908293 L1.15172387,21.9957073 L1.53746094,21.9957073 L14.9096797,21.9957073 L15.2954167,21.9957073 L15.2954167,21.3375005 C15.3143567,21.416496 15.3322794,21.4927245 15.3491183,21.5659024 C15.3922229,21.7520976 15.5587144,21.8781951 15.7429865,21.8781951 C15.7726209,21.8781951 15.8027941,21.8749756 15.8335061,21.8685366 C16.0506455,21.8186341 16.1869638,21.6029268 16.1368547,21.3856098 C15.7844747,19.8558049 14.5355192,15.312 13.6044602,14.1052195 C12.144831,11.6825366 9.08063366,11.9857073 8.99388568,11.9985854 L6.49759124,11.9985854 C6.38767454,11.996439 3.92209212,11.9320488 2.47323917,14.0059512 C1.66987741,15.1531707 0.489889321,19.5553171 0.0750076642,21.3872195 C0.0254373883,21.6045366 0.162294454,21.8197073 0.379972623,21.8685366 C0.460649718,21.8870317 0.541104777,21.8798767 0.61291652,21.8524806 L0.61291652,22 L1.15172387,22 L1.15172387,21.4634146 L0.885804128,21.4634146 Z" id="Fill-92" sketch:type="MSShapeGroup"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="21px" height="19px" viewBox="-8 -8 37 37" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.4 (17249) - http://www.bohemiancoding.com/sketch -->
<title>icon_search</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="icon_search" sketch:type="MSLayerGroup" transform="translate(-8.000000, -8.000000)" stroke="#FFFFFF">
<path d="M21.328421,19.3333333 L27.5542961,24.7357275 C27.9574623,25.085568 28.0116667,25.70516 27.6700827,26.1261351 L27.6700827,26.1261351 C27.3308636,26.5441955 26.72562,26.5965299 26.3258751,26.2496583 L20.1,20.8472641" id="Rectangle-9" sketch:type="MSShapeGroup"></path>
<g id="search" transform="translate(15.617851, 15.853553) rotate(-45.000000) translate(-15.617851, -15.853553) translate(8.117851, 7.853553)" sketch:type="MSShapeGroup">
<ellipse id="Search" cx="7.64433504" cy="7.90518519" rx="7.1665641" ry="7.41111111"></ellipse>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="21px" height="19px" viewBox="0 0 21 19" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: bin/sketchtool 1.4 (305) - http://www.bohemiancoding.com/sketch -->
<title>icons_search</title>
<desc>Created with bin/sketchtool.</desc>
<defs></defs>
<g id="02-Chat" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="02_13-Chat-member-profile" sketch:type="MSArtboardGroup" transform="translate(-910.000000, -34.000000)" stroke="#76CFA6">
<g id="icons_search" sketch:type="MSLayerGroup" transform="translate(906.000000, 30.000000)">
<path d="M17.328421,15.3333333 L23.5542961,20.7357275 C23.9574623,21.085568 24.0116667,21.70516 23.6700827,22.1261351 L23.6700827,22.1261351 C23.3308636,22.5441955 22.72562,22.5965299 22.3258751,22.2496583 L16.1,16.8472641" id="Rectangle-9" sketch:type="MSShapeGroup"></path>
<g id="search" transform="translate(11.617851, 11.853553) rotate(-45.000000) translate(-11.617851, -11.853553) translate(4.117851, 3.853553)" sketch:type="MSShapeGroup">
<ellipse id="Search" cx="7.64433504" cy="7.90518519" rx="7.1665641" ry="7.41111111"></ellipse>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: bin/sketchtool 1.4 (305) - http://www.bohemiancoding.com/sketch -->
<title>icon_settings_small</title>
<desc>Created with bin/sketchtool.</desc>
<defs></defs>
<g id="06a-Room-settings" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="06a_1-Room-settings-hover" sketch:type="MSArtboardGroup" transform="translate(-452.000000, -27.000000)" fill="#76CFA6">
<path d="M460,33 C460,32.4479139 459.804689,31.9765645 459.414062,31.5859375 C459.023436,31.1953105 458.552086,31 458,31 C457.447914,31 456.976564,31.1953105 456.585938,31.5859375 C456.195311,31.9765645 456,32.4479139 456,33 C456,33.5520861 456.195311,34.0234355 456.585938,34.4140625 C456.976564,34.8046895 457.447914,35 458,35 C458.552086,35 459.023436,34.8046895 459.414062,34.4140625 C459.804689,34.0234355 460,33.5520861 460,33 L460,33 Z M464,32.1484375 L464,33.8828125 C464,33.9453128 463.979167,34.005208 463.9375,34.0625 C463.895833,34.119792 463.84375,34.1536458 463.78125,34.1640625 L462.335938,34.3828125 C462.236979,34.6640639 462.135417,34.9010407 462.03125,35.09375 C462.213543,35.354168 462.492186,35.7135394 462.867188,36.171875 C462.919271,36.2343753 462.945312,36.2994788 462.945312,36.3671875 C462.945312,36.4348962 462.921875,36.4947914 462.875,36.546875 C462.734374,36.7395843 462.476564,37.0208315 462.101562,37.390625 C461.726561,37.7604185 461.481771,37.9453125 461.367188,37.9453125 C461.304687,37.9453125 461.23698,37.9218752 461.164062,37.875 L460.085938,37.03125 C459.85677,37.1510423 459.619793,37.2499996 459.375,37.328125 C459.291666,38.0364619 459.216146,38.520832 459.148438,38.78125 C459.111979,38.9270841 459.01823,39 458.867188,39 L457.132812,39 C457.059895,39 456.996094,38.9778648 456.941406,38.9335938 C456.886718,38.8893227 456.856771,38.8333337 456.851562,38.765625 L456.632812,37.328125 C456.377603,37.2447912 456.14323,37.148438 455.929688,37.0390625 L454.828125,37.875 C454.776041,37.9218752 454.710938,37.9453125 454.632812,37.9453125 C454.559895,37.9453125 454.494792,37.916667 454.4375,37.859375 C453.781247,37.265622 453.351564,36.8281264 453.148438,36.546875 C453.111979,36.4947914 453.09375,36.4348962 453.09375,36.3671875 C453.09375,36.3046872 453.114583,36.244792 453.15625,36.1875 C453.234375,36.0781245 453.367187,35.9049491 453.554688,35.6679688 C453.742188,35.4309884 453.882812,35.2473965 453.976562,35.1171875 C453.835937,34.8567695 453.729167,34.5989596 453.65625,34.34375 L452.226562,34.1328125 C452.158854,34.1223958 452.104167,34.089844 452.0625,34.0351562 C452.020833,33.9804685 452,33.9192712 452,33.8515625 L452,32.1171875 C452,32.0546872 452.020833,31.994792 452.0625,31.9375 C452.104167,31.880208 452.153646,31.8463542 452.210938,31.8359375 L453.664062,31.6171875 C453.73698,31.377603 453.838541,31.138022 453.96875,30.8984375 C453.760416,30.601561 453.481773,30.2421896 453.132812,29.8203125 C453.080729,29.7578122 453.054688,29.6953128 453.054688,29.6328125 C453.054688,29.5807289 453.078125,29.5208337 453.125,29.453125 C453.260417,29.2656241 453.516925,28.9856789 453.894531,28.6132812 C454.272137,28.2408836 454.518229,28.0546875 454.632812,28.0546875 C454.700521,28.0546875 454.768229,28.0807289 454.835938,28.1328125 L455.914062,28.96875 C456.14323,28.8489577 456.380207,28.7500004 456.625,28.671875 C456.708334,27.9635381 456.783854,27.479168 456.851562,27.21875 C456.888021,27.0729159 456.98177,27 457.132812,27 L458.867188,27 C458.940105,27 459.003906,27.0221352 459.058594,27.0664062 C459.113282,27.1106773 459.143229,27.1666663 459.148438,27.234375 L459.367188,28.671875 C459.622397,28.7552088 459.85677,28.851562 460.070312,28.9609375 L461.179688,28.125 C461.226563,28.0781248 461.289062,28.0546875 461.367188,28.0546875 C461.434896,28.0546875 461.5,28.0807289 461.5625,28.1328125 C462.234378,28.7526073 462.664062,29.1953112 462.851562,29.4609375 C462.888021,29.5026044 462.90625,29.5598955 462.90625,29.6328125 C462.90625,29.6953128 462.885417,29.755208 462.84375,29.8125 C462.765625,29.9218755 462.632813,30.0950509 462.445312,30.3320312 C462.257812,30.5690116 462.117188,30.7526035 462.023438,30.8828125 C462.158855,31.1432305 462.265625,31.3984362 462.34375,31.6484375 L463.773438,31.8671875 C463.841146,31.8776042 463.895833,31.910156 463.9375,31.9648438 C463.979167,32.0195315 464,32.0807288 464,32.1484375 L464,32.1484375 Z" id="icon_settings_small" sketch:type="MSShapeGroup"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="23px" height="20px" viewBox="-1 -1 23 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.3 (16618) - http://www.bohemiancoding.com/sketch -->
<title>sound_indicator</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="05-Voice-and-video" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="05_2-Video-call" sketch:type="MSArtboardGroup" transform="translate(-247.000000, -668.000000)" fill="#FFFFFF">
<g id="sound_indicator" sketch:type="MSLayerGroup" transform="translate(247.000000, 668.000000)">
<path d="M5.769,6.7284 L7.8,4.6968 L7.8,13.0626 L5.4174,10.68 L1.2,10.68 L1.2,7.08 L5.4174,7.08 L5.769,6.7284 L5.769,6.7284 Z M0,5.88 L0,11.88 L4.9206,11.88 L9,15.9594 L9,1.8 L4.9206,5.88 L0,5.88 L0,5.88 Z" id="Fill-28" sketch:type="MSShapeGroup"></path>
<path d="M17.1672,0 L16.2,0.72 C17.9172,3.021 18.9354,5.8728 18.9354,8.9586 C18.9354,12.0438 17.9172,14.8956 16.2,17.196 L17.1672,17.9166 C19.0314,15.417 20.1354,12.3168 20.1354,8.9586 C20.1354,5.6004 19.0314,2.4996 17.1672,0" id="Fill-29" sketch:type="MSShapeGroup"></path>
<path d="M14.1606,15.9948 C15.579,14.094 16.4304,11.7462 16.4304,9.1974 C16.4304,6.6486 15.579,4.3008 14.1606,2.4 L13.2,3.1152 C14.469,4.8156 15.2304,6.9168 15.2304,9.1974 C15.2304,11.478 14.4696,13.5786 13.2,15.2796 L14.1606,15.9948" id="Fill-30" sketch:type="MSShapeGroup"></path>
<path d="M11.7606,13.5024 C12.732,12.2016 13.314,10.5954 13.314,8.8512 C13.314,7.107 12.732,5.5002 11.7606,4.2 L10.8,4.9152 C11.6214,6.0156 12.114,7.3752 12.114,8.8512 C12.114,10.3272 11.6214,11.6862 10.8,12.7866 L11.7606,13.5024" id="Fill-31" sketch:type="MSShapeGroup"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="20px" height="14px" viewBox="0 0 20 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: bin/sketchtool 1.4 (305) - http://www.bohemiancoding.com/sketch -->
<title>icon_eol</title>
<desc>Created with bin/sketchtool.</desc>
<defs></defs>
<g id="03-Input" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="03_2-Mentions-autocomplete" sketch:type="MSArtboardGroup" transform="translate(-772.000000, -670.000000)">
<g id="icon_eol" sketch:type="MSLayerGroup" transform="translate(772.000000, 670.000000)">
<path d="M0,7.5 L17,7.5" id="Path-118" stroke="#76CFA6" sketch:type="MSShapeGroup"></path>
<path d="M13,2 L18,7.38056399 L13,12.761128" id="Path-119" stroke="#76CFA6" sketch:type="MSShapeGroup"></path>
<path d="M19.5,0 L19.5,14" id="Path-120" stroke="#80CEF4" sketch:type="MSShapeGroup"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="45px" height="59px" viewBox="-1 -1 45 59" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: bin/sketchtool 1.4 (305) - http://www.bohemiancoding.com/sketch -->
<title>icons_upload_drop</title>
<desc>Created with bin/sketchtool.</desc>
<defs></defs>
<g id="03-Input" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="03_05-File-drop" sketch:type="MSArtboardGroup" transform="translate(-570.000000, -368.000000)">
<g id="icons_upload_drop" sketch:type="MSLayerGroup" transform="translate(570.000000, 368.000000)">
<g id="Rectangle-5-+-Rectangle-6" sketch:type="MSShapeGroup">
<path d="M0,4.00812931 C0,1.79450062 1.78537926,0 4.00241155,0 L24.8253683,0 C24.8253683,0 42.2466793,16.8210687 42.2466793,16.8210687 L42.2466793,53.000599 C42.2466793,55.2094072 40.4583762,57 38.2531894,57 L3.99348992,57 C1.78794634,57 0,55.1999609 0,52.9918707 L0,4.00812931 Z" id="Rectangle-5" stroke="#76CFA6"></path>
<path d="M40.5848017,19.419576 L29.8354335,19.419576 C26.7387692,19.419576 24.2284269,16.9063989 24.2284269,13.8067771 L24.2284269,4.88501382 L40.5848017,19.419576 Z" id="Rectangle-6-Copy" fill="#FFFFFF"></path>
<path d="M42.2466793,18.3870968 L29.539478,18.3870968 C26.4130381,18.3870968 23.8785579,15.8497544 23.8785579,12.7203286 L23.8785579,0" id="Rectangle-6" stroke="#76CFA6"></path>
</g>
<path d="M31.3419737,32.9284726 C31.701384,32.9284726 32.0607942,32.8000473 32.3359677,32.5414375 C32.8825707,32.0259772 32.8825707,31.1920926 32.3359677,30.6766323 L21.622922,20.6119619 C21.076319,20.0965016 20.187153,20.0982608 19.638678,20.6102026 L8.9125289,30.6607991 C8.36405391,31.1762594 8.36218198,32.0119032 8.90878504,32.5273635 C9.4553881,33.0445831 10.344554,33.0445831 10.893029,32.530882 L19.2399573,24.7092556 L19.2437012,46.487014 C19.2437012,47.2153435 19.874541,47.8064516 20.6476474,47.8064516 C21.4244976,47.8064516 22.0515936,47.2153435 22.0515936,46.487014 L22.0478497,24.7426814 L30.3498517,32.5414375 C30.6231533,32.8000473 30.9825635,32.9284726 31.3419737,32.9284726 L31.3419737,32.9284726 Z" id="Fill-75" fill="#76CFA6" sketch:type="MSShapeGroup"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="17px" height="22px" viewBox="0 0 17 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: bin/sketchtool 1.4 (305) - http://www.bohemiancoding.com/sketch -->
<title>icons_upload</title>
<desc>Created with bin/sketchtool.</desc>
<defs></defs>
<g id="02-Chat" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="02_13-Chat-member-profile" sketch:type="MSArtboardGroup" transform="translate(-873.000000, -722.000000)">
<g id="icons_upload" sketch:type="MSLayerGroup" transform="translate(873.000000, 722.000000)">
<g id="Rectangle-5-+-Rectangle-6" sketch:type="MSShapeGroup">
<path d="M0,4.00955791 C0,1.79514022 1.78163126,0 3.99825563,0 L9.59161955,0 C9.59161955,0 16.3225806,6.49234232 16.3225806,6.49234232 L16.3225806,18.0063928 C16.3225806,20.2120012 14.5290874,22 12.3296282,22 L3.99295243,22 C1.7877057,22 0,20.1996477 0,17.9904421 L0,4.00955791 Z" id="Rectangle-5" stroke="#76CFA6"></path>
<path d="M15.6804916,7.49527496 L11.5273266,7.49527496 C10.3308881,7.49527496 9.3609831,6.52527676 9.3609831,5.3289315 L9.3609831,1.88544393 L15.6804916,7.49527496 Z" id="Rectangle-6-Copy" fill="#FFFFFF"></path>
<path d="M16.3225806,7.09677419 L11.4129801,7.09677419 C10.2050375,7.09677419 9.22580645,6.11744908 9.22580645,4.90960051 L9.22580645,0" id="Rectangle-6" stroke="#76CFA6"></path>
</g>
<path d="M12.3736951,12.709235 C12.5125582,12.709235 12.6514212,12.6596674 12.7577382,12.5598531 C12.9689258,12.3609035 12.9689258,12.0390533 12.7577382,11.8401037 L8.61860697,7.95549406 C8.40741942,7.75654446 8.06387804,7.75722347 7.85196724,7.95481505 L3.70777326,11.8339926 C3.49586247,12.0329422 3.49513923,12.3554714 3.70632677,12.554421 C3.91751432,12.7540496 4.2610557,12.7540496 4.4729665,12.555779 L7.69791605,9.53690567 L7.69936254,17.9423563 C7.69936254,18.2234659 7.94309612,18.4516129 8.24179631,18.4516129 C8.541943,18.4516129 8.78423008,18.2234659 8.78423008,17.9423563 L8.78278359,9.54980684 L11.9903753,12.5598531 C12.095969,12.6596674 12.2348321,12.709235 12.3736951,12.709235 L12.3736951,12.709235 Z" id="Fill-75" fill="#76CFA6" sketch:type="MSShapeGroup"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="19px" height="24px" viewBox="-1 -1 19 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: bin/sketchtool 1.4 (305) - http://www.bohemiancoding.com/sketch -->
<title>icons_upload</title>
<desc>Created with bin/sketchtool.</desc>
<defs></defs>
<g id="02-Chat" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="02_13-Chat-member-profile" sketch:type="MSArtboardGroup" transform="translate(-873.000000, -722.000000)">
<g id="icons_upload" sketch:type="MSLayerGroup" transform="translate(873.000000, 722.000000)">
<g id="Rectangle-5-+-Rectangle-6" sketch:type="MSShapeGroup">
<path d="M0,4.00955791 C0,1.79514022 1.78163126,0 3.99825563,0 L9.59161955,0 C9.59161955,0 16.3225806,6.49234232 16.3225806,6.49234232 L16.3225806,18.0063928 C16.3225806,20.2120012 14.5290874,22 12.3296282,22 L3.99295243,22 C1.7877057,22 0,20.1996477 0,17.9904421 L0,4.00955791 Z" id="Rectangle-5" stroke="#76CFA6"></path>
<path d="M15.6804916,7.49527496 L11.5273266,7.49527496 C10.3308881,7.49527496 9.3609831,6.52527676 9.3609831,5.3289315 L9.3609831,1.88544393 L15.6804916,7.49527496 Z" id="Rectangle-6-Copy" fill="#FFFFFF"></path>
<path d="M16.3225806,7.09677419 L11.4129801,7.09677419 C10.2050375,7.09677419 9.22580645,6.11744908 9.22580645,4.90960051 L9.22580645,0" id="Rectangle-6" stroke="#76CFA6"></path>
</g>
<path d="M12.3736951,12.709235 C12.5125582,12.709235 12.6514212,12.6596674 12.7577382,12.5598531 C12.9689258,12.3609035 12.9689258,12.0390533 12.7577382,11.8401037 L8.61860697,7.95549406 C8.40741942,7.75654446 8.06387804,7.75722347 7.85196724,7.95481505 L3.70777326,11.8339926 C3.49586247,12.0329422 3.49513923,12.3554714 3.70632677,12.554421 C3.91751432,12.7540496 4.2610557,12.7540496 4.4729665,12.555779 L7.69791605,9.53690567 L7.69936254,17.9423563 C7.69936254,18.2234659 7.94309612,18.4516129 8.24179631,18.4516129 C8.541943,18.4516129 8.78423008,18.2234659 8.78423008,17.9423563 L8.78278359,9.54980684 L11.9903753,12.5598531 C12.095969,12.6596674 12.2348321,12.709235 12.3736951,12.709235 L12.3736951,12.709235 Z" id="Fill-75" fill="#76CFA6" sketch:type="MSShapeGroup"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="31px" height="27px" viewBox="-2 -2 31 27" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.3 (16618) - http://www.bohemiancoding.com/sketch -->
<title>icons_video copy</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="05-Voice-and-video" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="05_2-Video-call" sketch:type="MSArtboardGroup" transform="translate(-871.000000, -667.000000)" stroke="#FFFFFF">
<g id="icons_video-copy" sketch:type="MSLayerGroup" transform="translate(871.000000, 666.000000)">
<g id="Rectangle-20-+-Path-16" transform="translate(0.000000, 0.464286)" sketch:type="MSShapeGroup">
<rect id="Rectangle-20" x="0" y="0.535714286" width="20" height="20" rx="4"></rect>
<path d="M20.75,10.6964286 C20.75,14.0446429 24.188247,15.7371974 24.188247,15.7371974 C25.5057636,16.651593 26.5738219,16.0843085 26.5738219,14.4868066 L26.5738219,6.90605053 C26.5738219,5.30108314 25.4784055,4.70120148 24.188247,5.65565975 C24.188247,5.65565975 20.75,7.34821429 20.75,10.6964286 Z" id="Path-16"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="31px" height="27px" viewBox="-1 -1 31 27" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.4 (17249) - http://www.bohemiancoding.com/sketch -->
<title>icons_video copy</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="05-Voice-and-video" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="05_2-Video-call" sketch:type="MSArtboardGroup" transform="translate(-870.000000, -666.000000)" stroke="#FFFFFF">
<g id="icons_video-copy" sketch:type="MSLayerGroup" transform="translate(870.000000, 666.000000)">
<g id="Rectangle-20-+-Path-16" transform="translate(1.000000, 0.464286)" sketch:type="MSShapeGroup">
<rect id="Rectangle-20" x="0" y="0.535714286" width="20" height="20" rx="4"></rect>
<path d="M20.75,10.6964286 C20.75,14.0446429 24.188247,15.7371974 24.188247,15.7371974 C25.5057636,16.651593 26.5738219,16.0843085 26.5738219,14.4868066 L26.5738219,6.90605053 C26.5738219,5.30108314 25.4784055,4.70120148 24.188247,5.65565975 C24.188247,5.65565975 20.75,7.34821429 20.75,10.6964286 Z" id="Path-16"></path>
</g>
<path d="M24,1 L0.00856596586,23.6585766" id="Path-98" sketch:type="MSShapeGroup"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="21px" height="26px" viewBox="-4 -1 21 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.3 (16618) - http://www.bohemiancoding.com/sketch -->
<title>Audio</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="05-Voice-and-video" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="05_2-Video-call" sketch:type="MSArtboardGroup" transform="translate(-915.000000, -665.000000)" fill="#FFFFFF">
<g id="Audio" sketch:type="MSLayerGroup" transform="translate(915.000000, 665.000000)">
<path d="M3.51108197,4.57927869 C3.51108197,2.62701639 5.09940984,1.03868852 7.05206557,1.03868852 C9.00472131,1.03868852 10.5930492,2.62701639 10.5930492,4.57927869 L10.5930492,12.448918 C10.5930492,14.4015738 9.00472131,15.9899016 7.05206557,15.9899016 C5.09940984,15.9899016 3.51108197,14.4015738 3.51108197,12.448918 L3.51108197,4.57927869 L3.51108197,4.57927869 Z M7.05206557,16.7767869 C9.44183607,16.7767869 11.3799344,14.839082 11.3799344,12.448918 L11.3799344,4.57927869 C11.3799344,2.18911475 9.44183607,0.251803279 7.05206557,0.251803279 C4.66229508,0.251803279 2.72419672,2.18911475 2.72419672,4.57927869 L2.72419672,12.448918 C2.72419672,14.839082 4.66229508,16.7767869 7.05206557,16.7767869 Z M12.9517377,8.51409836 L12.9517377,12.448918 C12.9517377,15.703082 10.3042623,18.3505574 7.05009836,18.3505574 C3.79554098,18.3505574 1.14845902,15.703082 1.14845902,12.448918 L1.14845902,8.51409836 L0.36157377,8.51409836 L0.36157377,12.448918 C0.36157377,16.0217705 3.17980328,18.9407213 6.70898361,19.1201311 L6.65862295,19.1201311 L6.65862295,23.080918 L3.11567213,23.080918 L3.11567213,23.8678033 L10.9845246,23.8678033 L10.9845246,23.080918 L7.4455082,23.080918 L7.4455082,19.1201311 L7.39121311,19.1201311 C10.9203934,18.9407213 13.738623,16.0217705 13.738623,12.448918 L13.738623,8.51409836 L12.9517377,8.51409836 Z" id="Fill-16" sketch:type="MSShapeGroup"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="21px" height="26px" viewBox="-1 -1 21 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.4 (17249) - http://www.bohemiancoding.com/sketch -->
<title>Audio</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="05-Voice-and-video" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="05_2-Video-call" sketch:type="MSArtboardGroup" transform="translate(-912.000000, -665.000000)">
<g id="Audio" sketch:type="MSLayerGroup" transform="translate(912.000000, 665.000000)">
<path d="M6.51108197,4.57927869 C6.51108197,2.62701639 8.09940984,1.03868852 10.0520656,1.03868852 C12.0047213,1.03868852 13.5930492,2.62701639 13.5930492,4.57927869 L13.5930492,12.448918 C13.5930492,14.4015738 12.0047213,15.9899016 10.0520656,15.9899016 C8.09940984,15.9899016 6.51108197,14.4015738 6.51108197,12.448918 L6.51108197,4.57927869 L6.51108197,4.57927869 Z M10.0520656,16.7767869 C12.4418361,16.7767869 14.3799344,14.839082 14.3799344,12.448918 L14.3799344,4.57927869 C14.3799344,2.18911475 12.4418361,0.251803279 10.0520656,0.251803279 C7.66229508,0.251803279 5.72419672,2.18911475 5.72419672,4.57927869 L5.72419672,12.448918 C5.72419672,14.839082 7.66229508,16.7767869 10.0520656,16.7767869 Z M15.9517377,8.51409836 L15.9517377,12.448918 C15.9517377,15.703082 13.3042623,18.3505574 10.0500984,18.3505574 C6.79554098,18.3505574 4.14845902,15.703082 4.14845902,12.448918 L4.14845902,8.51409836 L3.36157377,8.51409836 L3.36157377,12.448918 C3.36157377,16.0217705 6.17980328,18.9407213 9.70898361,19.1201311 L9.65862295,19.1201311 L9.65862295,23.080918 L6.11567213,23.080918 L6.11567213,23.8678033 L13.9845246,23.8678033 L13.9845246,23.080918 L10.4455082,23.080918 L10.4455082,19.1201311 L10.3912131,19.1201311 C13.9203934,18.9407213 16.738623,16.0217705 16.738623,12.448918 L16.738623,8.51409836 L15.9517377,8.51409836 Z" id="Fill-16" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
<path d="M19,3 L0.272141024,20.6874224" id="Path-98" stroke="#FFFFFF" sketch:type="MSShapeGroup"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 856 B

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="16px" height="26px" viewBox="0 0 16 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.2 (15857) - http://www.bohemiancoding.com/sketch -->
<title>icon_voice</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="icon_voice" sketch:type="MSLayerGroup" fill="#76CFA6">
<path d="M15.690213,10.5130204 C15.690213,9.68172789 15.0096307,9.00560998 14.1739648,9.00560998 C13.3355096,9.00560998 12.6543693,9.68172789 12.6543693,10.5130204 L12.6554851,13.5200825 C12.6510222,13.5599846 11.9274851,17.4980943 7.84566437,17.4980943 C3.7599387,17.4980943 3.03472797,13.5815982 3.03361226,13.5500091 L3.03361226,10.5130204 C3.03361226,9.68172789 2.35302989,9.00560998 1.51680613,9.00560998 C0.680024521,9.00560998 0,9.68172789 0,10.5130204 L0,13.5500091 C0,15.5922177 1.86211801,19.602927 6.32830038,20.3771374 L6.32830038,22.9513732 L2.35358774,22.9513732 C1.51680613,22.9513732 0.836781609,23.6280454 0.836781609,24.4593379 C0.836781609,25.2900762 1.51680613,25.9661941 2.35358774,25.9661941 L13.3371831,25.9661941 C14.1717333,25.9661941 14.8506421,25.2900762 14.8506421,24.4593379 C14.8506421,23.6280454 14.1717333,22.9513732 13.3371831,22.9513732 L9.36079693,22.9513732 L9.36079693,20.3771374 C13.828095,19.602927 15.690213,15.5922177 15.690213,13.5500091 L15.690213,10.5130204 Z M13.3371831,23.7826658 C13.7098299,23.7826658 14.0138605,24.0863646 14.0138605,24.4593379 C14.0138605,24.8317569 13.7098299,25.1349016 13.3371831,25.1349016 L2.35358774,25.1349016 C1.97870958,25.1349016 1.67356322,24.8317569 1.67356322,24.4593379 C1.67356322,24.0863646 1.97870958,23.7826658 2.35358774,23.7826658 L6.74613333,23.7826658 C6.97764291,23.7826658 7.16508199,23.5970104 7.16508199,23.3670195 L7.16508199,20.0196816 C7.16508199,19.8113043 7.00888276,19.6350703 6.80024521,19.6079147 C2.63809349,19.0681288 0.836781609,15.334517 0.836781609,13.5500091 L0.836781609,10.5130204 C0.836781609,10.1400472 1.14192797,9.83690249 1.51680613,9.83690249 C1.89168429,9.83690249 2.19683065,10.1400472 2.19683065,10.5130204 L2.19683065,13.555551 C2.20519847,14.1812372 3.30696092,18.3293868 7.84566437,18.3293868 C12.2990161,18.3293868 13.491151,14.1175048 13.491151,13.5500091 L13.491151,10.5130204 C13.491151,10.1400472 13.797413,9.83690249 14.1739648,9.83690249 C14.5488429,9.83690249 14.8539893,10.1400472 14.8539893,10.5130204 L14.8539893,13.5500091 C14.8539893,15.334517 13.0532352,19.0681288 8.88940996,19.6079147 C8.68077241,19.6350703 8.52401533,19.8113043 8.52401533,20.0196816 L8.52401533,23.3670195 C8.52401533,23.5970104 8.71201226,23.7826658 8.94296398,23.7826658 L13.3371831,23.7826658 Z" id="Fill-200" sketch:type="MSShapeGroup"></path>
<path d="M3.04309579,10.1578404 L3.04309579,8.37998277 L3.04309579,7.54869025 L3.04309579,6.79997279 L3.04309579,5.96868027 L3.04309579,5.63727166 C3.04309579,5.49650612 3.05257931,5.35795737 3.06429425,5.21996281 L3.21324138,4.38867029 C3.76384368,2.3436907 5.62875096,0.831292517 7.84510651,0.831292517 C10.0609042,0.831292517 11.9263693,2.3436907 12.4775295,4.38867029 L12.6259188,5.21996281 C12.6376337,5.35795737 12.6476751,5.49650612 12.6476751,5.63727166 L12.6476751,5.96868027 L12.6476751,6.79997279 L12.6476751,7.54869025 L12.6476751,8.37998277 L12.6476751,10.1578404 C12.6476751,10.3872771 12.8351142,10.5734866 13.0660659,10.5734866 C13.2970176,10.5734866 13.4844567,10.3872771 13.4844567,10.1578404 L13.4844567,5.63727166 C13.4844567,2.52934603 10.954587,0 7.84510651,0 C4.7350682,0 2.20631418,2.52934603 2.20631418,5.63727166 L2.20631418,10.1578404 C2.20631418,10.3872771 2.39375326,10.5734866 2.62470498,10.5734866 C2.8556567,10.5734866 3.04309579,10.3872771 3.04309579,10.1578404 Z" id="Path" sketch:type="MSShapeGroup"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="22px" height="17px" viewBox="-1 -1 22 17" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.4 (17249) - http://www.bohemiancoding.com/sketch -->
<title>Triangle 1</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="05-Voice-and-video" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="05_2-Video-call" sketch:type="MSArtboardGroup" transform="translate(-912.000000, -693.000000)" fill="#76CFA6">
<polygon id="Triangle-1" sketch:type="MSShapeGroup" transform="translate(922.000000, 700.500000) scale(1, -1) translate(-922.000000, -700.500000) " points="922 693 932 708 912 708 "></polygon>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 902 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 903 B

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 23" style="enable-background:new 0 0 24 23;" xml:space="preserve">
<style type="text/css">
.st0{clip-path:url(#SVGID_2_);fill:#FF0064;}
.st1{clip-path:url(#SVGID_4_);fill:#FFFFFF;}
</style>
<g>
<g>
<defs>
<path id="SVGID_1_" d="M9.2,2.2c1.6-2.9,4.1-2.9,5.7,0l8.3,15.4c1.6,2.9,0.2,5.3-3.2,5.3H4c-3.3,0-4.7-2.4-3.2-5.3L9.2,2.2
L9.2,2.2z M9.2,2.2"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
</clipPath>
<rect x="-4.8" y="-5" class="st0" width="33.6" height="32.9"/>
</g>
<g>
<defs>
<path id="SVGID_3_" d="M12.7,15L13,5.4H11l0.3,9.6H12.7L12.7,15z M12,19.1c0.7,0,1.2-0.5,1.2-1.2c0-0.7-0.5-1.2-1.2-1.2
c-0.7,0-1.2,0.5-1.2,1.2C10.8,18.6,11.3,19.1,12,19.1L12,19.1L12,19.1z M12,19.1"/>
</defs>
<clipPath id="SVGID_4_">
<use xlink:href="#SVGID_3_" style="overflow:visible;"/>
</clipPath>
<rect x="5.8" y="0.4" class="st1" width="12.4" height="23.7"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,93 +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.
*/
/*
* THIS FILE IS AUTO-GENERATED
* You can edit it you like, but your changes will be overwritten,
* so you'd just be trying to swim upstream like a salmon.
* You are not a salmon.
*/
var skin = {};
skin['atoms.EditableText'] = require('./views/atoms/EditableText');
skin['atoms.EnableNotificationsButton'] = require('./views/atoms/EnableNotificationsButton');
skin['atoms.ImageView'] = require('./views/atoms/ImageView');
skin['atoms.LogoutButton'] = require('./views/atoms/LogoutButton');
skin['atoms.MemberAvatar'] = require('./views/atoms/MemberAvatar');
skin['atoms.MessageTimestamp'] = require('./views/atoms/MessageTimestamp');
skin['atoms.RoomAvatar'] = require('./views/atoms/RoomAvatar');
skin['atoms.Spinner'] = require('./views/atoms/Spinner');
skin['atoms.create_room.CreateRoomButton'] = require('./views/atoms/create_room/CreateRoomButton');
skin['atoms.create_room.Presets'] = require('./views/atoms/create_room/Presets');
skin['atoms.create_room.RoomAlias'] = require('./views/atoms/create_room/RoomAlias');
skin['atoms.voip.VideoFeed'] = require('./views/atoms/voip/VideoFeed');
skin['molecules.BottomLeftMenu'] = require('./views/molecules/BottomLeftMenu');
skin['molecules.BottomLeftMenuTile'] = require('./views/molecules/BottomLeftMenuTile');
skin['molecules.ChangeAvatar'] = require('./views/molecules/ChangeAvatar');
skin['molecules.ChangeDisplayName'] = require('./views/molecules/ChangeDisplayName');
skin['molecules.ChangePassword'] = require('./views/molecules/ChangePassword');
skin['molecules.DateSeparator'] = require('./views/molecules/DateSeparator');
skin['molecules.EventAsTextTile'] = require('./views/molecules/EventAsTextTile');
skin['molecules.EventTile'] = require('./views/molecules/EventTile');
skin['molecules.MEmoteTile'] = require('./views/molecules/MEmoteTile');
skin['molecules.MFileTile'] = require('./views/molecules/MFileTile');
skin['molecules.MImageTile'] = require('./views/molecules/MImageTile');
skin['molecules.MNoticeTile'] = require('./views/molecules/MNoticeTile');
skin['molecules.MRoomMemberTile'] = require('./views/molecules/MRoomMemberTile');
skin['molecules.MTextTile'] = require('./views/molecules/MTextTile');
skin['molecules.MatrixToolbar'] = require('./views/molecules/MatrixToolbar');
skin['molecules.MemberInfo'] = require('./views/molecules/MemberInfo');
skin['molecules.MemberTile'] = require('./views/molecules/MemberTile');
skin['molecules.MessageComposer'] = require('./views/molecules/MessageComposer');
skin['molecules.MessageContextMenu'] = require('./views/molecules/MessageContextMenu');
skin['molecules.MessageTile'] = require('./views/molecules/MessageTile');
skin['molecules.ProgressBar'] = require('./views/molecules/ProgressBar');
skin['molecules.RoomCreate'] = require('./views/molecules/RoomCreate');
skin['molecules.RoomDropTarget'] = require('./views/molecules/RoomDropTarget');
skin['molecules.RoomHeader'] = require('./views/molecules/RoomHeader');
skin['molecules.RoomSettings'] = require('./views/molecules/RoomSettings');
skin['molecules.RoomTile'] = require('./views/molecules/RoomTile');
skin['molecules.RoomTooltip'] = require('./views/molecules/RoomTooltip');
skin['molecules.SearchBar'] = require('./views/molecules/SearchBar');
skin['molecules.SenderProfile'] = require('./views/molecules/SenderProfile');
skin['molecules.ServerConfig'] = require('./views/molecules/ServerConfig');
skin['molecules.UnknownMessageTile'] = require('./views/molecules/UnknownMessageTile');
skin['molecules.UserSelector'] = require('./views/molecules/UserSelector');
skin['molecules.voip.CallView'] = require('./views/molecules/voip/CallView');
skin['molecules.voip.IncomingCallBox'] = require('./views/molecules/voip/IncomingCallBox');
skin['molecules.voip.VideoView'] = require('./views/molecules/voip/VideoView');
skin['organisms.CasLogin'] = require('./views/organisms/CasLogin');
skin['organisms.CreateRoom'] = require('./views/organisms/CreateRoom');
skin['organisms.ErrorDialog'] = require('./views/organisms/ErrorDialog');
skin['organisms.LeftPanel'] = require('./views/organisms/LeftPanel');
skin['organisms.LogoutPrompt'] = require('./views/organisms/LogoutPrompt');
skin['organisms.MemberList'] = require('./views/organisms/MemberList');
skin['organisms.Notifier'] = require('./views/organisms/Notifier');
skin['organisms.QuestionDialog'] = require('./views/organisms/QuestionDialog');
skin['organisms.RightPanel'] = require('./views/organisms/RightPanel');
skin['organisms.RoomDirectory'] = require('./views/organisms/RoomDirectory');
skin['organisms.RoomList'] = require('./views/organisms/RoomList');
skin['organisms.RoomSubList'] = require('./views/organisms/RoomSubList');
skin['organisms.RoomView'] = require('./views/organisms/RoomView');
skin['organisms.UserSettings'] = require('./views/organisms/UserSettings');
skin['organisms.ViewSource'] = require('./views/organisms/ViewSource');
skin['pages.CompatibilityPage'] = require('./views/pages/CompatibilityPage');
skin['pages.MatrixChat'] = require('./views/pages/MatrixChat');
skin['templates.Login'] = require('./views/templates/Login');
skin['templates.Register'] = require('./views/templates/Register');
module.exports = skin;

View File

@ -1,3 +0,0 @@
{
"baseSkin": ""
}

View File

@ -1,76 +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';
var React = require('react');
var EditableTextController = require('matrix-react-sdk/lib/controllers/atoms/EditableText')
module.exports = React.createClass({
displayName: 'EditableText',
mixins: [EditableTextController],
onKeyUp: function(ev) {
if (ev.key == "Enter") {
this.onFinish(ev);
} else if (ev.key == "Escape") {
this.cancelEdit();
}
},
onClickDiv: function() {
this.setState({
phase: this.Phases.Edit,
})
},
onFocus: function(ev) {
ev.target.setSelectionRange(0, ev.target.value.length);
},
onFinish: function(ev) {
if (ev.target.value) {
this.setValue(ev.target.value, ev.key === "Enter");
} else {
this.cancelEdit();
}
},
render: function() {
var editable_el;
if (this.state.phase == this.Phases.Display) {
if (this.state.value) {
editable_el = <div ref="display_div" onClick={this.onClickDiv}>{this.state.value}</div>;
} else {
editable_el = <div ref="display_div" onClick={this.onClickDiv}>{this.props.label}</div>;
}
} else if (this.state.phase == this.Phases.Edit) {
editable_el = (
<div>
<input type="text" defaultValue={this.state.value} onKeyUp={this.onKeyUp} onFocus={this.onFocus} onBlur={this.onFinish} placeholder={this.props.placeHolder} autoFocus/>
</div>
);
}
return (
<div className="mx_EditableText">
{editable_el}
</div>
);
}
});

View File

@ -1,38 +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';
var React = require('react');
var EnableNotificationsButtonController = require('matrix-react-sdk/lib/controllers/atoms/EnableNotificationsButton')
module.exports = React.createClass({
displayName: 'EnableNotificationsButton',
mixins: [EnableNotificationsButtonController],
render: function() {
if (this.enabled()) {
return (
<button className="mx_EnableNotificationsButton" onClick={this.onClick}>Disable Notifications</button>
);
} else {
return (
<button className="mx_EnableNotificationsButton" onClick={this.onClick}>Enable Notifications</button>
);
}
}
});

View File

@ -1,32 +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';
var React = require('react');
var LogoutButtonController = require('matrix-react-sdk/lib/controllers/atoms/LogoutButton')
module.exports = React.createClass({
displayName: 'LogoutButton',
mixins: [LogoutButtonController],
render: function() {
return (
<button className="mx_LogoutButton" onClick={this.onClick}>Sign out</button>
);
}
});

View File

@ -1,68 +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';
var React = require('react');
var Avatar = require('../../../../Avatar');
var MemberAvatarController = require('matrix-react-sdk/lib/controllers/atoms/MemberAvatar')
module.exports = React.createClass({
displayName: 'MemberAvatar',
mixins: [MemberAvatarController],
avatarUrlForMember: function(member) {
return Avatar.avatarUrlForMember(
member,
this.props.member,
this.props.width,
this.props.height,
this.props.resizeMethod
);
},
skinnedDefaultAvatarUrl: function(member, width, height, resizeMethod) {
return Avatar.defaultAvatarUrlForString(member.userId);
},
render: function() {
// XXX: recalculates default avatar url constantly
if (this.state.imageUrl === this.defaultAvatarUrl(this.props.member)) {
var initial;
if (this.props.member.name[0])
initial = this.props.member.name[0].toUpperCase();
if (initial === '@' && this.props.member.name[1])
initial = this.props.member.name[1].toUpperCase();
return (
<span className="mx_MemberAvatar">
<span className="mx_MemberAvatar_initial" aria-hidden="true"
style={{ fontSize: (this.props.width * 0.75) + "px",
width: this.props.width + "px",
lineHeight: this.props.height*1.2 + "px" }}>{ initial }</span>
<img className="mx_MemberAvatar_image" src={this.state.imageUrl}
onError={this.onError} width={this.props.width} height={this.props.height} />
</span>
);
}
return (
<img className="mx_MemberAvatar mx_MemberAvatar_image" src={this.state.imageUrl}
onError={this.onError}
width={this.props.width} height={this.props.height} />
);
}
});

Some files were not shown because too many files have changed in this diff Show More