Merge remote-tracking branch 'upstream/develop' into fix_4821

pull/5900/head
nostradamos 2018-01-02 12:58:30 +01:00
commit 762f6aaf0f
80 changed files with 1804 additions and 326 deletions

View File

@ -1,3 +1,5 @@
<!-- Please report security issues by email to security@matrix.org -->
<!-- This is a bug report template. By following the instructions below and <!-- This is a bug report template. By following the instructions below and
filling out the sections with your information, you will help the us to get all filling out the sections with your information, you will help the us to get all
the necessary data to fix your issue. the necessary data to fix your issue.

View File

@ -13,3 +13,6 @@ include:
* Michael Telatynski (https://github.com/t3chguy) * Michael Telatynski (https://github.com/t3chguy)
Improved consistency of inverted elements in dark theme across browsers Improved consistency of inverted elements in dark theme across browsers
* Alexandr Korsak (https://github.com/oivoodoo)
Improved multiple file uploading

View File

@ -1,6 +1,10 @@
{ {
"default_hs_url": "https://matrix.org", "default_hs_url": "https://matrix.org",
"default_is_url": "https://vector.im", "default_is_url": "https://vector.im",
"disable_custom_urls": false,
"disable_guests": false,
"disable_login_language_selector": false,
"disable_3pid_login": false,
"brand": "Riot", "brand": "Riot",
"integrations_ui_url": "https://scalar.vector.im/", "integrations_ui_url": "https://scalar.vector.im/",
"integrations_rest_url": "https://scalar.vector.im/api", "integrations_rest_url": "https://scalar.vector.im/api",
@ -10,6 +14,8 @@
"feature_pinning": "labs" "feature_pinning": "labs"
}, },
"default_federate": true, "default_federate": true,
"welcomePageUrl": "home.html",
"default_theme": "light",
"roomDirectory": { "roomDirectory": {
"servers": [ "servers": [
"matrix.org" "matrix.org"

68
docs/skinning thoughts.md Normal file
View File

@ -0,0 +1,68 @@
== Skinning refactor ==
matrix-react-sdk
- base images
- base CSS
- all the components needed to build a workable app (including the top layer)
riot-web: the riot skin
- riot-specific classes (e.g. login header/footer)
- riot-specific themes
- light
- dark
i.e. the only things which should go into riot-web are bits which apply vector-specific skinning
specifically "Stuff that any other brand would not want to use. (e.g. riot logos, links, T&Cs)"
- Questions:
- Electron app? (should probably be a separate repo in its own right? but might as well go here for now)
- index.html & index.js? (should be in matrix-react-sdk, given the SDK is useless without them?)
ideally matrix-react-sdk itself should ship with a default skin which actually works built in.
status skin (can go in the same app for now)
- has status theme
- which inherits from riot light theme
- how do we share graphics between skins?
- shove them into react-sdk, or...
- guess we do ../../vector/img
- this means keeping the skin name in the images (unless /img is a shortcut to the right skin's images)
out of scope:
- making the components more independent, so they can be used in isolation.
- that said, the bits which should probably be used by being embeded into a different app:
- login/reg
- RoomView + RoomSettings
- MessageComposer
- RoomList
- MemberList
- MemberInfo
- Voip UI
- UserSettings
- sharing different js-sdks between the different isolated modules
other changes:
- how do we handle i18n?
- each skin should really be its own i18n project. As long as all the commonality stuff is in matrix-react-sdk this shouldn't be too bad.
- ability to associate components with a given skin
- skins/vector/src <-- components
- skins/vector/css
- skins/vector/img
- skins/vector/fonts
- gather together themes (per skin) into a single place too
- skins/vector/themes/foo/css
- skins/vector/themes/foo/img
- skins/vector/themes/foo/fonts
- ideally riot-web would contain almost nothing but skins/vector directory.
- ability to entirely replace CSS rather than override it for a given theme
- e.g. if we replace `Login.js` with `StatusLogin.js`, then we should similarly be able to replace `_Login.scss` with `_StatusLogin.scss`.
random thoughts;
- should we be able to change the entire skin at runtime (more like wordpress) - to the extent of replacing entire components?
- might pose security issues if a theme can be swapped out to replace MatrixChat or other fundamental functionality at runtime
- if so, perhaps skins & themes should converge...
-----------------
Immediate plan for Status:
* Implement it as a theme for the riot skin
* Ideally move skins to a sensible level (possibly even including src?)

View File

@ -36,9 +36,13 @@ function getColorName(hex) {
## Adding variables inside a string. ## Adding variables inside a string.
1. Extend your ``_t()`` call. Instead of ``_t(STRING)`` use ``_t(STRING, {})`` 1. Extend your ``_t()`` call. Instead of ``_t(STRING)`` use ``_t(STRING, {})``
2. Decide how to name it. Please think about if the person who has to translate it can understand what it does. 1. Decide how to name it. Please think about if the person who has to translate it can understand what it does. E.g. using the name 'recipient' is bad, because a translator does not know if it is the name of a person, an email address, a user ID, etc. Rather use e.g. recipientEmailAddress.
3. Add it to the array in ``_t`` for example ``_t(STRING, {variable: this.variable})`` 1. Add it to the array in ``_t`` for example ``_t(STRING, {variable: this.variable})``
4. Add the variable inside the string. The syntax for variables is ``%(variable)s``. Please note the s at the end. The name of the variable has to match the previous used name. 1. Add the variable inside the string. The syntax for variables is ``%(variable)s``. Please note the _s_ at the end. The name of the variable has to match the previous used name.
- You can use the special ``count`` variable to choose between multiple versions of the same string, in order to get the correct pluralization. E.g. ``_t('You have %(count)s new messages', { count: 2 })`` would show 'You have 2 new messages', while ``_t('You have %(count)s new messages', { count: 1 })`` would show 'You have one new message' (assuming a singular version of the string has been added to the translation file. See above). Passing in ``count`` is much prefered over having an if-statement choose the correct string to use, because some languages have much more complicated plural rules than english (e.g. they might need a completely different form if there are three things rather than two).
- If you want to translate text that includes e.g. hyperlinks or other HTML you have to also use tag substitution, e.g. ``_t('<a>Click here!</a>', {}, { 'a': (sub) => <a>{sub}</a> })``. If you don't do the tag substitution you will end up showing literally '<a>' rather than making a hyperlink.
- You can also use React components with normal variable substitution if you want to insert HTML markup, e.g. ``_t('Your email address is %(emailAddress)s', { emailAddress: <i>{userEmailAddress}</i> })``.
## Things to know/Style Guides ## Things to know/Style Guides
@ -47,3 +51,5 @@ function getColorName(hex) {
- If a string is presented in the UI with punctuation like a full stop, include this in the translation strings, since punctuation varies between languages too. - If a string is presented in the UI with punctuation like a full stop, include this in the translation strings, since punctuation varies between languages too.
- Avoid "translation in parts", i.e. concatenating translated strings or using translated strings in variable substitutions. Context is important for translations, and translating partial strings this way is simply not always possible. - Avoid "translation in parts", i.e. concatenating translated strings or using translated strings in variable substitutions. Context is important for translations, and translating partial strings this way is simply not always possible.
- Concatenating strings often also introduces an implicit assumption about word order (e.g. that the subject of the sentence comes first), which is incorrect for many languages. - Concatenating strings often also introduces an implicit assumption about word order (e.g. that the subject of the sentence comes first), which is incorrect for many languages.
- Translation 'smell test': If you have a string that does not begin with a capital letter (is not the start of a sentence) or it ends with e.g. ':' or a preposition (e.g. 'to') you should recheck that you are not trying to translate a partial sentence.
- If you have multiple strings, that are almost identical, except some part (e.g. a word or two) it is still better to translate the full sentence multiple times. It may seem like inefficient repetion, but unlike programming where you try to minimize repetition, translation is much faster if you have many, full, clear, sentences to work with, rather than fewer, but incomplete sentence fragments.

View File

@ -5,6 +5,10 @@
"brand": "Riot", "brand": "Riot",
"integrations_ui_url": "https://scalar.vector.im/", "integrations_ui_url": "https://scalar.vector.im/",
"integrations_rest_url": "https://scalar.vector.im/api", "integrations_rest_url": "https://scalar.vector.im/api",
"integrations_widgets_urls": [
"https://scalar-staging.riot.im/scalar/api",
"https://scalar.vector.im/api"
],
"bug_report_endpoint_url": "https://riot.im/bugreports/submit", "bug_report_endpoint_url": "https://riot.im/bugreports/submit",
"welcomeUserId": "@riot-bot:matrix.org", "welcomeUserId": "@riot-bot:matrix.org",
"roomDirectory": { "roomDirectory": {

192
res/home-status.html Normal file
View File

@ -0,0 +1,192 @@
<style type="text/css">
/* we deliberately inline style here to avoid flash-of-CSS problems, and to avoid
* voodoo where we have to set display: none by default
*/
.mx_HomePage_container {
text-align: center;
display: block ! important;
width: 690px;
margin: 20px;
}
.mx_HomePage_header {
margin-top: 37px;
margin-left: 10px;
width: 670px;
box-sizing: border-box;
font-size: 18px;
background-color: #fff;
box-shadow: 0px 2px 10px 0px rgba(48,55,81,0.05);
border-radius: 5px;
padding: 20px 80px 20px 80px;
align-items: center;
}
.mx_HomePage_header h1 {
font-size: 29px;
margin-bottom: 10px;
}
.mx_HomePage_intro h2 {
margin-top: 32px;
font-size: 25px;
color: #49555F;
}
.mx_HomePage_intro {
margin: auto;
width: 600px;
margin-top: 40px;
margin-bottom: 40px;
font-size: 18px;
}
.mx_HomePage_coc {
font-size: 16px;
}
.mx_HomePage_coc a {
color: #4360DF;
}
.mx_HomePage_room, .mx_HomePage_telegram {
float: left;
background-color: #fff;
box-shadow: 0px 2px 10px 0px rgba(48,55,81,0.05);
border-radius: 5px;
margin: 10px;
width: 210px;
height: 250px;
display: flex;
flex-direction: column;
align-items: center;
}
.mx_HomePage_telegram {
background-color: transparent;
border: 1px solid rgba(113, 129, 142, 0.2);
box-shadow: none;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
font-size: 16px;
line-height: 25px;
box-sizing: border-box;
}
.mx_HomePage_telegram a {
text-transform: uppercase;
color: #4360DF;
font-size: 13px;
font-family: PostGrotesk-Medium, Arial, Helvetica, Sans-Serif;
font-weight: 600;
opacity: 1.0;
transition: opacity .2s ease;
}
.mx_HomePage_telegram a:hover {
opacity: 0.5;
}
.mx_HomePage_room .mx_HomePage_icon {
margin-top: 24px;
margin-bottom: 16px;
width: 50px;
height: 50px;
}
.mx_HomePage_room .mx_HomePage_name {
display: block;
font-family: PostGrotesk-Medium, Arial, Helvetica, Sans-Serif;
font-weight: 600;
font-size: 15px;
color: #49555F;
line-height: 25px;
margin: 0px 12px 0px 12px;
}
.mx_HomePage_room .mx_HomePage_desc {
flex: 1;
display: block;
margin: 0px 12px 0px 12px;
font-size: 14px;
line-height: 20px;
}
.mx_HomePage_button {
align-self: normal;
margin: 12px;
border-radius: 8px;
border: 1px solid rgba(199, 206, 209, 0.12);
background-color: #6CC1F6;
font-size: 13px;
font-family: PostGrotesk-Medium, Arial, Helvetica, Sans-Serif;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1px;
color: #fff ! important;
cursor: pointer;
outline: none;
padding: 14px;
box-sizing: border-box;
padding-left: 1.5em;
padding-right: 1.5em;
}
</style>
<div class="mx_HomePage_container">
<div class="mx_HomePage_header">
<div>
<h1>Welcome to Status Community Chat, powered by Riot.</h1>
<p>For contributors, developers and Ethereum-enthusiasts who care about the movement for decentralization.</p>
</div>
</div>
<div class="mx_HomePage_intro">
<h2>Our rooms</h2>
<p>Please abide by the channels discussion categories and remain on topic to the specific category details listed.</p>
<p class="mx_HomePage_coc">Before posting please refer to our <a href="https://wiki.status.im/Code_of_conduct">Code of Conduct</a></p>
</div>
<div class="mx_HomePage_room">
<img class="mx_HomePage_icon" src="themes/status/img/a.png">
<span class="mx_HomePage_name">#announcements</span>
<span class="mx_HomePage_desc">Company wide announcements.</span>
<a class="mx_HomePage_button" href="#/room/#announcements:status.im">Join</a>
</div>
<div class="mx_HomePage_room">
<img class="mx_HomePage_icon" src="themes/status/img/i.png">
<span class="mx_HomePage_name">#introductions</span>
<span class="mx_HomePage_desc">Newcomer introductions.</span>
<a class="mx_HomePage_button" href="#/room/#introductions:status.im">Join</a>
</div>
<div class="mx_HomePage_room">
<img class="mx_HomePage_icon" src="themes/status/img/g.png">
<span class="mx_HomePage_name">#general</span>
<span class="mx_HomePage_desc">General discussions of Status.</span>
<a class="mx_HomePage_button" href="#/room/#general:status.im">Join</a>
</div>
<div class="mx_HomePage_room">
<img class="mx_HomePage_icon" src="themes/status/img/d.png">
<span class="mx_HomePage_name">#dev-status</span>
<span class="mx_HomePage_desc">Contributing to our codebase? Building a DApp or a chatbot? We're here to help.</span>
<a class="mx_HomePage_button" href="#/room/#dev-status:status.im">Join</a>
</div>
<div class="mx_HomePage_room">
<img class="mx_HomePage_icon" src="themes/status/img/n.png">
<span class="mx_HomePage_name">#news-articles</span>
<span class="mx_HomePage_desc">Share news, articles related to Ethereum or projects you're excited about</span>
<a class="mx_HomePage_button" href="#/room/#news-articles:status.im">Join</a>
</div>
<div class="mx_HomePage_telegram">
<p>
Interested in market and cryptocurrency type discussions?
</p>
<a href="https://t.me/StatusNetworkChat">Join Telegram</a>
</div>
</div>

View File

@ -43,10 +43,11 @@ const INCLUDE_LANGS = [
const COPY_LIST = [ const COPY_LIST = [
["res/manifest.json", "webapp"], ["res/manifest.json", "webapp"],
["res/home.html", "webapp"], ["res/home.html", "webapp"],
["res/home-status.html", "webapp"],
["res/home/**", "webapp/home"], ["res/home/**", "webapp/home"],
["res/{media,vector-icons}/**", "webapp"], ["res/{media,vector-icons}/**", "webapp"],
["res/flags/*", "webapp/flags/"], ["res/flags/*", "webapp/flags/"],
["src/skins/vector/{fonts,img}/**", "webapp"], ["src/skins/vector/{fonts,img,themes}/**", "webapp"],
["node_modules/emojione/assets/svg/*", "webapp/emojione/svg/"], ["node_modules/emojione/assets/svg/*", "webapp/emojione/svg/"],
["node_modules/emojione/assets/png/*", "webapp/emojione/png/"], ["node_modules/emojione/assets/png/*", "webapp/emojione/png/"],
["./config.json", "webapp", { directwatch: 1 }], ["./config.json", "webapp", { directwatch: 1 }],

View File

@ -21,7 +21,7 @@ import sdk from 'matrix-react-sdk';
import dis from 'matrix-react-sdk/lib/dispatcher'; import dis from 'matrix-react-sdk/lib/dispatcher';
import Velocity from 'velocity-vector'; import Velocity from 'velocity-vector';
import 'velocity-vector/velocity.ui'; import 'velocity-vector/velocity.ui';
import UserSettingsStore from 'matrix-react-sdk/lib/UserSettingsStore'; import SettingsStore from "matrix-react-sdk/lib/settings/SettingsStore";
const CALLOUT_ANIM_DURATION = 1000; const CALLOUT_ANIM_DURATION = 1000;

View File

@ -17,7 +17,7 @@ limitations under the License.
'use strict'; 'use strict';
var React = require('react'); var React = require('react');
import { _t, _tJsx } from 'matrix-react-sdk/lib/languageHandler'; import { _t } from 'matrix-react-sdk/lib/languageHandler';
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'CompatibilityPage', displayName: 'CompatibilityPage',
@ -40,30 +40,24 @@ module.exports = React.createClass({
return ( return (
<div className="mx_CompatibilityPage"> <div className="mx_CompatibilityPage">
<div className="mx_CompatibilityPage_box"> <div className="mx_CompatibilityPage_box">
<p>{ _tJsx("Sorry, your browser is <b>not</b> able to run Riot.", /<b>(.*?)<\/b>/, (sub) => <b>{sub}</b>) } </p> <p>{ _t("Sorry, your browser is <b>not</b> able to run Riot.", {}, { 'b': (sub) => <b>{sub}</b> }) } </p>
<p> <p>
{ _t("Riot uses many advanced browser features, some of which are not available or experimental in your current browser.") } { _t("Riot uses many advanced browser features, some of which are not available or experimental in your current browser.") }
</p> </p>
<p> <p>
{ _tJsx('Please install <a href="https://www.google.com/chrome">Chrome</a> or <a href="https://getfirefox.com">Firefox</a> for the best experience.', { _t('Please install <chromeLink>Chrome</chromeLink> or <firefoxLink>Firefox</firefoxLink> for the best experience.',
[ {},
/<a href="https:\/\/www.google.com\/chrome">(.*?)<\/a>/, {
/<a href="https:\/\/getfirefox.com">(.*?)<\/a>/, 'chromeLink': (sub) => <a href="https://www.google.com/chrome">{sub}</a>,
], 'firefoxLink': (sub) => <a href="https://getfirefox.com">{sub}</a>,
[ },
(sub) => <a href="https://www.google.com/chrome">{sub}</a>,
(sub) => <a href="https://getfirefox.com">{sub}</a>,
]
)} )}
{ _tJsx('<a href="http://apple.com/safari">Safari</a> and <a href="http://opera.com">Opera</a> work too.', { _t('<safariLink>Safari</safariLink> and <operaLink>Opera</operaLink> work too.',
[ {},
/<a href="http:\/\/apple\.com\/safari">(.*?)<\/a>/, {
/<a href="http:\/\/opera\.com">(.*?)<\/a>/, 'safariLink': (sub) => <a href="http://apple.com/safari">{sub}</a>,
], 'operaLink': (sub) => <a href="http://opera.com">{sub}</a>,
[ },
(sub) => <a href="http://apple.com/safari">{sub}</a>,
(sub) => <a href="http://opera.com">{sub}</a>,
]
)} )}
</p> </p>
<p> <p>

View File

@ -17,10 +17,8 @@ limitations under the License.
'use strict'; 'use strict';
import React from 'react'; import React from 'react';
import { DragDropContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import classNames from 'classnames'; import classNames from 'classnames';
import KeyCode from 'matrix-react-sdk/lib/KeyCode'; import { KeyCode } from 'matrix-react-sdk/lib/Keyboard';
import sdk from 'matrix-react-sdk'; import sdk from 'matrix-react-sdk';
import dis from 'matrix-react-sdk/lib/dispatcher'; import dis from 'matrix-react-sdk/lib/dispatcher';
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg'; import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
@ -199,4 +197,4 @@ var LeftPanel = React.createClass({
} }
}); });
module.exports = DragDropContext(HTML5Backend)(LeftPanel); module.exports = LeftPanel;

View File

@ -29,6 +29,8 @@ import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/Acc
import { showGroupInviteDialog, showGroupAddRoomDialog } from 'matrix-react-sdk/lib/GroupAddressPicker'; import { showGroupInviteDialog, showGroupAddRoomDialog } from 'matrix-react-sdk/lib/GroupAddressPicker';
import GroupStoreCache from 'matrix-react-sdk/lib/stores/GroupStoreCache'; import GroupStoreCache from 'matrix-react-sdk/lib/stores/GroupStoreCache';
import { formatCount } from 'matrix-react-sdk/lib/utils/FormattingUtils';
class HeaderButton extends React.Component { class HeaderButton extends React.Component {
constructor() { constructor() {
super(); super();
@ -47,12 +49,18 @@ class HeaderButton extends React.Component {
const TintableSvg = sdk.getComponent("elements.TintableSvg"); const TintableSvg = sdk.getComponent("elements.TintableSvg");
const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
return <AccessibleButton className="mx_RightPanel_headerButton" onClick={this.onClick} > return <AccessibleButton
aria-label={this.props.title}
title={this.props.title}
className="mx_RightPanel_headerButton"
onClick={this.onClick} >
<div className="mx_RightPanel_headerButton_badge"> <div className="mx_RightPanel_headerButton_badge">
{ this.props.badge ? this.props.badge : <span>&nbsp;</span> } { this.props.badge ? this.props.badge : <span>&nbsp;</span> }
</div> </div>
<TintableSvg src={this.props.iconSrc} width="25" height="25"/> <TintableSvg src={this.props.iconSrc} width="25" height="25"/>
{ this.props.isHighlighted ? <div className="mx_RightPanel_headerButton_highlight"></div> : <div/> } { this.props.isHighlighted ? <div className="mx_RightPanel_headerButton_highlight"></div> : <div/> }
</AccessibleButton>; </AccessibleButton>;
} }
} }
@ -69,6 +77,9 @@ HeaderButton.propTypes = {
badge: PropTypes.node, badge: PropTypes.node,
// The parameters to track the click event // The parameters to track the click event
analytics: PropTypes.arrayOf(PropTypes.string).isRequired, analytics: PropTypes.arrayOf(PropTypes.string).isRequired,
// Button title
title: PropTypes.string.isRequired,
}; };
module.exports = React.createClass({ module.exports = React.createClass({
@ -116,7 +127,7 @@ module.exports = React.createClass({
return { return {
phase: this.props.groupId ? this.Phase.GroupMemberList : this.Phase.RoomMemberList, phase: this.props.groupId ? this.Phase.GroupMemberList : this.Phase.RoomMemberList,
isUserPrivilegedInGroup: null, isUserPrivilegedInGroup: null,
} };
}, },
componentWillReceiveProps(newProps) { componentWillReceiveProps(newProps) {
@ -128,9 +139,7 @@ module.exports = React.createClass({
_initGroupStore(groupId) { _initGroupStore(groupId) {
if (!groupId) return; if (!groupId) return;
this._groupStore = GroupStoreCache.getGroupStore( this._groupStore = GroupStoreCache.getGroupStore(groupId);
this.context.matrixClient, groupId,
);
this._groupStore.registerListener(this.onGroupStoreUpdated); this._groupStore.registerListener(this.onGroupStoreUpdated);
}, },
@ -140,7 +149,7 @@ module.exports = React.createClass({
} }
}, },
onGroupStoreUpdated: function(){ onGroupStoreUpdated: function() {
this.setState({ this.setState({
isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(), isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(),
}); });
@ -264,7 +273,7 @@ module.exports = React.createClass({
const room = cli.getRoom(this.props.roomId); const room = cli.getRoom(this.props.roomId);
let userIsInRoom; let userIsInRoom;
if (room) { if (room) {
membersBadge = room.getJoinedMembers().length; membersBadge = formatCount(room.getJoinedMembers().length);
userIsInRoom = room.hasMembershipState( userIsInRoom = room.hasMembershipState(
this.context.matrixClient.credentials.userId, 'join', this.context.matrixClient.credentials.userId, 'join',
); );
@ -327,7 +336,7 @@ module.exports = React.createClass({
// button on these 2 screens or you won't be able to re-expand the panel. // button on these 2 screens or you won't be able to re-expand the panel.
headerButtons.push( headerButtons.push(
<div className="mx_RightPanel_headerButton mx_RightPanel_collapsebutton" key="_minimizeButton" <div className="mx_RightPanel_headerButton mx_RightPanel_collapsebutton" key="_minimizeButton"
title={ _t("Hide panel") } onClick={ this.onCollapseClick } title={ _t("Hide panel") } aria-label={ _t("Hide panel") } onClick={ this.onCollapseClick }
> >
<TintableSvg src="img/minimise.svg" width="10" height="16"/> <TintableSvg src="img/minimise.svg" width="10" height="16"/>
</div>, </div>,

View File

@ -30,7 +30,7 @@ var RoomNotifs = require('matrix-react-sdk/lib/RoomNotifs');
var FormattingUtils = require('matrix-react-sdk/lib/utils/FormattingUtils'); var FormattingUtils = require('matrix-react-sdk/lib/utils/FormattingUtils');
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton'); var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
import Modal from 'matrix-react-sdk/lib/Modal'; import Modal from 'matrix-react-sdk/lib/Modal';
import KeyCode from 'matrix-react-sdk/lib/KeyCode'; import { KeyCode } from 'matrix-react-sdk/lib/Keyboard';
// turn this on for drop & drag console debugging galore // turn this on for drop & drag console debugging galore
var debug = false; var debug = false;
@ -327,43 +327,46 @@ var RoomSubList = React.createClass({
}, },
calcManualOrderTagData: function(room) { calcManualOrderTagData: function(room) {
var index = this.state.sortedList.indexOf(room); const index = this.state.sortedList.indexOf(room);
// we sort rooms by the lexicographic ordering of the 'order' metadata on their tags. // we sort rooms by the lexicographic ordering of the 'order' metadata on their tags.
// for convenience, we calculate this for now a floating point number between 0.0 and 1.0. // for convenience, we calculate this for now a floating point number between 0.0 and 1.0.
var orderA = 0.0; // by default we're next to the beginning of the list let orderA = 0.0; // by default we're next to the beginning of the list
if (index > 0) { if (index > 0) {
var prevTag = this.state.sortedList[index - 1].tags[this.props.tagName]; const prevTag = this.state.sortedList[index - 1].tags[this.props.tagName];
if (!prevTag) { if (!prevTag) {
console.error("Previous room in sublist is not tagged to be in this list. This should never happen.") console.error("Previous room in sublist is not tagged to be in this list. This should never happen.");
} } else if (prevTag.order === undefined) {
else if (prevTag.order === undefined) {
console.error("Previous room in sublist has no ordering metadata. This should never happen."); console.error("Previous room in sublist has no ordering metadata. This should never happen.");
} } else {
else {
orderA = prevTag.order; orderA = prevTag.order;
} }
} }
var orderB = 1.0; // by default we're next to the end of the list too let orderB = 1.0; // by default we're next to the end of the list too
if (index < this.state.sortedList.length - 1) { if (index < this.state.sortedList.length - 1) {
var nextTag = this.state.sortedList[index + 1].tags[this.props.tagName]; const nextTag = this.state.sortedList[index + 1].tags[this.props.tagName];
if (!nextTag) { if (!nextTag) {
console.error("Next room in sublist is not tagged to be in this list. This should never happen.") console.error("Next room in sublist is not tagged to be in this list. This should never happen.");
} } else if (nextTag.order === undefined) {
else if (nextTag.order === undefined) {
console.error("Next room in sublist has no ordering metadata. This should never happen."); console.error("Next room in sublist has no ordering metadata. This should never happen.");
} } else {
else {
orderB = nextTag.order; orderB = nextTag.order;
} }
} }
var order = (orderA + orderB) / 2.0; const order = (orderA + orderB) / 2.0;
if (order === orderA || order === orderB) { if (order === orderA || order === orderB) {
console.error("Cannot describe new list position. This should be incredibly unlikely."); console.error("Cannot describe new list position. This should be incredibly unlikely.");
// TODO: renumber the list this.state.sortedList.forEach((room, index) => {
MatrixClientPeg.get().setRoomTag(
room.roomId, this.props.tagName,
{order: index / this.state.sortedList.length},
);
});
return index / this.state.sortedList.length;
} }
return order; return order;

View File

@ -18,7 +18,7 @@ limitations under the License.
import React from 'react'; import React from 'react';
import { _t } from 'matrix-react-sdk/lib/languageHandler'; import { _t } from 'matrix-react-sdk/lib/languageHandler';
import KeyCode from 'matrix-react-sdk/lib/KeyCode'; import { KeyCode } from 'matrix-react-sdk/lib/Keyboard';
import sdk from 'matrix-react-sdk'; import sdk from 'matrix-react-sdk';
import dis from 'matrix-react-sdk/lib/dispatcher'; import dis from 'matrix-react-sdk/lib/dispatcher';
import rate_limited_func from 'matrix-react-sdk/lib/ratelimitedfunc'; import rate_limited_func from 'matrix-react-sdk/lib/ratelimitedfunc';

View File

@ -24,7 +24,7 @@ const sdk = require('matrix-react-sdk');
import { _t } from 'matrix-react-sdk/lib/languageHandler'; import { _t } from 'matrix-react-sdk/lib/languageHandler';
const Modal = require('matrix-react-sdk/lib/Modal'); const Modal = require('matrix-react-sdk/lib/Modal');
const Resend = require("matrix-react-sdk/lib/Resend"); const Resend = require("matrix-react-sdk/lib/Resend");
import * as UserSettingsStore from 'matrix-react-sdk/lib/UserSettingsStore'; import SettingsStore from "matrix-react-sdk/lib/settings/SettingsStore";
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'MessageContextMenu', displayName: 'MessageContextMenu',
@ -67,7 +67,7 @@ module.exports = React.createClass({
let canPin = room.currentState.mayClientSendStateEvent('m.room.pinned_events', cli); let canPin = room.currentState.mayClientSendStateEvent('m.room.pinned_events', cli);
// HACK: Intentionally say we can't pin if the user doesn't want to use the functionality // HACK: Intentionally say we can't pin if the user doesn't want to use the functionality
if (!UserSettingsStore.isFeatureEnabled("feature_pinning")) canPin = false; if (!SettingsStore.isFeatureEnabled("feature_pinning")) canPin = false;
this.setState({canRedact, canPin}); this.setState({canRedact, canPin});
}, },

View File

@ -0,0 +1,101 @@
/*
Copyright 2017 Travis Ralston
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.
*/
import React from 'react';
import { _t, _td } from 'matrix-react-sdk/lib/languageHandler';
import sdk from 'matrix-react-sdk';
const STATUS_LABELS = {
"online": _td("Online"),
"unavailable": _td("Away"),
"offline": _td("Appear Offline"),
};
const PresenceContextMenuOption = React.createClass({
displayName: 'PresenceContextMenuOption',
propTypes: {
forStatus: React.PropTypes.string.isRequired,
isCurrent: React.PropTypes.bool,
onChange: React.PropTypes.func.isRequired,
},
onClick: function() {
if (this.isCurrent) return;
this.props.onChange(this.props.forStatus);
},
render: function() {
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
const indicatorClasses = "mx_PresenceContextMenuOption_indicator "
+ "mx_PresenceContextMenuOption_indicator_" + this.props.forStatus;
let classNames = "mx_PresenceContextMenuOption";
if (this.props.isCurrent) classNames += " mx_PresenceContextMenuOption_current";
return (
<AccessibleButton className={classNames} element="div" onClick={this.onClick}>
<div className={indicatorClasses}></div>
{ _t(STATUS_LABELS[this.props.forStatus]) }
</AccessibleButton>
);
},
});
module.exports = React.createClass({
displayName: 'PresenceContextMenu',
propTypes: {
// "online", "unavailable", or "offline"
currentStatus: React.PropTypes.string.isRequired,
// Called when the user wants to change their status.
// Args: (newStatus:string)
onChange: React.PropTypes.func.isRequired,
// callback called when the menu is dismissed
onFinished: React.PropTypes.func,
},
getInitialState() {
return {
currentStatus: this.props.currentStatus,
};
},
onChange: function(newStatus) {
this.props.onChange(newStatus);
this.setState({currentStatus: newStatus});
},
render: function() {
const statusElements = [];
for (let status of Object.keys(STATUS_LABELS)) {
statusElements.push((
<PresenceContextMenuOption forStatus={status} key={status}
onChange={this.onChange}
isCurrent={status === this.state.currentStatus} />
));
}
return (
<div>
{ statusElements }
</div>
);
},
});

View File

@ -60,7 +60,7 @@ class GenericEditor extends DevtoolsComponent {
<label htmlFor={id}>{ label }</label> <label htmlFor={id}>{ label }</label>
</div> </div>
<div className="mx_DevTools_inputCell"> <div className="mx_DevTools_inputCell">
<input id={id} onChange={this._onChange} value={this.state[id]} size="32" /> <input id={id} className="mx_TextInputDialog_input" onChange={this._onChange} value={this.state[id]} size="32" />
</div> </div>
</div>; </div>;
} }

View File

@ -42,7 +42,7 @@ export default React.createClass({
const QuestionDialog = sdk.getComponent('dialogs.QuestionDialog'); const QuestionDialog = sdk.getComponent('dialogs.QuestionDialog');
Modal.createTrackedDialog('Display release notes', '', QuestionDialog, { Modal.createTrackedDialog('Display release notes', '', QuestionDialog, {
title: _t("What's New"), title: _t("What's New"),
description: <pre className="changelog_text">{releaseNotes}</pre>, description: <div className="mx_MatrixToolbar_changelog">{releaseNotes}</div>,
button: _t("Update"), button: _t("Update"),
onFinished: (update) => { onFinished: (update) => {
if(update && PlatformPeg.get()) { if(update && PlatformPeg.get()) {

View File

@ -20,7 +20,7 @@ import React from 'react';
import sdk from 'matrix-react-sdk'; import sdk from 'matrix-react-sdk';
import Modal from 'matrix-react-sdk/lib/Modal'; import Modal from 'matrix-react-sdk/lib/Modal';
import dis from 'matrix-react-sdk/lib/dispatcher'; import dis from 'matrix-react-sdk/lib/dispatcher';
import { _t, _tJsx } from 'matrix-react-sdk/lib/languageHandler'; import { _t } from 'matrix-react-sdk/lib/languageHandler';
export default React.createClass({ export default React.createClass({
onUpdateClicked: function() { onUpdateClicked: function() {
@ -49,10 +49,10 @@ export default React.createClass({
alt="Warning" alt="Warning"
/> />
<div className="mx_MatrixToolbar_content"> <div className="mx_MatrixToolbar_content">
{ _tJsx( { _t(
"To return to your account in future you need to <u>set a password</u>", "To return to your account in future you need to <u>set a password</u>",
/<u>(.*?)<\/u>/, {},
(sub) => { return <u>{ sub }</u>; }, { 'u': (sub) => <u>{ sub }</u> },
) } ) }
</div> </div>
<button className="mx_MatrixToolbar_action"> <button className="mx_MatrixToolbar_action">

View File

@ -18,6 +18,7 @@ limitations under the License.
var React = require('react'); var React = require('react');
import { _t } from 'matrix-react-sdk/lib/languageHandler'; import { _t } from 'matrix-react-sdk/lib/languageHandler';
import SettingsStore from 'matrix-react-sdk/lib/settings/SettingsStore';
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'VectorLoginFooter', displayName: 'VectorLoginFooter',
@ -26,6 +27,9 @@ module.exports = React.createClass({
}, },
render: function() { render: function() {
// FIXME: replace this with a proper Status skin
if (SettingsStore.getValue("theme") === 'status') return <div/>;
return ( return (
<div className="mx_Login_links"> <div className="mx_Login_links">
<a href="https://medium.com/@RiotChat">blog</a>&nbsp;&nbsp;&middot;&nbsp;&nbsp; <a href="https://medium.com/@RiotChat">blog</a>&nbsp;&nbsp;&middot;&nbsp;&nbsp;

View File

@ -33,9 +33,11 @@ module.exports = React.createClass({
render: function() { render: function() {
return ( return (
<div className="mx_Login_header">
<div className="mx_Login_logo"> <div className="mx_Login_logo">
<img src={this.props.icon || DEFAULT_LOGO_URI} alt="Riot"/> <img src={this.props.icon || DEFAULT_LOGO_URI} alt="Riot"/>
</div> </div>
</div>
); );
} }
}); });

View File

@ -17,9 +17,10 @@ limitations under the License.
import React from 'react'; import React from 'react';
import Promise from 'bluebird'; import Promise from 'bluebird';
import sdk from 'matrix-react-sdk'; import sdk from 'matrix-react-sdk';
import { _t, _tJsx } from 'matrix-react-sdk/lib/languageHandler'; import { _t } from 'matrix-react-sdk/lib/languageHandler';
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg'; import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
import UserSettingsStore from 'matrix-react-sdk/lib/UserSettingsStore'; import UserSettingsStore from 'matrix-react-sdk/lib/UserSettingsStore';
import SettingsStore, {SettingLevel} from "matrix-react-sdk/lib/settings/SettingsStore";
import Modal from 'matrix-react-sdk/lib/Modal'; import Modal from 'matrix-react-sdk/lib/Modal';
import { import {
NotificationUtils, NotificationUtils,
@ -112,12 +113,33 @@ module.exports = React.createClass({
}, },
onEnableDesktopNotificationsChange: function(event) { onEnableDesktopNotificationsChange: function(event) {
UserSettingsStore.setEnableNotifications(event.target.checked); SettingsStore.setValue(
"notificationsEnabled", null,
SettingLevel.DEVICE,
event.target.checked,
).finally(() => {
this.forceUpdate();
});
}, },
onEnableDesktopNotificationBodyChange: function(event) { onEnableDesktopNotificationBodyChange: function(event) {
UserSettingsStore.setEnableNotificationBody(event.target.checked); SettingsStore.setValue(
"notificationBodyEnabled", null,
SettingLevel.DEVICE,
event.target.checked,
).finally(() => {
this.forceUpdate(); this.forceUpdate();
});
},
onEnableAudioNotificationsChange: function(event) {
SettingsStore.setValue(
"audioNotificationsEnabled", null,
SettingLevel.DEVICE,
event.target.checked,
).finally(() => {
this.forceUpdate();
});
}, },
onEnableEmailNotificationsChange: function(address, event) { onEnableEmailNotificationsChange: function(address, event) {
@ -542,10 +564,11 @@ module.exports = React.createClass({
"vectorRuleId": "_keywords", "vectorRuleId": "_keywords",
"description" : ( "description" : (
<span> <span>
{ _tJsx('Messages containing <span>keywords</span>', { _t('Messages containing <span>keywords</span>',
/<span>(.*?)<\/span>/, {},
(sub) => { 'span': (sub) =>
<span className="mx_UserNotifSettings_keywords" onClick={ self.onKeywordsClicked }>{sub}</span> <span className="mx_UserNotifSettings_keywords" onClick={ self.onKeywordsClicked }>{sub}</span>
},
)} )}
</span> </span>
), ),
@ -824,7 +847,7 @@ module.exports = React.createClass({
<input id="enableDesktopNotifications" <input id="enableDesktopNotifications"
ref="enableDesktopNotifications" ref="enableDesktopNotifications"
type="checkbox" type="checkbox"
checked={ UserSettingsStore.getEnableNotifications() } checked={ SettingsStore.getValue("notificationsEnabled") }
onChange={ this.onEnableDesktopNotificationsChange } /> onChange={ this.onEnableDesktopNotificationsChange } />
</div> </div>
<div className="mx_UserNotifSettings_labelCell"> <div className="mx_UserNotifSettings_labelCell">
@ -839,7 +862,7 @@ module.exports = React.createClass({
<input id="enableDesktopNotificationBody" <input id="enableDesktopNotificationBody"
ref="enableDesktopNotificationBody" ref="enableDesktopNotificationBody"
type="checkbox" type="checkbox"
checked={ UserSettingsStore.getEnableNotificationBody() } checked={ SettingsStore.getValue("notificationBodyEnabled") }
onChange={ this.onEnableDesktopNotificationBodyChange } /> onChange={ this.onEnableDesktopNotificationBodyChange } />
</div> </div>
<div className="mx_UserNotifSettings_labelCell"> <div className="mx_UserNotifSettings_labelCell">
@ -854,11 +877,8 @@ module.exports = React.createClass({
<input id="enableDesktopAudioNotifications" <input id="enableDesktopAudioNotifications"
ref="enableDesktopAudioNotifications" ref="enableDesktopAudioNotifications"
type="checkbox" type="checkbox"
checked={ UserSettingsStore.getEnableAudioNotifications() } checked={ SettingsStore.getValue("audioNotificationsEnabled") }
onChange={ (e) => { onChange={ this.onEnableAudioNotificationsChange } />
UserSettingsStore.setEnableAudioNotifications(e.target.checked);
this.forceUpdate();
}} />
</div> </div>
<div className="mx_UserNotifSettings_labelCell"> <div className="mx_UserNotifSettings_labelCell">
<label htmlFor="enableDesktopAudioNotifications"> <label htmlFor="enableDesktopAudioNotifications">

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@ -68,9 +68,10 @@
"What's New": "What's New", "What's New": "What's New",
"Update": "Update", "Update": "Update",
"What's new?": "What's new?", "What's new?": "What's new?",
"Appear Offline": "Appear Offline",
"Away": "Away",
"A new version of Riot is available.": "A new version of Riot is available.", "A new version of Riot is available.": "A new version of Riot is available.",
"To return to your account in future you need to <u>set a password</u>": "To return to your account in future you need to <u>set a password</u>", "To return to your account in future you need to <u>set a password</u>": "To return to your account in future you need to <u>set a password</u>",
"Toolbox": "Toolbox",
"Set Password": "Set Password", "Set Password": "Set Password",
"Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).", "Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).",
"Checking for an update...": "Checking for an update...", "Checking for an update...": "Checking for an update...",
@ -98,18 +99,19 @@
"Unavailable": "Unavailable", "Unavailable": "Unavailable",
"Changelog": "Changelog", "Changelog": "Changelog",
"Back": "Back", "Back": "Back",
"Send Custom Event": "Send Custom Event",
"You must specify an event type!": "You must specify an event type!", "You must specify an event type!": "You must specify an event type!",
"Event sent!": "Event sent!", "Event sent!": "Event sent!",
"Failed to send custom event.": "Failed to send custom event.", "Failed to send custom event.": "Failed to send custom event.",
"Event Type": "Event Type", "Event Type": "Event Type",
"Event Content": "Event Content",
"State Key": "State Key", "State Key": "State Key",
"Edit": "Edit", "Event Content": "Event Content",
"Filter results": "Filter results",
"Send Custom Event": "Send Custom Event",
"Send Account Data": "Send Account Data", "Send Account Data": "Send Account Data",
"Explore Account Data": "Explore Account Data", "Filter results": "Filter results",
"Explore Room State": "Explore Room State", "Explore Room State": "Explore Room State",
"Edit": "Edit",
"Explore Account Data": "Explore Account Data",
"Toolbox": "Toolbox",
"Developer Tools": "Developer Tools", "Developer Tools": "Developer Tools",
"You have successfully set a password!": "You have successfully set a password!", "You have successfully set a password!": "You have successfully set a password!",
"You have successfully set a password and an email address!": "You have successfully set a password and an email address!", "You have successfully set a password and an email address!": "You have successfully set a password and an email address!",
@ -147,8 +149,8 @@
"Direct Chat": "Direct Chat", "Direct Chat": "Direct Chat",
"Sorry, your browser is <b>not</b> able to run Riot.": "Sorry, your browser is <b>not</b> able to run Riot.", "Sorry, your browser is <b>not</b> able to run Riot.": "Sorry, your browser is <b>not</b> able to run Riot.",
"Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.", "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.",
"Please install <a href=\"https://www.google.com/chrome\">Chrome</a> or <a href=\"https://getfirefox.com\">Firefox</a> for the best experience.": "Please install <a href=\"https://www.google.com/chrome\">Chrome</a> or <a href=\"https://getfirefox.com\">Firefox</a> for the best experience.", "Please install <chromeLink>Chrome</chromeLink> or <firefoxLink>Firefox</firefoxLink> for the best experience.": "Please install <chromeLink>Chrome</chromeLink> or <firefoxLink>Firefox</firefoxLink> for the best experience.",
"<a href=\"http://apple.com/safari\">Safari</a> and <a href=\"http://opera.com\">Opera</a> work too.": "<a href=\"http://apple.com/safari\">Safari</a> and <a href=\"http://opera.com\">Opera</a> work too.", "<safariLink>Safari</safariLink> and <operaLink>Opera</operaLink> work too.": "<safariLink>Safari</safariLink> and <operaLink>Opera</operaLink> work too.",
"With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!",
"I understand the risks and wish to continue": "I understand the risks and wish to continue", "I understand the risks and wish to continue": "I understand the risks and wish to continue",
"Couldn't load home page": "Couldn't load home page", "Couldn't load home page": "Couldn't load home page",

View File

@ -1,6 +1,7 @@
/* /*
Copyright 2015, 2016 OpenMarket Ltd Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd Copyright 2017 Vector Creations Ltd
Copyright 2017 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -23,12 +24,7 @@ html {
} }
body { body {
/* Open Sans lacks combining diacritics, so these will fall through font-family: $font-family;
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; font-size: 15px;
background-color: $primary-bg-color; background-color: $primary-bg-color;
color: $primary-fg-color; color: $primary-fg-color;
@ -73,7 +69,7 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
/* Required by Firefox */ /* Required by Firefox */
textarea { textarea {
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif; font-family: $font-family;
} }
/* Prevent ugly dotted highlight around selected elements in Firefox */ /* Prevent ugly dotted highlight around selected elements in Firefox */
@ -123,6 +119,23 @@ textarea {
transition: height 120ms ease-out ! important; transition: height 120ms ease-out ! important;
} }
// These are magic constants which are excluded from tinting, to let themes
// (which only have CSS, unlike skins) tell the app what their non-tinted
// colourscheme is by inspecting the stylesheet DOM.
//
// They are not used for layout!!
#mx_theme_accentColor {
color: $accent-color;
}
#mx_theme_secondaryAccentColor {
color: $secondary-accent-color;
}
#mx_theme_tertiaryAccentColor {
color: $roomsublist-label-bg-color;
}
.mx_Dialog_wrapper { .mx_Dialog_wrapper {
position: fixed; position: fixed;
z-index: 4000; z-index: 4000;
@ -210,24 +223,19 @@ textarea {
} }
.mx_Dialog button, .mx_Dialog input[type="submit"] { .mx_Dialog button, .mx_Dialog input[type="submit"] {
border: 0px; @mixin mx_DialogButton;
height: 36px;
border-radius: 40px;
border: solid 1px $accent-color;
font-weight: 600;
font-size: 14px;
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
margin-left: 0px; margin-left: 0px;
margin-right: 8px; margin-right: 8px;
padding-left: 1.5em;
padding-right: 1.5em;
outline: none;
cursor: pointer;
color: $accent-color;
background-color: $primary-bg-color;
/* align images in buttons (eg spinners) */ // flip colours for the secondary ones
vertical-align: middle; font-weight: 600;
border: 1px solid $accent-color ! important;
color: $accent-color;
background-color: $accent-fg-color;
}
.mx_Dialog button:hover, .mx_Dialog input[type="submit"]:hover {
@mixin mx_DialogButton_hover;
} }
.mx_Dialog button:focus, .mx_Dialog input[type="submit"]:focus { .mx_Dialog button:focus, .mx_Dialog input[type="submit"]:focus {
@ -292,26 +300,18 @@ textarea {
color: $selection-fg-color; color: $selection-fg-color;
} }
/** green button with rounded corners */
.mx_textButton { .mx_textButton {
color: $accent-fg-color; @mixin mx_DialogButton_small;
background-color: $accent-color; }
border-radius: 17px;
text-align: center; .mx_textButton:hover {
padding-left: 1em; @mixin mx_DialogButton_hover;
padding-right: 1em;
cursor: pointer;
display: inline;
} }
.mx_button_row { .mx_button_row {
margin-top: 69px; margin-top: 69px;
} }
.changelog_text {
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
}
.mx_Beta { .mx_Beta {
color: red; color: red;
margin-right: 10px; margin-right: 10px;
@ -332,3 +332,30 @@ textarea {
border: 1px solid gray; border: 1px solid gray;
background-color: darkred; background-color: darkred;
} }
.mx_TintableSvgButton {
position: relative;
display: flex;
flex-direction: row;
justify-content: center;
align-content: center;
}
.mx_TintableSvgButton object {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
}
.mx_TintableSvgButton span {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
opacity: 0;
cursor: pointer;
}

View File

@ -11,10 +11,12 @@
@import "./matrix-react-sdk/structures/_RoomStatusBar.scss"; @import "./matrix-react-sdk/structures/_RoomStatusBar.scss";
@import "./matrix-react-sdk/structures/_RoomView.scss"; @import "./matrix-react-sdk/structures/_RoomView.scss";
@import "./matrix-react-sdk/structures/_SearchBox.scss"; @import "./matrix-react-sdk/structures/_SearchBox.scss";
@import "./matrix-react-sdk/structures/_TagPanel.scss";
@import "./matrix-react-sdk/structures/_UploadBar.scss"; @import "./matrix-react-sdk/structures/_UploadBar.scss";
@import "./matrix-react-sdk/structures/_UserSettings.scss"; @import "./matrix-react-sdk/structures/_UserSettings.scss";
@import "./matrix-react-sdk/structures/login/_Login.scss"; @import "./matrix-react-sdk/structures/login/_Login.scss";
@import "./matrix-react-sdk/views/avatars/_BaseAvatar.scss"; @import "./matrix-react-sdk/views/avatars/_BaseAvatar.scss";
@import "./matrix-react-sdk/views/avatars/_MemberPresenceAvatar.scss";
@import "./matrix-react-sdk/views/dialogs/_BugReportDialog.scss"; @import "./matrix-react-sdk/views/dialogs/_BugReportDialog.scss";
@import "./matrix-react-sdk/views/dialogs/_ChatCreateOrReuseChatDialog.scss"; @import "./matrix-react-sdk/views/dialogs/_ChatCreateOrReuseChatDialog.scss";
@import "./matrix-react-sdk/views/dialogs/_ChatInviteDialog.scss"; @import "./matrix-react-sdk/views/dialogs/_ChatInviteDialog.scss";
@ -37,7 +39,9 @@
@import "./matrix-react-sdk/views/elements/_RichText.scss"; @import "./matrix-react-sdk/views/elements/_RichText.scss";
@import "./matrix-react-sdk/views/elements/_RoleButton.scss"; @import "./matrix-react-sdk/views/elements/_RoleButton.scss";
@import "./matrix-react-sdk/views/elements/_ToolTipButton.scss"; @import "./matrix-react-sdk/views/elements/_ToolTipButton.scss";
@import "./matrix-react-sdk/views/groups/_GroupPublicityToggle.scss";
@import "./matrix-react-sdk/views/groups/_GroupRoomList.scss"; @import "./matrix-react-sdk/views/groups/_GroupRoomList.scss";
@import "./matrix-react-sdk/views/groups/_GroupUserSettings.scss";
@import "./matrix-react-sdk/views/login/_InteractiveAuthEntryComponents.scss"; @import "./matrix-react-sdk/views/login/_InteractiveAuthEntryComponents.scss";
@import "./matrix-react-sdk/views/login/_ServerConfig.scss"; @import "./matrix-react-sdk/views/login/_ServerConfig.scss";
@import "./matrix-react-sdk/views/messages/_MEmoteBody.scss"; @import "./matrix-react-sdk/views/messages/_MEmoteBody.scss";
@ -80,6 +84,7 @@
@import "./vector-web/structures/_RoomSubList.scss"; @import "./vector-web/structures/_RoomSubList.scss";
@import "./vector-web/structures/_ViewSource.scss"; @import "./vector-web/structures/_ViewSource.scss";
@import "./vector-web/views/context_menus/_MessageContextMenu.scss"; @import "./vector-web/views/context_menus/_MessageContextMenu.scss";
@import "./vector-web/views/context_menus/_PresenceContextMenuOption.scss";
@import "./vector-web/views/context_menus/_RoomTileContextMenu.scss"; @import "./vector-web/views/context_menus/_RoomTileContextMenu.scss";
@import "./vector-web/views/dialogs/_ChangelogDialog.scss"; @import "./vector-web/views/dialogs/_ChangelogDialog.scss";
@import "./vector-web/views/dialogs/_DevtoolsDialog.scss"; @import "./vector-web/views/dialogs/_DevtoolsDialog.scss";

View File

@ -94,6 +94,60 @@ limitations under the License.
left: 1px; left: 1px;
} }
.mx_ContextualMenu.mx_ContextualMenu_top {
top: 8px;
}
.mx_ContextualMenu_chevron_top {
position: absolute;
left: 0px;
top: -8px;
width: 0;
height: 0;
border-left: 8px solid transparent;
border-bottom: 8px solid $menu-border-color;
border-right: 8px solid transparent;
}
.mx_ContextualMenu_chevron_top:after{
content:'';
width: 0;
height: 0;
border-left: 7px solid transparent;
border-bottom: 7px solid $menu-bg-color;
border-right: 7px solid transparent;
position:absolute;
left: -7px;
top: 1px;
}
.mx_ContextualMenu.mx_ContextualMenu_bottom {
bottom: 8px;
}
.mx_ContextualMenu_chevron_bottom {
position: absolute;
left: 0px;
bottom: -8px;
width: 0;
height: 0;
border-left: 8px solid transparent;
border-top: 8px solid $menu-border-color;
border-right: 8px solid transparent;
}
.mx_ContextualMenu_chevron_bottom:after{
content:'';
width: 0;
height: 0;
border-left: 7px solid transparent;
border-top: 7px solid $menu-bg-color;
border-right: 7px solid transparent;
position:absolute;
left: -7px;
bottom: 1px;
}
.mx_ContextualMenu_field { .mx_ContextualMenu_field {
padding: 3px 6px 3px 6px; padding: 3px 6px 3px 6px;
cursor: pointer; cursor: pointer;

View File

@ -122,13 +122,13 @@ limitations under the License.
justify-content: center; justify-content: center;
} }
.mx_GroupTile_profile h3.mx_GroupTile_name, .mx_GroupTile_profile .mx_GroupTile_name,
.mx_GroupTile_profile .mx_GroupTile_groupId, .mx_GroupTile_profile .mx_GroupTile_groupId,
.mx_GroupTile_profile .mx_GroupTile_desc { .mx_GroupTile_profile .mx_GroupTile_desc {
padding-right: 10px; padding-right: 10px;
} }
.mx_GroupTile_profile h3.mx_GroupTile_name { .mx_GroupTile_profile .mx_GroupTile_name {
margin: 0px; margin: 0px;
font-size: 15px; font-size: 15px;
} }

View File

@ -21,6 +21,8 @@ limitations under the License.
padding-top: 24px; padding-top: 24px;
padding-bottom: 22px; padding-bottom: 22px;
border-bottom: 1px solid $panel-divider-color;
display: flex; display: flex;
} }
@ -38,7 +40,7 @@ limitations under the License.
.mx_SearchBox_search { .mx_SearchBox_search {
flex: 1 1 auto; flex: 1 1 auto;
width: 0px; width: 0px;
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif; font-family: $font-family;
font-size: 12px; font-size: 12px;
margin-top: -2px; margin-top: -2px;
height: 24px; height: 24px;

View File

@ -0,0 +1,77 @@
/*
Copyright 2017 New Vector 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.
*/
.mx_TagPanel {
width: 60px;
background-color: $tertiary-accent-color;
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
.mx_TagPanel .mx_TagPanel_tagTileContainer {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 65px;
}
.mx_TagPanel .mx_TagTile {
margin: 6px 0px;
opacity: 0.5;
}
.mx_TagPanel .mx_TagTile:focus,
.mx_TagPanel .mx_TagTile:hover,
.mx_TagPanel .mx_TagTile.mx_TagTile_selected {
opacity: 1;
}
.mx_TagPanel .mx_TagTile.mx_TagTile_selected {
/* To offset border of mx_TagTile_avatar */
margin: 3px 0px;
}
.mx_TagPanel .mx_TagTile.mx_TagTile_selected .mx_TagTile_avatar {
border: 3px solid $accent-color;
border-radius: 60px;
}
.mx_TagPanel .mx_TagTile.mx_AccessibleButton:focus {
filter: none;
}
.mx_TagTile_tooltip {
position: relative;
top: -30px;
left: 5px;
}
.mx_TagPanel_createGroupButton {
opacity: 0.5;
margin-bottom: 17px;
height: 25px;
}
.mx_TagPanel_createGroupButton:hover {
opacity: 1;
}
.mx_TagPanel_createGroupButton object {
pointer-events: none;
}

View File

@ -64,30 +64,13 @@ limitations under the License.
} }
.mx_UserSettings_button { .mx_UserSettings_button {
@mixin mx_DialogButton;
display: inline; display: inline;
vertical-align: middle;
border: 0px;
border-radius: 36px;
font-weight: 400;
font-size: 16px;
color: $accent-fg-color;
background-color: $accent-color;
width: auto;
margin: auto; margin: auto;
padding: 7px;
padding-left: 1.5em;
padding-right: 1.5em;
cursor: pointer;
} }
.mx_UserSettings_button.mx_UserSettings_buttonSmall { .mx_UserSettings_button:hover {
height: 36px; @mixin mx_DialogButton_hover;
padding: 4px;
padding-left: 7px;
padding-right: 7px;
font-size: 12px;
margin-right: 5px;
line-height: 12px;
} }
.mx_UserSettings_button.danger { .mx_UserSettings_button.danger {

View File

@ -26,7 +26,6 @@ limitations under the License.
} }
.mx_Login h2 { .mx_Login h2 {
color: $primary-fg-color;
font-weight: 300; font-weight: 300;
margin-top: 32px; margin-top: 32px;
margin-bottom: 20px; margin-bottom: 20px;
@ -80,15 +79,14 @@ limitations under the License.
} }
.mx_Login_submit { .mx_Login_submit {
@mixin mx_DialogButton;
width: 100%;
margin-top: 35px; margin-top: 35px;
margin-bottom: 24px; margin-bottom: 24px;
width: 100%; }
border-radius: 40px;
height: 40px; .mx_Login_submit:hover {
border: 0px; @mixin mx_DialogButton_hover;
background-color: $accent-color;
font-size: 15px;
color: $accent-fg-color;
} }
.mx_Login_submit:disabled { .mx_Login_submit:disabled {
@ -137,8 +135,7 @@ limitations under the License.
} }
.mx_Login_forgot { .mx_Login_forgot {
font-size: 13px; font-size: 15px;
opacity: 0.8;
} }
.mx_Login_forgot:link { .mx_Login_forgot:link {
@ -224,7 +221,6 @@ limitations under the License.
height: 16px; height: 16px;
flex-shrink: 1; flex-shrink: 1;
min-width: 0px; min-width: 0px;
border-radius: 3px;
} }
.mx_Login_phoneNumberField { .mx_Login_phoneNumberField {

View File

@ -31,5 +31,5 @@ limitations under the License.
.mx_BaseAvatar_image { .mx_BaseAvatar_image {
border-radius: 40px; border-radius: 40px;
vertical-align: top; vertical-align: top;
background-color: #fff; background-color: $avatar-bg-color;
} }

View File

@ -0,0 +1,43 @@
/*
Copyright 2017 Travis Ralston
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.
*/
.mx_MemberPresenceAvatar {
display: inline-block;
position: relative;
}
.mx_MemberPresenceAvatar_status {
display: block;
width: 10px;
height: 10px;
border-radius: 10px;
position: absolute;
bottom: -2px;
right: -3px;
}
.mx_MemberPresenceAvatar_status_online {
background-color: $presence-online;
}
.mx_MemberPresenceAvatar_status_unavailable {
background-color: $presence-unavailable;
}
.mx_MemberPresenceAvatar_status_offline {
background-color: $presence-offline;
}

View File

@ -28,7 +28,7 @@ limitations under the License.
{ {
height: 26px; height: 26px;
font-size: 14px; font-size: 14px;
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif; font-family: $font-family;
padding-left: 12px; padding-left: 12px;
padding-right: 12px; padding-right: 12px;
margin: 0 !important; margin: 0 !important;

View File

@ -34,7 +34,7 @@ limitations under the License.
} }
.mx_ConfirmUserActionDialog_reasonField { .mx_ConfirmUserActionDialog_reasonField {
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif; font-family: $font-family;
font-size: 14px; font-size: 14px;
color: $primary-fg-color; color: $primary-fg-color;
background-color: $primary-bg-color; background-color: $primary-bg-color;

View File

@ -21,19 +21,7 @@ limitations under the License.
} }
.mx_EncryptedEventDialog .mx_MemberDeviceInfo_textButton { .mx_EncryptedEventDialog .mx_MemberDeviceInfo_textButton {
border: 0px; @mixin mx_DialogButton;
height: 36px;
border-radius: 40px;
border: solid 1px $accent-color;
font-weight: 600;
font-size: 14px;
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
margin-left: 0px;
margin-right: 8px;
padding-left: 1.5em;
padding-right: 1.5em;
outline: none;
cursor: pointer;
color: $accent-color;
background-color: $primary-bg-color; background-color: $primary-bg-color;
color: $accent-color;
} }

View File

@ -43,22 +43,9 @@ limitations under the License.
} }
.mx_UnknownDeviceDialog .mx_MemberDeviceInfo_textButton { .mx_UnknownDeviceDialog .mx_MemberDeviceInfo_textButton {
border: 0px; @mixin mx_DialogButton_small;
height: 24px;
border-radius: 40px;
border: solid 1px $accent-color;
font-weight: 600;
font-size: 13px;
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
margin-left: 0px;
margin-right: 8px;
padding-left: 0.5em;
padding-right: 0.5em;
width: 85px;
outline: none;
cursor: pointer;
color: $accent-color;
background-color: $primary-bg-color; background-color: $primary-bg-color;
color: $accent-color;
} }
.mx_UnknownDeviceDialog .mx_UnknownDeviceDialog_deviceList li { .mx_UnknownDeviceDialog .mx_UnknownDeviceDialog_deviceList li {

View File

@ -0,0 +1,42 @@
/*
Copyright 2017 New Vector 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.
*/
.mx_GroupPublicity_toggle {
display: flex;
align-items: center;
margin: 8px;
}
.mx_GroupPublicity_toggle > label {
display: flex;
align-items: flex-start;
}
.mx_GroupPublicity_toggle > label,
.mx_GroupPublicity_toggle .mx_GroupTile {
width: 50%;
}
.mx_GroupPublicity_toggle input {
margin-right: 8px;
vertical-align: -4px;
}
.mx_GroupPublicity_toggle .mx_GroupTile {
display: flex;
align-items: flex-start;
cursor: pointer;
}

View File

@ -0,0 +1,23 @@
/*
Copyright 2017 New Vector 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.
*/
.mx_GroupUserSettings_groupPublicity_scrollbox {
height: 200px;
border: 1px solid $primary-hairline-color;
border-radius: 3px;
margin-right: 32px;
overflow: hidden;
}

View File

@ -14,8 +14,9 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// .mx_AppsDrawer { .mx_AppsDrawer {
// } margin: 5px;
}
.mx_AppsContainer { .mx_AppsContainer {
display: flex; display: flex;
@ -75,17 +76,32 @@ limitations under the License.
} }
.mx_AppTileMenuBar { .mx_AppTileMenuBar {
// height: 15px;
margin: 0; margin: 0;
padding: 2px 10px; padding: 2px 10px;
// background-color: $e2e-verified-color;
border-bottom: 1px solid $primary-hairline-color; border-bottom: 1px solid $primary-hairline-color;
font-size: 10px; font-size: 10px;
background-color: $widget-menu-bar-bg-color;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
cursor: pointer;
}
.mx_AppTileMenuBarTitle {
display: flex;
flex-direction: row;
align-items: center;
pointer-events: none;
} }
.mx_AppTileMenuBarWidgets { .mx_AppTileMenuBarWidgets {
float: right; float: right;
display: flex;
flex-direction: row;
align-items: center;
} }
.mx_AppTileMenuBarWidget { .mx_AppTileMenuBarWidget {
// pointer-events: none; // pointer-events: none;
cursor: pointer; cursor: pointer;
@ -101,7 +117,7 @@ limitations under the License.
} }
.mx_AppTileMenuBarWidget:hover { .mx_AppTileMenuBarWidget:hover {
border: 1px solid $primary-hairline-color; border: 1px solid $primary-fg-color;
border-radius: 2px; border-radius: 2px;
} }
@ -193,8 +209,12 @@ form.mx_Custom_Widget_Form div {
.mx_AppPermissionWarning { .mx_AppPermissionWarning {
text-align: center; text-align: center;
padding: 30px 0;
background-color: $primary-bg-color; background-color: $primary-bg-color;
display: flex;
height: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
} }
.mx_AppPermissionWarningImage { .mx_AppPermissionWarningImage {

View File

@ -156,18 +156,17 @@ limitations under the License.
.mx_EventTile_redacted .mx_EventTile_line .mx_UnknownBody { .mx_EventTile_redacted .mx_EventTile_line .mx_UnknownBody {
display: block; display: block;
width: 100%; width: 100%;
height: 36px; height: 22px;
background-image: $event-redacted-img; width: 250px;
background-repeat: no-repeat; border-radius: 11px;
background-size: contain; background: repeating-linear-gradient(
} -45deg,
$event-redacted-fg-color,
.mx_EventTile.mx_EventTile_redacted .mx_EventTile_line { $event-redacted-fg-color 3px,
/* transparent 3px,
Prevent changing colour of the background because transparent 6px
$event-redacted-img matches $primary-bg-color );
*/ box-shadow: 0px 0px 3px $event-redacted-border-color inset;
background-color: initial !important;
} }
.mx_EventTile_highlight, .mx_EventTile_highlight,

View File

@ -26,19 +26,15 @@ limitations under the License.
} }
.mx_MemberDeviceInfo_textButton { .mx_MemberDeviceInfo_textButton {
color: $accent-fg-color; @mixin mx_DialogButton_small;
background-color: $accent-color;
border-radius: 17px;
text-align: center;
padding-left: 1em;
padding-right: 1em;
border: 0px;
font-size: 14px;
cursor: pointer;
margin: 2px; margin: 2px;
flex: 1; flex: 1;
} }
.mx_MemberDeviceInfo_textButton:hover {
@mixin mx_DialogButton_hover;
}
.mx_MemberDeviceInfo_deviceId { .mx_MemberDeviceInfo_deviceId {
font-size: 13px; font-size: 13px;
} }

View File

@ -49,7 +49,7 @@ limitations under the License.
.mx_MemberList_query, .mx_MemberList_query,
.mx_GroupMemberList_query, .mx_GroupMemberList_query,
.mx_GroupRoomList_query { .mx_GroupRoomList_query {
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif; font-family: $font-family;
border-radius: 3px; border-radius: 3px;
border: 1px solid $input-border-color; border: 1px solid $input-border-color;
padding: 9px; padding: 9px;

View File

@ -55,9 +55,11 @@ limitations under the License.
.mx_MessageComposer_noperm_error { .mx_MessageComposer_noperm_error {
width: 100%; width: 100%;
height: 60px; height: 60px;
text-align: center;
font-style: italic; font-style: italic;
color: $greyed-fg-color; color: $greyed-fg-color;
display: flex;
align-items: center;
justify-content: center;
} }
.mx_MessageComposer_input_wrapper { .mx_MessageComposer_input_wrapper {
@ -135,7 +137,7 @@ limitations under the License.
max-height: 120px; max-height: 120px;
overflow: auto; overflow: auto;
/* needed for FF */ /* needed for FF */
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif; font-family: $font-family;
} }
/* hack for FF as vertical alignment of custom placeholder text is broken */ /* hack for FF as vertical alignment of custom placeholder text is broken */
@ -172,6 +174,8 @@ limitations under the License.
.mx_MessageComposer_formatting { .mx_MessageComposer_formatting {
cursor: pointer; cursor: pointer;
margin: 0 11px; margin: 0 11px;
width: 24px;
height: 18px;
} }
.mx_MessageComposer_formatbar_wrapper { .mx_MessageComposer_formatbar_wrapper {

View File

@ -42,22 +42,14 @@ limitations under the License.
} }
.mx_RoomHeader_textButton { .mx_RoomHeader_textButton {
height: 36px; @mixin mx_DialogButton;
background-color: $accent-color;
border-radius: 36px;
margin-right: 8px; margin-right: 8px;
color: $accent-fg-color; margin-top: -5px;
line-height: 34px;
margin-top: -2px;
text-align: center;
order: 2; order: 2;
cursor: pointer; }
/* .mx_RoomHeader_textButton:hover {
flex: 0 0 90px; @mixin mx_DialogButton_hover;
*/
padding-left: 12px;
padding-right: 12px;
} }
.mx_RoomHeader_textButton_danger { .mx_RoomHeader_textButton_danger {

View File

@ -50,10 +50,11 @@ limitations under the License.
color: $primary-fg-color; color: $primary-fg-color;
background-color: $droptarget-bg-color; background-color: $droptarget-bg-color;
border-radius: 4px; border-radius: 4px;
line-height: 16px;
} }
.mx_RoomList_emptySubListTip .mx_RoleButton { .mx_RoomList_emptySubListTip .mx_RoleButton {
vertical-align: -3px; vertical-align: -2px;
} }
.mx_RoomList_headerButtons { .mx_RoomList_headerButtons {

View File

@ -22,18 +22,16 @@ limitations under the License.
.mx_RoomSettings_leaveButton, .mx_RoomSettings_leaveButton,
.mx_RoomSettings_unbanButton { .mx_RoomSettings_unbanButton {
@mixin mx_DialogButton;
position: relative; position: relative;
height: 36px;
background-color: $accent-color;
border-radius: 36px;
margin-right: 8px; margin-right: 8px;
color: $accent-fg-color;
line-height: 34px;
text-align: center;
cursor: pointer;
padding-left: 12px;
padding-right: 12px;
} }
.mx_RoomSettings_leaveButton:hover,
.mx_RoomSettings_unbanButton:hover {
@mixin mx_DialogButton_hover;
}
.mx_RoomSettings_integrationsButton_error { .mx_RoomSettings_integrationsButton_error {
position: relative; position: relative;
cursor: not-allowed; cursor: not-allowed;

View File

@ -21,7 +21,7 @@ limitations under the License.
} }
.mx_SearchableEntityList_query { .mx_SearchableEntityList_query {
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif; font-family: $font-family;
border-radius: 3px; border-radius: 3px;
border: 1px solid $input-border-color; border: 1px solid $input-border-color;
padding: 9px; padding: 9px;

View File

@ -1,3 +1,9 @@
/* Open Sans lacks combining diacritics, so these will fall through
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;
// typical text (dark-on-white in light skin) // typical text (dark-on-white in light skin)
$primary-fg-color: #454545; $primary-fg-color: #454545;
@ -34,6 +40,7 @@ $preview-bar-bg-color: #f7f7f7;
// left-panel style muted accent color // left-panel style muted accent color
$secondary-accent-color: #eaf5f0; $secondary-accent-color: #eaf5f0;
$tertiary-accent-color: #d3efe1;
// used by RoomDirectory permissions // used by RoomDirectory permissions
$plinth-bg-color: $secondary-accent-color; $plinth-bg-color: $secondary-accent-color;
@ -42,7 +49,7 @@ $plinth-bg-color: $secondary-accent-color;
$droptarget-bg-color: rgba(255,255,255,0.5); $droptarget-bg-color: rgba(255,255,255,0.5);
// used by AddressSelector // used by AddressSelector
$selected-color: #eaf5f0; $selected-color: $secondary-accent-color;
// selected for hoverover & selected event tiles // selected for hoverover & selected event tiles
$event-selected-color: #f7f7f7; $event-selected-color: #f7f7f7;
@ -65,6 +72,7 @@ $menu-border-color: rgba(187, 187, 187, 0.5);
$menu-bg-color: #f6f6f6; $menu-bg-color: #f6f6f6;
$avatar-initial-color: #ffffff; $avatar-initial-color: #ffffff;
$avatar-bg-color: #ffffff;
$h3-color: #3d3b39; $h3-color: #3d3b39;
@ -97,7 +105,14 @@ $roomtile-selected-bg-color: rgba(255, 255, 255, 0.8);
$roomtile-focused-bg-color: rgba(255, 255, 255, 0.9); $roomtile-focused-bg-color: rgba(255, 255, 255, 0.9);
$roomsublist-label-fg-color: $h3-color; $roomsublist-label-fg-color: $h3-color;
$roomsublist-label-bg-color: #d3efe1; $roomsublist-label-bg-color: $tertiary-accent-color;
$roomsublist-chevron-color: $accent-color;
$panel-divider-color: rgba(118, 207, 166, 0.2);
// ********************
$widget-menu-bar-bg-color: $tertiary-accent-color;
// ******************** // ********************
@ -107,7 +122,8 @@ $event-sending-color: #ddd;
$event-notsent-color: #f44; $event-notsent-color: #f44;
// event redaction // event redaction
$event-redacted-img: url('../../img/redacted.jpg'); $event-redacted-fg-color: #e2e2e2;
$event-redacted-border-color: #cccccc;
// event timestamp // event timestamp
$event-timestamp-color: #acacac; $event-timestamp-color: #acacac;
@ -120,6 +136,11 @@ $e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent-color
$e2e-unverified-color: #e8bf37; $e2e-unverified-color: #e8bf37;
$e2e-warning-color: #ba6363; $e2e-warning-color: #ba6363;
// presence
$presence-online: #60de00;
$presence-unavailable: #deb800;
$presence-offline: #b7b7b7;
/*** ImageView ***/ /*** ImageView ***/
$lightbox-bg-color: #454545; $lightbox-bg-color: #454545;
$lightbox-fg-color: #ffffff; $lightbox-fg-color: #ffffff;
@ -127,3 +148,32 @@ $lightbox-border-color: #ffffff;
// unused? // unused?
$progressbar-color: #000; $progressbar-color: #000;
// ***** Mixins! *****
@define-mixin mx_DialogButton {
/* align images in buttons (eg spinners) */
vertical-align: middle;
border: 0px;
border-radius: 36px;
font-family: $font-family;
font-size: 14px;
color: $accent-fg-color;
background-color: $accent-color;
width: auto;
padding: 7px;
padding-left: 1.5em;
padding-right: 1.5em;
cursor: pointer;
display: inline-block;
outline: none;
}
@define-mixin mx_DialogButton_hover {
}
@define-mixin mx_DialogButton_small {
@mixin mx_DialogButton;
font-size: 15px;
padding: 0px 1.5em 0px 1.5em;
}

View File

@ -29,6 +29,18 @@ $preview-bar-bg-color: #333;
// left-panel style muted accent color // left-panel style muted accent color
$secondary-accent-color: $primary-bg-color; $secondary-accent-color: $primary-bg-color;
$tertiary-accent-color: #454545;
// stop the tinter trying to change the secondary accent color
// by overriding the key to something untintable
// XXX: this is a bit of a hack.
#mx_theme_secondaryAccentColor {
color: #c0ffee ! important;
}
#mx_theme_tertiaryAccentColor {
color: #c0ffee ! important;
}
// used by RoomDirectory permissions // used by RoomDirectory permissions
$plinth-bg-color: #474747; $plinth-bg-color: #474747;
@ -60,6 +72,7 @@ $menu-border-color: rgba(187, 187, 187, 0.5);
$menu-bg-color: #373737; $menu-bg-color: #373737;
$avatar-initial-color: #2d2d2d; $avatar-initial-color: #2d2d2d;
$avatar-bg-color: #ffffff;
$h3-color: $primary-fg-color; $h3-color: $primary-fg-color;
@ -91,7 +104,14 @@ $roomtile-selected-bg-color: rgba(255, 255, 255, 0.05);
$roomtile-focused-bg-color: rgba(255, 255, 255, 0.2); $roomtile-focused-bg-color: rgba(255, 255, 255, 0.2);
$roomsublist-label-fg-color: $h3-color; $roomsublist-label-fg-color: $h3-color;
$roomsublist-label-bg-color: #454545; $roomsublist-label-bg-color: $tertiary-accent-color;
$roomsublist-chevron-color: $accent-color;
$panel-divider-color: rgba(118, 207, 166, 0.2);
// ********************
$widget-menu-bar-bg-color: $tertiary-accent-color;
// ******************** // ********************
@ -101,7 +121,8 @@ $event-sending-color: #888;
$event-notsent-color: #f44; $event-notsent-color: #f44;
// event redaction // event redaction
$event-redacted-img: url('../../img/redacted-dark.jpg'); $event-redacted-fg-color: #606060;
$event-redacted-border-color: #000000;
// event timestamp // event timestamp
$event-timestamp-color: #acacac; $event-timestamp-color: #acacac;
@ -122,6 +143,25 @@ $lightbox-border-color: #ffffff;
// unused? // unused?
$progressbar-color: #000; $progressbar-color: #000;
// XXX: copypasted from _base in order to pick up the right FG color...
@define-mixin mx_DialogButton {
/* align images in buttons (eg spinners) */
vertical-align: middle;
border: 0px;
border-radius: 36px;
font-family: $font-family;
font-size: 14px;
color: $accent-fg-color;
background-color: $accent-color;
width: auto;
padding: 7px;
padding-left: 1.5em;
padding-right: 1.5em;
cursor: pointer;
display: inline-block;
outline: none;
}
// Nasty hacks to apply a filter to arbitrary monochrome artwork to make it // Nasty hacks to apply a filter to arbitrary monochrome artwork to make it
// better match the theme. Typically applied to dark grey 'off' buttons or // better match the theme. Typically applied to dark grey 'off' buttons or
// light grey 'on' buttons. // light grey 'on' buttons.

View File

@ -44,12 +44,13 @@ limitations under the License.
.mx_LeftPanel.collapsed .mx_BottomLeftMenu { .mx_LeftPanel.collapsed .mx_BottomLeftMenu {
flex: 0 0 160px; flex: 0 0 160px;
margin-bottom: 9px;
} }
.mx_LeftPanel .mx_BottomLeftMenu { .mx_LeftPanel .mx_BottomLeftMenu {
order: 3; order: 3;
border-top: 1px solid rgba(118, 207, 166, 0.2); border-top: 1px solid $panel-divider-color;
margin-left: 16px; /* gutter */ margin-left: 16px; /* gutter */
margin-right: 16px; /* gutter */ margin-right: 16px; /* gutter */
flex: 0 0 60px; flex: 0 0 60px;
@ -77,6 +78,7 @@ limitations under the License.
.mx_BottomLeftMenu_options .mx_RoleButton { .mx_BottomLeftMenu_options .mx_RoleButton {
margin-left: 0px; margin-left: 0px;
margin-right: 10px; margin-right: 10px;
height: 30px;
} }
.mx_BottomLeftMenu_options .mx_BottomLeftMenu_settings { .mx_BottomLeftMenu_options .mx_BottomLeftMenu_settings {

View File

@ -33,14 +33,13 @@ limitations under the License.
font-weight: 600; font-weight: 600;
font-size: 12px; font-size: 12px;
width: 203px; /* padding + width = LHS Panel width */ width: 203px; /* padding + width = LHS Panel width */
height: 17px; /* padding + height = 29px, same as mx_RoomSubList_stickyContainer */ height: 19px; /* height + padding = 31px = mx_RoomSubList_label height */
padding-left: 16px; /* gutter */ padding-left: 16px; /* gutter */
padding-right: 16px; /* gutter */ padding-right: 16px; /* gutter */
padding-top: 6px; padding-top: 6px;
padding-bottom: 6px; padding-bottom: 6px;
cursor: pointer; cursor: pointer;
background-color: $roomsublist-label-bg-color; background-color: $secondary-accent-color;
border-top: solid 2px $secondary-accent-color;
} }
.mx_RoomSubList_label.mx_RoomSubList_fixed { .mx_RoomSubList_label.mx_RoomSubList_fixed {
@ -129,7 +128,7 @@ limitations under the License.
height: 0; height: 0;
border-left: 5px solid transparent; border-left: 5px solid transparent;
border-right: 5px solid transparent; border-right: 5px solid transparent;
border-top: 6px solid $accent-color; border-top: 6px solid $roomsublist-chevron-color;
} }
.mx_RoomSubList_chevronUp { .mx_RoomSubList_chevronUp {
@ -137,14 +136,14 @@ limitations under the License.
height: 0; height: 0;
border-left: 5px solid transparent; border-left: 5px solid transparent;
border-right: 5px solid transparent; border-right: 5px solid transparent;
border-bottom: 6px solid $accent-color; border-bottom: 6px solid $roomsublist-chevron-color;
} }
.mx_RoomSubList_chevronRight { .mx_RoomSubList_chevronRight {
width: 0; width: 0;
height: 0; height: 0;
border-top: 5px solid transparent; border-top: 5px solid transparent;
border-left: 6px solid $accent-color; border-left: 6px solid $roomsublist-chevron-color;
border-bottom: 5px solid transparent; border-bottom: 5px solid transparent;
} }

View File

@ -0,0 +1,42 @@
/*
Copyright 2017 Travis Ralston
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.
*/
.mx_PresenceContextMenuOption_indicator {
width: 10px;
height: 10px;
border-radius: 10px;
display: inline-block;
margin-right: 5px;
}
.mx_PresenceContextMenuOption_indicator.mx_PresenceContextMenuOption_indicator_online {
background-color: $presence-online;
}
.mx_PresenceContextMenuOption_indicator.mx_PresenceContextMenuOption_indicator_unavailable {
background-color: $presence-unavailable;
}
.mx_PresenceContextMenuOption_indicator.mx_PresenceContextMenuOption_indicator_offline {
background-color: $presence-offline;
}
.mx_PresenceContextMenuOption {
padding: 2px;
}
.mx_PresenceContextMenuOption.mx_PresenceContextMenuOption_current {
font-weight: 700;
}

View File

@ -56,3 +56,7 @@ limitations under the License.
.mx_MatrixToolbar_action { .mx_MatrixToolbar_action {
margin-right: 16px; margin-right: 16px;
} }
.mx_MatrixToolbar_changelog {
white-space: pre;
}

View File

@ -1,18 +1,21 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="utf-8"?>
<svg width="24px" height="18px" viewBox="0 0 24 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!-- Generator: sketchtool 39 (31667) - http://www.bohemiancoding.com/sketch --> <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"
<title>F69CBF5F-0BEC-47E8-B1DF-125D6376C0C9</title> viewBox="0 0 24 18" style="enable-background:new 0 0 24 18;" xml:space="preserve">
<desc>Created with sketchtool.</desc> <style type="text/css">
<defs></defs> .st0{fill:#F6F6F6;}
<g id="Screens-revised" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> .st1{enable-background:new ;}
<g id="02_x-Chat-text-input-" transform="translate(-829.000000, -729.000000)"> .st2{fill:#4A4A4A;}
<g id="button_text_formatting" transform="translate(829.000000, 729.000000)"> </style>
<rect id="Rectangle-111" fill="#F6F6F6" x="0" y="0" width="24" height="18" rx="9"></rect> <path id="Rectangle-111" class="st0" d="M9,0h6c5,0,9,4,9,9l0,0c0,5-4,9-9,9H9c-5,0-9-4-9-9l0,0C0,4,4,0,9,0z"/>
<text id="Aa" font-family="OpenSans-Bold, Open Sans" font-size="12" font-weight="bold" letter-spacing="-1.20000005" fill="#4A4A4A"> <g class="st1">
<tspan x="5" y="13">A</tspan> <path class="st2" d="M11.3,13l-0.6-2H7.6L7,13H5l3-8.6h2.2l3,8.6H11.3z M10.3,9.4c-0.6-1.8-0.9-2.9-1-3.1S9.2,5.9,9.1,5.7
<tspan x="12.0792968" y="13" font-family="OpenSans-Italic, Open Sans" font-style="italic" font-weight="normal">a</tspan> C9,6.2,8.6,7.5,8,9.4H10.3z"/>
</text> </g>
</g> <g class="st1">
</g> <path class="st2" d="M15.8,6.5c0.4,0,0.7,0.1,1,0.3s0.5,0.5,0.7,0.8h0.1l0.4-1h0.7L17.3,13h-0.8l0.2-1.2h0
</g> c-0.7,0.9-1.4,1.3-2.2,1.3c-0.5,0-1-0.2-1.3-0.6s-0.5-0.9-0.5-1.6c0-0.8,0.1-1.6,0.4-2.3s0.7-1.2,1.1-1.6S15.2,6.5,15.8,6.5z
M14.7,12.3c0.4,0,0.8-0.2,1.1-0.5s0.7-0.8,0.9-1.4s0.4-1.2,0.4-1.7c0-0.4-0.1-0.7-0.3-1s-0.5-0.4-0.9-0.4c-0.4,0-0.8,0.2-1.1,0.5
S14.2,8.6,14,9.2s-0.3,1.2-0.3,1.8c0,0.4,0.1,0.8,0.3,1S14.4,12.3,14.7,12.3z"/>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<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"
width="2048px" height="1792px" viewBox="0 0 2048 1792" enable-background="new 0 0 2048 1792" xml:space="preserve">
<path fill="#76CFA6" d="M1024,672c79.333,0,147.166,28.167,203.5,84.5c56.333,56.334,84.5,124.167,84.5,203.5
c0,79.334-28.167,147.167-84.5,203.5c-56.334,56.334-124.167,84.5-203.5,84.5c-79.334,0-147.167-28.166-203.5-84.5
C764.166,1107.167,736,1039.334,736,960c0-79.333,28.166-147.166,84.5-203.5C876.833,700.167,944.666,672,1024,672z M1728,256
c70.666,0,131,25,181,75s75,110.334,75,181v896c0,70.667-25,131-75,181s-110.334,75-181,75H320c-70.667,0-131-25-181-75
s-75-110.333-75-181V512c0-70.666,25-131,75-181s110.333-75,181-75h224l51-136c12.666-32.666,35.833-60.833,69.5-84.5
C698.166,11.834,732.666,0,768,0h512c35.333,0,69.833,11.834,103.5,35.5c33.666,23.667,56.833,51.834,69.5,84.5l51,136H1728z
M1024,1408c123.333,0,228.833-43.833,316.5-131.5c87.666-87.666,131.5-193.166,131.5-316.5c0-123.333-43.834-228.833-131.5-316.5
C1252.833,555.834,1147.333,512,1024,512c-123.334,0-228.834,43.834-316.5,131.5C619.833,731.167,576,836.667,576,960
c0,123.334,43.833,228.834,131.5,316.5C795.166,1364.167,900.666,1408,1024,1408z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 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="#76CFA6" 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

@ -1,13 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<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" <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"
width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve"> width="512px" height="512px" viewBox="0 0 512 512" xml:space="preserve">
<g> <g>
<rect fill="#000000" x="167.664" y="69.108" transform="matrix(-0.7071 -0.7071 0.7071 -0.7071 219.262 633.2606)" width="146.238" height="404.224"/>
<rect x="178.846" y="92.087" transform="matrix(-0.7071 -0.7071 0.7071 -0.7071 224.3476 631.1498)" width="128.085" height="354.049"/> <path fill="#000000" d="M502.05,64.887L447.116,9.952c-13.386-13.385-36.032-12.44-50.585,2.113l-51.609,51.61L448.328,167.08l51.609-51.608
<path d="M471.723,88.393l-48.115-48.114c-11.723-11.724-31.558-10.896-44.304,1.85l-45.202,45.203l90.569,90.568l45.202-45.202 C514.486,100.918,515.434,78.271,502.05,64.887z"/>
C482.616,119.952,483.445,100.116,471.723,88.393z"/> <polygon fill="#000000" points="36.56,378.704 0,512 133.283,475.439"/>
<polygon points="64.021,363.252 32,480 148.737,447.979 "/> </g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 876 B

After

Width:  |  Height:  |  Size: 780 B

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<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"
width="512px" height="512px" viewBox="0 0 512 512" xml:space="preserve">
<g>
<rect fill="#76CFA6" x="167.664" y="69.108" transform="matrix(-0.7071 -0.7071 0.7071 -0.7071 219.262 633.2606)" width="146.238" height="404.224"/>
<path fill="#76CFA6" d="M502.05,64.887L447.116,9.952c-13.386-13.385-36.032-12.44-50.585,2.113l-51.609,51.61L448.328,167.08l51.609-51.608
C514.486,100.918,515.434,78.271,502.05,64.887z"/>
<polygon fill="#76CFA6" points="36.56,378.704 0,512 133.283,475.439"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 780 B

View File

@ -1,10 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<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" <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"
width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve"> width="512px" height="533px" viewBox="0 -11.5 512 533" xml:space="preserve">
<g> <g>
<path fill="#FF0064" d="M85.633,454.889c0,31.168,25.553,56.661,56.79,56.661h227.156c31.234,0,56.787-25.493,56.787-56.661 <g>
V128.225H85.633V454.889z M468.958,43.042H362.479L326.828,0.45H185.173l-35.652,42.591H43.042v42.592h425.916V43.042z"/> <path fill="#FF0064" d="M142.423,517.05c-34.347,0-62.29-27.886-62.29-62.161V128.225c0-3.038,2.462-5.5,5.5-5.5h340.733
c3.037,0,5.5,2.462,5.5,5.5v326.664c0,34.275-27.942,62.161-62.287,62.161H142.423z M43.042,91.133c-3.038,0-5.5-2.462-5.5-5.5
V43.041c0-3.038,2.462-5.5,5.5-5.5h103.91L180.956-3.08c1.045-1.249,2.589-1.97,4.217-1.97h141.655
c1.628,0,3.173,0.721,4.218,1.97l34.001,40.622h103.911c3.037,0,5.5,2.462,5.5,5.5v42.591c0,3.038-2.463,5.5-5.5,5.5H43.042z"/>
<path fill="#000000" d="M326.828,0.45l35.65,42.592h106.479v42.591H43.042V43.041h106.479L185.173,0.45H326.828 M426.366,128.225
v326.664c0,31.168-25.553,56.661-56.787,56.661H142.423c-31.237,0-56.79-25.493-56.79-56.661V128.225H426.366 M326.828-10.55
H185.173c-3.256,0-6.345,1.442-8.435,3.939l-32.354,38.651H43.042c-6.075,0-11,4.925-11,11v42.592c0,6.075,4.925,11,11,11h425.916
c6.075,0,11-4.925,11-11V43.042c0-6.075-4.925-11-11-11H367.616L335.264-6.61C333.173-9.107,330.084-10.55,326.828-10.55
L326.828-10.55z M426.366,117.225H85.633c-6.075,0-11,4.925-11,11v326.664c0,37.309,30.411,67.661,67.79,67.661h227.156
c37.378,0,67.787-30.353,67.787-67.661V128.225C437.366,122.15,432.441,117.225,426.366,117.225L426.366,117.225z"/>
</g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 738 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<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"
width="1792px" height="1792px" viewBox="0 0 1792 1792" enable-background="new 0 0 1792 1792" xml:space="preserve">
<path fill="#76CFA6" d="M256,1408h1280V640H256V1408z M1792,288v1216c0,44-15.667,81.667-47,113s-69,47-113,47H160
c-44,0-81.667-15.667-113-47s-47-69-47-113V288c0-44,15.667-81.667,47-113s69-47,113-47h1472c44,0,81.667,15.667,113,47
S1792,244,1792,288z"/>
</svg>

After

Width:  |  Height:  |  Size: 745 B

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<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"
width="1792px" height="1792px" viewBox="0 0 1792 1792" enable-background="new 0 0 1792 1792" xml:space="preserve">
<path fill="#76CFA6" d="M1792,1312v192c0,44-15.667,81.667-47,113s-69,47-113,47H160c-44,0-81.667-15.667-113-47s-47-69-47-113v-192
c0-44,15.667-81.667,47-113s69-47,113-47h1472c44,0,81.667,15.667,113,47S1792,1268,1792,1312z"/>
</svg>

After

Width:  |  Height:  |  Size: 716 B

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<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"
width="500px" height="500px" viewBox="0 0 500 500" enable-background="new 0 0 500 500" xml:space="preserve">
<g>
<g>
<g>
<defs>
<path id="SVGID_1_" d="M191.667,56.25c33.333-60.417,85.417-60.417,118.75,0l172.916,320.834
C516.667,437.5,487.5,487.5,416.667,487.5H83.333c-68.75,0-97.917-50-66.667-110.416L191.667,56.25L191.667,56.25z"/>
</defs>
<use xlink:href="#SVGID_1_" overflow="visible" fill="#E8BF37"/>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
<rect x="-100" y="-93.75" clip-path="url(#SVGID_2_)" fill="#E8BF37" width="700" height="685.417"/>
</g>
</g>
<g>
<g>
<defs>
<path id="SVGID_3_" d="M264.584,322.916l6.25-200h-41.667l6.25,200H264.584L264.584,322.916z M250,408.334
c14.584,0,25-10.418,25-25c0-14.584-10.416-25-25-25c-14.583,0-25,10.416-25,25C225,397.916,235.417,408.334,250,408.334
L250,408.334L250,408.334z"/>
</defs>
<clipPath id="SVGID_4_">
<use xlink:href="#SVGID_3_" overflow="visible"/>
</clipPath>
<rect x="120.833" y="18.75" clip-path="url(#SVGID_4_)" fill="#FFFFFF" width="258.333" height="493.75"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,232 @@
/*
Copyright 2017 New Vector 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.
*/
// overrides for mx_Login* specific to Status.
// Ideally this would be all Status prefixes for a Status specific version of the component
// but given we're not doing Status as a dedicated 'skin' yet...
.mx_StatusLogin {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
overflow: auto;
.mx_StatusLogin_brand {
position: absolute;
top: 30px;
left: 30px;
}
.mx_StatusLogin_content {
margin: auto;
}
.mx_StatusLogin_header {
text-align: center;
margin-top: 70px;
margin-bottom: 50px;
}
.mx_StatusLogin_header h1 {
font-size: 29px;
margin-bottom: 3px;
}
.mx_StatusLogin_subtitle {
font-size: 18px;
}
.mx_StatusLogin_subtitle a {
color: $riot-link-color;
}
.mx_StatusLogin_footer {
margin-top: 30px;
margin-bottom: 30px;
text-align: center;
font-size: 16px;
color: $footer-color;
}
.mx_StatusLogin_footer p {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.mx_StatusLogin_footer_cta {
color: $callout-color;
font-family: $header-font-family;
letter-spacing: 1px;
font-size: 13px;
text-transform: uppercase;
opacity: 1.0;
transition: opacity .2s ease;
}
.mx_StatusLogin_footer_cta:hover {
opacity: 0.5;
text-decoration: none;
}
// overrides of .mx_Login
.mx_Login_box {
width: 330px;
min-height: initial;
padding-top: 40px;
padding-bottom: 20px;
padding-left: 10px;
padding-right: 10px;
border-radius: 8px;
color: $form-fg-color;
font-size: 16px;
line-height: 25px;
background-color: $form-bg-color;
background-image: url(../../themes/status/img/dot.svg);
box-shadow: 0px 5px 16px 0px rgba(25,12,46,0.16);
position: relative;
text-align: center;
}
.mx_Login_logo {
background-color: #fff;
width: 74px;
height: 74px;
border-radius: 37px;
box-shadow: 0px 5px 16px 0px rgba(0,0,0,0.2);
position: absolute;
top: -36px;
left: 50%;
margin-left: -36px;
}
.mx_Login_logo img {
width: 36px;
height: 36px;
padding: 19px;
}
.mx_Login_box h2 {
text-align: center;
color: $form-fg-color;
font-size: 25px;
margin-bottom: 24px;
}
.mx_Login_field {
width: 260px;
height: 27px;
padding: 8px 20px 10px 20px;
border-radius: 10px;
text-align: left;
border: 1px solid transparent;
background-color: $form-field-bg-color;
color: $form-field-fg-color;
font-weight: 300;
font-size: 15px;
margin-bottom: 14px;
transition: background-color .2s ease;
}
.mx_Login_field:focus {
border: 1px solid transparent;
background-color: $form-field-bg-hover-color;
}
.mx_Login_field::-webkit-input-placeholder {
font-family: $font-family;
color: $form-field-fg-color;
opacity: 0.6;
}
.mx_Login_field::-moz-placeholder {
font-family: $font-family;
color: $form-field-fg-color;
opacity: 0.6;
}
.mx_Login_field_disabled {
opacity: 0.3;
}
.mx_Login_prompt {
font-size: 16px;
}
.mx_Login_submit {
min-width: 200px;
width: auto;
margin-top: 13px;
margin-bottom: 10px;
}
.mx_Login_submit:disabled {
opacity: 0.3;
}
.mx_Login_create {
margin-top: 10px;
display: block;
text-align: center;
width: 100%;
font-size: 15px;
opacity: 1.0;
}
.mx_Login_create:link,
.mx_Login_create:hover,
.mx_Login_create:visited
{
color: $form-fg-color;
}
.mx_Login_forgot {
display: block;
font-size: 15px;
}
.mx_Login_forgot:link,
.mx_Login_forgot:hover,
.mx_Login_forgot:visited
{
color: $form-fg-color;
}
.mx_Login_error {
color: $warning-color;
font-size: 18px;
width: 300px;
height: 44px;
display: flex;
justify-content: center;
align-items: center;
margin: auto;
text-align: center;
margin-top: 12px;
margin-bottom: 16px;
}
.mx_Login_smallError {
font-size: 13px;
line-height: initial;
}
}

View File

@ -0,0 +1,285 @@
@font-face {
font-family:PostGrotesk-Medium;
src:url('https://status.im/fonts/PostGrotesk-Medium.eot');
src:url('https://status.im/fonts/PostGrotesk-Medium.eot?#iefix') format("embedded-opentype"),url('https://status.im/fonts/PostGrotesk-Medium.woff') format("woff"),url('https://status.im/fonts/PostGrotesk-Medium.svg#PostGrotesk-Medium') format("svg");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family:PostGrotesk-Book;
src:url('https://status.im/fonts/PostGrotesk-Book.eot');
src:url('https://status.im/fonts/PostGrotesk-Book.eot?#iefix') format("embedded-opentype"),url('https://status.im/fonts/PostGrotesk-Book.woff') format("woff"),url('https://status.im/fonts/PostGrotesk-Book.svg#PostGrotesk-Book') format("svg");
font-weight: 400;
font-style: normal;
}
// We deliberately prioritise Arial over Helvetica here due to diacritic problems (see _base.scss)
// N.B. that the status.im website uses:
// font-family:PostGrotesk-Book,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
// ...but can't be bothered to work out how the apple fonts & segoe interact, so keepingn it simple for now.
$font-family: PostGrotesk-Book, Arial, Helvetica, Sans-Serif;
// typical text (dark-on-white in light skin)
$primary-fg-color: #70808D;
$primary-bg-color: #EEF2F5;
// ***** Start of Status theme specifics ******
$header-color: #49555F;
$header-font-family: PostGrotesk-Medium, Arial, Helvetica, Sans-Serif;
$footer-color: #8D99A4;
$riot-link-color: #A26988;
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
h1,h2,h3,h4,h5 {
color: $header-color;
font-family: $header-font-family;
font-weight: 400 ! important;
}
$callout-color: #4360DF; // or #4957b8 from status.im homepage
$form-bg-color: $callout-color;
$form-fg-color: #ffffff;
$form-field-bg-color: rgba(244, 242, 247, 0.12);
$form-field-bg-hover-color: rgba(255, 255, 255, 0.2);
$form-field-fg-color: #ffffff;
// ***** End of Status theme specifics ******
// used for dialog box text
$light-fg-color: #747474;
// used for focusing form controls
$focus-bg-color: #dddddd;
// button UI (white-on-green in light skin)
$accent-fg-color: #ffffff;
$accent-color: #6CC1F6;
$accent-hover-color: #84cfff;
$selection-fg-color: $primary-bg-color;
$focus-brightness: 125%;
// red warning colour
$warning-color: #F69E98;
$mention-user-pill-bg-color: #ff0064;
$other-user-pill-bg-color: rgba(0, 0, 0, 0.1);
$group-alert-color: #774f7e;
$preview-bar-bg-color: #f7f7f7;
// left-panel style muted accent color
$secondary-accent-color: #586C7B;
$tertiary-accent-color: #DBEBF6;
// stop the tinter trying to change the secondary accent color
// by overriding the key to something untintable
// XXX: this is a bit of a hack.
#mx_theme_secondaryAccentColor {
color: #c0ffee ! important;
}
#mx_theme_tertiaryAccentColor {
color: #c0ffee ! important;
}
// used by RoomDirectory permissions
$plinth-bg-color: $secondary-accent-color;
// used by RoomDropTarget
$droptarget-bg-color: rgba(255,255,255,0.5);
// used by AddressSelector
$selected-color: #eaf5f0;
// selected for hoverover & selected event tiles
$event-selected-color: #f7f7f7;
// used for the hairline dividers in RoomView
$primary-hairline-color: #e5e5e5;
// used for the border of input text fields
$input-border-color: #c9cfd4;
// apart from login forms, which have stronger border
$strong-input-border-color: #c7c7c7;
// used for UserSettings EditableText
$input-underline-color: rgba(151, 151, 151, 0.5);
$input-fg-color: rgba(74, 74, 74, 0.9);
// context menus
$menu-border-color: rgba(187, 187, 187, 0.5);
$menu-bg-color: #f6f6f6;
$avatar-initial-color: #ffffff;
$avatar-bg-color: transparent;
$h3-color: #3d3b39;
$dialog-background-bg-color: #e9e9e9;
$lightbox-background-bg-color: #000;
$greyed-fg-color: #888;
$neutral-badge-color: #dbdbdb;
$preview-widget-bar-color: #ddd;
$preview-widget-fg-color: $greyed-fg-color;
$blockquote-bar-color: #ddd;
$blockquote-fg-color: #777;
$settings-grey-fg-color: #a2a2a2;
$voip-decline-color: #f48080;
$voip-accept-color: #80f480;
$rte-bg-color: #e9e9e9;
$rte-code-bg-color: rgba(0, 0, 0, 0.04);
$rte-room-pill-color: #aaa;
// ********************
$roomtile-name-color: #ffffff;
$roomtile-selected-bg-color: #465561;
$roomtile-focused-bg-color: #6d8597;
$roomsublist-label-fg-color: #ffffff;
$roomsublist-label-bg-color: $secondary-accent-color;
$roomsublist-chevron-color: #ffffff;
$panel-divider-color: rgba(0, 0, 0, 0.2);
// ********************
$widget-menu-bar-bg-color: #f7f7f7;
// ********************
// event tile lifecycle
$event-encrypting-color: #abddbc;
$event-sending-color: #ddd;
$event-notsent-color: #f44;
// event redaction
$event-redacted-fg-color: #e2e2e2;
$event-redacted-border-color: #cccccc;
// event timestamp
$event-timestamp-color: #acacac;
$edit-button-url: "../../img/icon_context_message.svg";
$copy-button-url: "../../img/icon_copy_message.svg";
// e2e
$e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent-color
$e2e-unverified-color: #e8bf37;
$e2e-warning-color: #ba6363;
/*** ImageView ***/
$lightbox-bg-color: #454545;
$lightbox-fg-color: #ffffff;
$lightbox-border-color: #ffffff;
// unused?
$progressbar-color: #000;
@define-mixin mx_DialogButton {
/* align images in buttons (eg spinners) */
vertical-align: middle;
border-radius: 8px;
border: 1px solid rgba(199, 206, 209, 0.12);
background-color: $accent-color;
font-size: 13px;
font-family: $header-font-family;
text-transform: uppercase;
letter-spacing: 1px;
color: $accent-fg-color;
cursor: pointer;
outline: none;
padding: 14px;
box-sizing: border-box;
padding-left: 1.5em;
padding-right: 1.5em;
display: inline-block;
transition: background-color .2s ease;
}
@define-mixin mx_DialogButton_hover {
background-color: $accent-hover-color;
}
@define-mixin mx_DialogButton_small {
@mixin mx_DialogButton;
height: auto;
padding-top: 7px;
padding-bottom: 7px;
padding-left: 1em;
padding-right: 1em;
}
.mx_RoomSubList_label {
font-size: 13px;
font-family: $header-font-family;
letter-spacing: 1px;
}
// FIXME: all these ! importants are horrid - we should instead go and define
// variables or something.
.mx_SearchBox_search {
color: #fff ! important;
}
.mx_SearchBox_search::-webkit-input-placeholder {
color: rgba(255, 255, 255, 0.6) ! important;
}
.mx_SearchBox_search::-moz-placeholder {
color: rgba(255, 255, 255, 0.6) ! important;
}
.mx_RoomList_emptySubListTip,
.mx_RoomDropTarget {
font-size: 14px ! important;
border: 1.5px dashed rgba(0,0,0,0.2) ! important;
color: #fff ! important;
background-color: transparent ! important;
border-radius: 6px ! important;
margin-left: 6px ! important;
margin-right: 6px ! important;
margin-top: 8px ! important;
margin-bottom: 7px ! important;
padding: 8px ! important;
}
.mx_RoomDirectory_perm {
font-family: $header-font-family ! important;
background-color: #fff ! important;
}
.mx_RoomTile_badge,
.mx_RoomSubList_badge {
height: 12px ! important;
padding-top: 1px ! important;
padding-bottom: 1px ! important;
}
.mx_RoomSubList_chevron {
top: 8px ! important;
}

View File

@ -0,0 +1,4 @@
@import "../../../css/themes/_base.scss";
@import "_status.scss";
@import "../../../css/_components.scss";
@import "_StatusLogin.scss";

View File

@ -0,0 +1 @@
We link out to status.im for fonts, although ideally we'd put them here.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1 @@
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><title>Artboard</title><circle cx="10" cy="10" r="1" fill="#FFF" fill-rule="evenodd" opacity=".11"/></svg>

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -20,15 +20,14 @@
<meta name="msapplication-TileImage" content="vector-icons/mstile-144x144.png"> <meta name="msapplication-TileImage" content="vector-icons/mstile-144x144.png">
<meta name="msapplication-config" content="vector-icons/browserconfig.xml"> <meta name="msapplication-config" content="vector-icons/browserconfig.xml">
<meta name="theme-color" content="#ffffff"> <meta name="theme-color" content="#ffffff">
<meta property="og:image" content="https://chat.status.im/img/logos/riot-im-logo-1.png" />
<% for (var i=0; i < htmlWebpackPlugin.files.css.length; i++) { <% for (var i=0; i < htmlWebpackPlugin.files.css.length; i++) {
var file = htmlWebpackPlugin.files.css[i]; var file = htmlWebpackPlugin.files.css[i];
var match = file.match(/^bundles\/.*?\/theme-(.*)\.css$/); var match = file.match(/^bundles\/.*?\/theme-(.*)\.css$/);
if (match) { if (match) {
var title = match[1].charAt(0).toUpperCase() + match[1].slice(1); var title = match[1].charAt(0).toUpperCase() + match[1].slice(1);
var light = match[1] == 'light';
%> %>
<link rel="<%= light ? '' : 'alternate ' %>stylesheet" title="<%= title %>" <link rel="stylesheet" disabled="disabled" title="<%= title %>" href="<%= file %>">
href="<%= file %>">
<% } else { %> <% } else { %>
<link rel="stylesheet" href="<%= file %>"> <link rel="stylesheet" href="<%= file %>">
<% } <% }
@ -73,5 +72,7 @@
<source src="media/busy.mp3" type="audio/mpeg" /> <source src="media/busy.mp3" type="audio/mpeg" />
</audio> </audio>
<audio id="remoteAudio"/> <audio id="remoteAudio"/>
<!-- let CSS themes pass constants to the app -->
<div id="mx_theme_accentColor"></div><div id="mx_theme_secondaryAccentColor"/></div><div id="mx_theme_tertiaryAccentColor"/></div>
</body> </body>
</html> </html>

View File

@ -67,7 +67,6 @@ sdk.loadSkin(require('../component-index'));
var VectorConferenceHandler = require('../VectorConferenceHandler'); var VectorConferenceHandler = require('../VectorConferenceHandler');
import Promise from 'bluebird'; import Promise from 'bluebird';
var request = require('browser-request'); var request = require('browser-request');
import * as UserSettingsStore from 'matrix-react-sdk/lib/UserSettingsStore';
import * as languageHandler from 'matrix-react-sdk/lib/languageHandler'; import * as languageHandler from 'matrix-react-sdk/lib/languageHandler';
// Also import _t directly so we can call it just `_t` as this is what gen-i18n.js expects // Also import _t directly so we can call it just `_t` as this is what gen-i18n.js expects
import { _t } from 'matrix-react-sdk/lib/languageHandler'; import { _t } from 'matrix-react-sdk/lib/languageHandler';
@ -78,6 +77,9 @@ import {parseQs, parseQsFromFragment} from './url_utils';
import Platform from './platform'; import Platform from './platform';
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg'; import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
import SettingsStore, {SettingLevel} from "matrix-react-sdk/lib/settings/SettingsStore";
import Tinter from 'matrix-react-sdk/lib/Tinter';
import SdkConfig from "matrix-react-sdk/lib/SdkConfig";
var lastLocationHashSet = null; var lastLocationHashSet = null;
@ -244,25 +246,6 @@ async function loadApp() {
// set the platform for react sdk (our Platform object automatically picks the right one) // set the platform for react sdk (our Platform object automatically picks the right one)
PlatformPeg.set(new Platform()); PlatformPeg.set(new Platform());
// don't try to redirect to the native apps if we're
// verifying a 3pid
const preventRedirect = Boolean(fragparts.params.client_secret);
if (!preventRedirect) {
if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
if (confirm(_t("Riot is not supported on mobile web. Install the app?"))) {
window.location = "https://itunes.apple.com/us/app/vector.im/id1083446067";
return;
}
}
else if (/Android/.test(navigator.userAgent)) {
if (confirm(_t("Riot is not supported on mobile web. Install the app?"))) {
window.location = "https://play.google.com/store/apps/details?id=im.vector.alpha";
return;
}
}
}
// Load the config file. First try to load up a domain-specific config of the // Load the config file. First try to load up a domain-specific config of the
// form "config.$domain.json" and if that fails, fall back to config.json. // form "config.$domain.json" and if that fails, fall back to config.json.
let configJson; let configJson;
@ -281,6 +264,70 @@ async function loadApp() {
configError = e; configError = e;
} }
// XXX: We call this twice, once here and once in MatrixChat as a prop. We call it here to ensure
// granular settings are loaded correctly and to avoid duplicating the override logic for the theme.
SdkConfig.put(configJson);
// don't try to redirect to the native apps if we're
// verifying a 3pid (but after we've loaded the config)
const preventRedirect = Boolean(fragparts.params.client_secret);
if (!preventRedirect) {
if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
// FIXME: ugly status hardcoding
if (SettingsStore.getValue("theme") === 'status') {
window.location = "https://status.im/join-riot.html";
return;
}
else {
if (confirm(_t("Riot is not supported on mobile web. Install the app?"))) {
window.location = "https://itunes.apple.com/us/app/vector.im/id1083446067";
return;
}
}
}
else if (/Android/.test(navigator.userAgent)) {
// FIXME: ugly status hardcoding
if (SettingsStore.getValue("theme") === 'status') {
window.location = "https://status.im/join-riot.html";
return;
}
else {
if (confirm(_t("Riot is not supported on mobile web. Install the app?"))) {
window.location = "https://play.google.com/store/apps/details?id=im.vector.alpha";
return;
}
}
}
}
// as quickly as we possibly can, set a default theme...
const styleElements = Object.create(null);
let a;
const theme = SettingsStore.getValue("theme");
for (let i = 0; (a = document.getElementsByTagName("link")[i]); i++) {
const href = a.getAttribute("href");
if (!href) continue;
// shouldn't we be using the 'title' tag rather than the href?
const match = href.match(/^bundles\/.*\/theme-(.*)\.css$/);
if (match) {
if (match[1] === theme) {
// remove the disabled flag off the stylesheet
a.removeAttribute("disabled");
// in case the Tinter.tint() in MatrixChat fires before the
// CSS has actually loaded (which in practice happens)...
// FIXME: we should probably block loading the app or even
// showing a spinner until the theme is loaded, to avoid
// flashes of unstyled content.
a.onload = () => {
Tinter.setTheme(theme);
};
}
}
}
if (window.localStorage && window.localStorage.getItem('mx_accepts_unsupported_browser')) { if (window.localStorage && window.localStorage.getItem('mx_accepts_unsupported_browser')) {
console.log('User has previously accepted risks in using an unsupported browser'); console.log('User has previously accepted risks in using an unsupported browser');
validBrowser = true; validBrowser = true;
@ -304,7 +351,7 @@ async function loadApp() {
config={configJson} config={configJson}
realQueryParams={params} realQueryParams={params}
startingFragmentQueryParams={fragparts.params} startingFragmentQueryParams={fragparts.params}
enableGuest={true} enableGuest={!configJson.disable_guests}
onTokenLoginCompleted={onTokenLoginCompleted} onTokenLoginCompleted={onTokenLoginCompleted}
initialScreenAfterLogin={getScreenFromLocation(window.location)} initialScreenAfterLogin={getScreenFromLocation(window.location)}
defaultDeviceDisplayName={platform.getDefaultDeviceDisplayName()} defaultDeviceDisplayName={platform.getDefaultDeviceDisplayName()}
@ -328,7 +375,7 @@ async function loadApp() {
} }
async function loadLanguage() { async function loadLanguage() {
const prefLang = UserSettingsStore.getLocalSetting('language'); const prefLang = SettingsStore.getValue("language", null, /*excludeDefault=*/true);
let langs = []; let langs = [];
if (!prefLang) { if (!prefLang) {
@ -340,6 +387,7 @@ async function loadLanguage() {
} }
try { try {
await languageHandler.setLanguage(langs); await languageHandler.setLanguage(langs);
document.documentElement.setAttribute("lang", languageHandler.getCurrentLanguage());
} catch (e) { } catch (e) {
console.error("Unable to set language", e); console.error("Unable to set language", e);
} }

View File

@ -546,6 +546,8 @@ describe('loading:', function () {
); );
}); });
/*
// ILAG renders this obsolete. I think.
it('should allow us to return to the app', function() { it('should allow us to return to the app', function() {
const login = ReactTestUtils.findRenderedComponentWithType( const login = ReactTestUtils.findRenderedComponentWithType(
matrixChat, sdk.getComponent('structures.login.Login') matrixChat, sdk.getComponent('structures.login.Login')
@ -568,6 +570,7 @@ describe('loading:', function () {
matrixChat, sdk.getComponent('structures.HomePage')); matrixChat, sdk.getComponent('structures.HomePage'));
}); });
}); });
*/
}); });
}); });

View File

@ -20,6 +20,7 @@ module.exports = {
// CSS themes // CSS themes
"theme-light": "./src/skins/vector/css/themes/light.scss", "theme-light": "./src/skins/vector/css/themes/light.scss",
"theme-dark": "./src/skins/vector/css/themes/dark.scss", "theme-dark": "./src/skins/vector/css/themes/dark.scss",
"theme-status": "./src/skins/vector/themes/status/css/status.scss",
}, },
module: { module: {
preLoaders: [ preLoaders: [