Merge remote-tracking branch 'upstream/develop' into fix_4821
2
.github/ISSUE_TEMPLATE.md
vendored
@ -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
|
||||
filling out the sections with your information, you will help the us to get all
|
||||
the necessary data to fix your issue.
|
||||
|
@ -13,3 +13,6 @@ include:
|
||||
|
||||
* Michael Telatynski (https://github.com/t3chguy)
|
||||
Improved consistency of inverted elements in dark theme across browsers
|
||||
|
||||
* Alexandr Korsak (https://github.com/oivoodoo)
|
||||
Improved multiple file uploading
|
||||
|
@ -1,6 +1,10 @@
|
||||
{
|
||||
"default_hs_url": "https://matrix.org",
|
||||
"default_is_url": "https://vector.im",
|
||||
"disable_custom_urls": false,
|
||||
"disable_guests": false,
|
||||
"disable_login_language_selector": false,
|
||||
"disable_3pid_login": false,
|
||||
"brand": "Riot",
|
||||
"integrations_ui_url": "https://scalar.vector.im/",
|
||||
"integrations_rest_url": "https://scalar.vector.im/api",
|
||||
@ -10,6 +14,8 @@
|
||||
"feature_pinning": "labs"
|
||||
},
|
||||
"default_federate": true,
|
||||
"welcomePageUrl": "home.html",
|
||||
"default_theme": "light",
|
||||
"roomDirectory": {
|
||||
"servers": [
|
||||
"matrix.org"
|
||||
|
68
docs/skinning thoughts.md
Normal 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?)
|
@ -36,9 +36,13 @@ function getColorName(hex) {
|
||||
## Adding variables inside a 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.
|
||||
3. 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. 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.
|
||||
1. Add it to the array in ``_t`` for example ``_t(STRING, {variable: this.variable})``
|
||||
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
|
||||
|
||||
@ -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.
|
||||
- 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.
|
||||
- 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.
|
||||
|
@ -5,6 +5,10 @@
|
||||
"brand": "Riot",
|
||||
"integrations_ui_url": "https://scalar.vector.im/",
|
||||
"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",
|
||||
"welcomeUserId": "@riot-bot:matrix.org",
|
||||
"roomDirectory": {
|
||||
|
192
res/home-status.html
Normal 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>
|
@ -43,10 +43,11 @@ const INCLUDE_LANGS = [
|
||||
const COPY_LIST = [
|
||||
["res/manifest.json", "webapp"],
|
||||
["res/home.html", "webapp"],
|
||||
["res/home-status.html", "webapp"],
|
||||
["res/home/**", "webapp/home"],
|
||||
["res/{media,vector-icons}/**", "webapp"],
|
||||
["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/png/*", "webapp/emojione/png/"],
|
||||
["./config.json", "webapp", { directwatch: 1 }],
|
||||
|
@ -21,7 +21,7 @@ import sdk from 'matrix-react-sdk';
|
||||
import dis from 'matrix-react-sdk/lib/dispatcher';
|
||||
import Velocity from 'velocity-vector';
|
||||
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;
|
||||
|
||||
|
@ -17,7 +17,7 @@ limitations under the License.
|
||||
'use strict';
|
||||
|
||||
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({
|
||||
displayName: 'CompatibilityPage',
|
||||
@ -40,30 +40,24 @@ module.exports = React.createClass({
|
||||
return (
|
||||
<div className="mx_CompatibilityPage">
|
||||
<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>
|
||||
{ _t("Riot uses many advanced browser features, some of which are not available or experimental in your current browser.") }
|
||||
</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.',
|
||||
[
|
||||
/<a href="https:\/\/www.google.com\/chrome">(.*?)<\/a>/,
|
||||
/<a href="https:\/\/getfirefox.com">(.*?)<\/a>/,
|
||||
],
|
||||
[
|
||||
(sub) => <a href="https://www.google.com/chrome">{sub}</a>,
|
||||
(sub) => <a href="https://getfirefox.com">{sub}</a>,
|
||||
]
|
||||
{ _t('Please install <chromeLink>Chrome</chromeLink> or <firefoxLink>Firefox</firefoxLink> for the best experience.',
|
||||
{},
|
||||
{
|
||||
'chromeLink': (sub) => <a href="https://www.google.com/chrome">{sub}</a>,
|
||||
'firefoxLink': (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.',
|
||||
[
|
||||
/<a href="http:\/\/apple\.com\/safari">(.*?)<\/a>/,
|
||||
/<a href="http:\/\/opera\.com">(.*?)<\/a>/,
|
||||
],
|
||||
[
|
||||
(sub) => <a href="http://apple.com/safari">{sub}</a>,
|
||||
(sub) => <a href="http://opera.com">{sub}</a>,
|
||||
]
|
||||
{ _t('<safariLink>Safari</safariLink> and <operaLink>Opera</operaLink> work too.',
|
||||
{},
|
||||
{
|
||||
'safariLink': (sub) => <a href="http://apple.com/safari">{sub}</a>,
|
||||
'operaLink': (sub) => <a href="http://opera.com">{sub}</a>,
|
||||
},
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
|
@ -17,10 +17,8 @@ limitations under the License.
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import { DragDropContext } from 'react-dnd';
|
||||
import HTML5Backend from 'react-dnd-html5-backend';
|
||||
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 dis from 'matrix-react-sdk/lib/dispatcher';
|
||||
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
|
||||
@ -199,4 +197,4 @@ var LeftPanel = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = DragDropContext(HTML5Backend)(LeftPanel);
|
||||
module.exports = LeftPanel;
|
||||
|
@ -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 GroupStoreCache from 'matrix-react-sdk/lib/stores/GroupStoreCache';
|
||||
|
||||
import { formatCount } from 'matrix-react-sdk/lib/utils/FormattingUtils';
|
||||
|
||||
class HeaderButton extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
@ -47,13 +49,19 @@ class HeaderButton extends React.Component {
|
||||
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
|
||||
|
||||
return <AccessibleButton className="mx_RightPanel_headerButton" onClick={this.onClick} >
|
||||
<div className="mx_RightPanel_headerButton_badge">
|
||||
{ this.props.badge ? this.props.badge : <span> </span> }
|
||||
</div>
|
||||
<TintableSvg src={this.props.iconSrc} width="25" height="25"/>
|
||||
{ this.props.isHighlighted ? <div className="mx_RightPanel_headerButton_highlight"></div> : <div/> }
|
||||
</AccessibleButton>;
|
||||
return <AccessibleButton
|
||||
aria-label={this.props.title}
|
||||
title={this.props.title}
|
||||
className="mx_RightPanel_headerButton"
|
||||
onClick={this.onClick} >
|
||||
|
||||
<div className="mx_RightPanel_headerButton_badge">
|
||||
{ this.props.badge ? this.props.badge : <span> </span> }
|
||||
</div>
|
||||
<TintableSvg src={this.props.iconSrc} width="25" height="25"/>
|
||||
{ this.props.isHighlighted ? <div className="mx_RightPanel_headerButton_highlight"></div> : <div/> }
|
||||
|
||||
</AccessibleButton>;
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +77,9 @@ HeaderButton.propTypes = {
|
||||
badge: PropTypes.node,
|
||||
// The parameters to track the click event
|
||||
analytics: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
|
||||
// Button title
|
||||
title: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
module.exports = React.createClass({
|
||||
@ -116,7 +127,7 @@ module.exports = React.createClass({
|
||||
return {
|
||||
phase: this.props.groupId ? this.Phase.GroupMemberList : this.Phase.RoomMemberList,
|
||||
isUserPrivilegedInGroup: null,
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
componentWillReceiveProps(newProps) {
|
||||
@ -128,9 +139,7 @@ module.exports = React.createClass({
|
||||
|
||||
_initGroupStore(groupId) {
|
||||
if (!groupId) return;
|
||||
this._groupStore = GroupStoreCache.getGroupStore(
|
||||
this.context.matrixClient, groupId,
|
||||
);
|
||||
this._groupStore = GroupStoreCache.getGroupStore(groupId);
|
||||
this._groupStore.registerListener(this.onGroupStoreUpdated);
|
||||
},
|
||||
|
||||
@ -140,7 +149,7 @@ module.exports = React.createClass({
|
||||
}
|
||||
},
|
||||
|
||||
onGroupStoreUpdated: function(){
|
||||
onGroupStoreUpdated: function() {
|
||||
this.setState({
|
||||
isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(),
|
||||
});
|
||||
@ -264,7 +273,7 @@ module.exports = React.createClass({
|
||||
const room = cli.getRoom(this.props.roomId);
|
||||
let userIsInRoom;
|
||||
if (room) {
|
||||
membersBadge = room.getJoinedMembers().length;
|
||||
membersBadge = formatCount(room.getJoinedMembers().length);
|
||||
userIsInRoom = room.hasMembershipState(
|
||||
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.
|
||||
headerButtons.push(
|
||||
<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"/>
|
||||
</div>,
|
||||
|
@ -30,7 +30,7 @@ var RoomNotifs = require('matrix-react-sdk/lib/RoomNotifs');
|
||||
var FormattingUtils = require('matrix-react-sdk/lib/utils/FormattingUtils');
|
||||
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
|
||||
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
|
||||
var debug = false;
|
||||
@ -327,43 +327,46 @@ var RoomSubList = React.createClass({
|
||||
},
|
||||
|
||||
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.
|
||||
// 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) {
|
||||
var prevTag = this.state.sortedList[index - 1].tags[this.props.tagName];
|
||||
const prevTag = this.state.sortedList[index - 1].tags[this.props.tagName];
|
||||
if (!prevTag) {
|
||||
console.error("Previous room in sublist is not tagged to be in this list. This should never happen.")
|
||||
}
|
||||
else if (prevTag.order === undefined) {
|
||||
console.error("Previous room in sublist is not tagged to be in this list. This should never happen.");
|
||||
} else if (prevTag.order === undefined) {
|
||||
console.error("Previous room in sublist has no ordering metadata. This should never happen.");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
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) {
|
||||
var nextTag = this.state.sortedList[index + 1].tags[this.props.tagName];
|
||||
const nextTag = this.state.sortedList[index + 1].tags[this.props.tagName];
|
||||
if (!nextTag) {
|
||||
console.error("Next room in sublist is not tagged to be in this list. This should never happen.")
|
||||
}
|
||||
else if (nextTag.order === undefined) {
|
||||
console.error("Next room in sublist is not tagged to be in this list. This should never happen.");
|
||||
} else if (nextTag.order === undefined) {
|
||||
console.error("Next room in sublist has no ordering metadata. This should never happen.");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
orderB = nextTag.order;
|
||||
}
|
||||
}
|
||||
|
||||
var order = (orderA + orderB) / 2.0;
|
||||
const order = (orderA + orderB) / 2.0;
|
||||
|
||||
if (order === orderA || order === orderB) {
|
||||
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;
|
||||
|
@ -18,7 +18,7 @@ limitations under the License.
|
||||
|
||||
import React from 'react';
|
||||
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 dis from 'matrix-react-sdk/lib/dispatcher';
|
||||
import rate_limited_func from 'matrix-react-sdk/lib/ratelimitedfunc';
|
||||
|
@ -24,7 +24,7 @@ const sdk = require('matrix-react-sdk');
|
||||
import { _t } from 'matrix-react-sdk/lib/languageHandler';
|
||||
const Modal = require('matrix-react-sdk/lib/Modal');
|
||||
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({
|
||||
displayName: 'MessageContextMenu',
|
||||
@ -67,7 +67,7 @@ module.exports = React.createClass({
|
||||
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
|
||||
if (!UserSettingsStore.isFeatureEnabled("feature_pinning")) canPin = false;
|
||||
if (!SettingsStore.isFeatureEnabled("feature_pinning")) canPin = false;
|
||||
|
||||
this.setState({canRedact, canPin});
|
||||
},
|
||||
|
101
src/components/views/context_menus/PresenceContextMenu.js
Normal 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>
|
||||
);
|
||||
},
|
||||
});
|
@ -60,7 +60,7 @@ class GenericEditor extends DevtoolsComponent {
|
||||
<label htmlFor={id}>{ label }</label>
|
||||
</div>
|
||||
<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>;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ export default React.createClass({
|
||||
const QuestionDialog = sdk.getComponent('dialogs.QuestionDialog');
|
||||
Modal.createTrackedDialog('Display release notes', '', QuestionDialog, {
|
||||
title: _t("What's New"),
|
||||
description: <pre className="changelog_text">{releaseNotes}</pre>,
|
||||
description: <div className="mx_MatrixToolbar_changelog">{releaseNotes}</div>,
|
||||
button: _t("Update"),
|
||||
onFinished: (update) => {
|
||||
if(update && PlatformPeg.get()) {
|
||||
|
@ -20,7 +20,7 @@ import React from 'react';
|
||||
import sdk from 'matrix-react-sdk';
|
||||
import Modal from 'matrix-react-sdk/lib/Modal';
|
||||
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({
|
||||
onUpdateClicked: function() {
|
||||
@ -49,10 +49,10 @@ export default React.createClass({
|
||||
alt="Warning"
|
||||
/>
|
||||
<div className="mx_MatrixToolbar_content">
|
||||
{ _tJsx(
|
||||
{ _t(
|
||||
"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>
|
||||
<button className="mx_MatrixToolbar_action">
|
||||
|
@ -18,6 +18,7 @@ limitations under the License.
|
||||
|
||||
var React = require('react');
|
||||
import { _t } from 'matrix-react-sdk/lib/languageHandler';
|
||||
import SettingsStore from 'matrix-react-sdk/lib/settings/SettingsStore';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'VectorLoginFooter',
|
||||
@ -26,6 +27,9 @@ module.exports = React.createClass({
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// FIXME: replace this with a proper Status skin
|
||||
if (SettingsStore.getValue("theme") === 'status') return <div/>;
|
||||
|
||||
return (
|
||||
<div className="mx_Login_links">
|
||||
<a href="https://medium.com/@RiotChat">blog</a> ·
|
||||
|
@ -33,8 +33,10 @@ module.exports = React.createClass({
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="mx_Login_logo">
|
||||
<img src={this.props.icon || DEFAULT_LOGO_URI} alt="Riot"/>
|
||||
<div className="mx_Login_header">
|
||||
<div className="mx_Login_logo">
|
||||
<img src={this.props.icon || DEFAULT_LOGO_URI} alt="Riot"/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -17,14 +17,15 @@ limitations under the License.
|
||||
import React from 'react';
|
||||
import Promise from 'bluebird';
|
||||
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 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 {
|
||||
NotificationUtils,
|
||||
VectorPushRulesDefinitions,
|
||||
PushRuleVectorState,
|
||||
NotificationUtils,
|
||||
VectorPushRulesDefinitions,
|
||||
PushRuleVectorState,
|
||||
ContentRules
|
||||
} from '../../../notifications';
|
||||
|
||||
@ -112,12 +113,33 @@ module.exports = React.createClass({
|
||||
},
|
||||
|
||||
onEnableDesktopNotificationsChange: function(event) {
|
||||
UserSettingsStore.setEnableNotifications(event.target.checked);
|
||||
SettingsStore.setValue(
|
||||
"notificationsEnabled", null,
|
||||
SettingLevel.DEVICE,
|
||||
event.target.checked,
|
||||
).finally(() => {
|
||||
this.forceUpdate();
|
||||
});
|
||||
},
|
||||
|
||||
onEnableDesktopNotificationBodyChange: function(event) {
|
||||
UserSettingsStore.setEnableNotificationBody(event.target.checked);
|
||||
this.forceUpdate();
|
||||
SettingsStore.setValue(
|
||||
"notificationBodyEnabled", null,
|
||||
SettingLevel.DEVICE,
|
||||
event.target.checked,
|
||||
).finally(() => {
|
||||
this.forceUpdate();
|
||||
});
|
||||
},
|
||||
|
||||
onEnableAudioNotificationsChange: function(event) {
|
||||
SettingsStore.setValue(
|
||||
"audioNotificationsEnabled", null,
|
||||
SettingLevel.DEVICE,
|
||||
event.target.checked,
|
||||
).finally(() => {
|
||||
this.forceUpdate();
|
||||
});
|
||||
},
|
||||
|
||||
onEnableEmailNotificationsChange: function(address, event) {
|
||||
@ -433,7 +455,7 @@ module.exports = React.createClass({
|
||||
needsUpdate.push( function(kind, rule) {
|
||||
return cli.setPushRuleActions(
|
||||
'global', kind, LEGACY_RULES[rule.rule_id], portLegacyActions(rule.actions)
|
||||
).then(() =>
|
||||
).then(() =>
|
||||
cli.deletePushRule('global', kind, rule.rule_id)
|
||||
).catch( (e) => {
|
||||
console.warn(`Error when porting legacy rule: ${e}`);
|
||||
@ -446,7 +468,7 @@ module.exports = React.createClass({
|
||||
if (needsUpdate.length > 0) {
|
||||
// If some of the rules need to be ported then wait for the porting
|
||||
// to happen and then fetch the rules again.
|
||||
return Promise.all(needsUpdate).then(() =>
|
||||
return Promise.all(needsUpdate).then(() =>
|
||||
cli.getPushRules()
|
||||
);
|
||||
} else {
|
||||
@ -542,10 +564,11 @@ module.exports = React.createClass({
|
||||
"vectorRuleId": "_keywords",
|
||||
"description" : (
|
||||
<span>
|
||||
{ _tJsx('Messages containing <span>keywords</span>',
|
||||
/<span>(.*?)<\/span>/,
|
||||
(sub) =>
|
||||
{ _t('Messages containing <span>keywords</span>',
|
||||
{},
|
||||
{ 'span': (sub) =>
|
||||
<span className="mx_UserNotifSettings_keywords" onClick={ self.onKeywordsClicked }>{sub}</span>
|
||||
},
|
||||
)}
|
||||
</span>
|
||||
),
|
||||
@ -694,13 +717,13 @@ module.exports = React.createClass({
|
||||
|
||||
render: function() {
|
||||
const self = this;
|
||||
|
||||
|
||||
let spinner;
|
||||
if (this.state.phase === this.phases.LOADING) {
|
||||
const Loader = sdk.getComponent("elements.Spinner");
|
||||
spinner = <Loader />;
|
||||
}
|
||||
|
||||
|
||||
let masterPushRuleDiv;
|
||||
if (this.state.masterPushRule) {
|
||||
masterPushRuleDiv = (
|
||||
@ -710,7 +733,7 @@ module.exports = React.createClass({
|
||||
ref="enableNotifications"
|
||||
type="checkbox"
|
||||
checked={ !this.state.masterPushRule.enabled }
|
||||
onChange={ this.onEnableNotificationsChange }
|
||||
onChange={ this.onEnableNotificationsChange }
|
||||
/>
|
||||
</div>
|
||||
<div className="mx_UserNotifSettings_labelCell">
|
||||
@ -824,7 +847,7 @@ module.exports = React.createClass({
|
||||
<input id="enableDesktopNotifications"
|
||||
ref="enableDesktopNotifications"
|
||||
type="checkbox"
|
||||
checked={ UserSettingsStore.getEnableNotifications() }
|
||||
checked={ SettingsStore.getValue("notificationsEnabled") }
|
||||
onChange={ this.onEnableDesktopNotificationsChange } />
|
||||
</div>
|
||||
<div className="mx_UserNotifSettings_labelCell">
|
||||
@ -839,7 +862,7 @@ module.exports = React.createClass({
|
||||
<input id="enableDesktopNotificationBody"
|
||||
ref="enableDesktopNotificationBody"
|
||||
type="checkbox"
|
||||
checked={ UserSettingsStore.getEnableNotificationBody() }
|
||||
checked={ SettingsStore.getValue("notificationBodyEnabled") }
|
||||
onChange={ this.onEnableDesktopNotificationBodyChange } />
|
||||
</div>
|
||||
<div className="mx_UserNotifSettings_labelCell">
|
||||
@ -854,11 +877,8 @@ module.exports = React.createClass({
|
||||
<input id="enableDesktopAudioNotifications"
|
||||
ref="enableDesktopAudioNotifications"
|
||||
type="checkbox"
|
||||
checked={ UserSettingsStore.getEnableAudioNotifications() }
|
||||
onChange={ (e) => {
|
||||
UserSettingsStore.setEnableAudioNotifications(e.target.checked);
|
||||
this.forceUpdate();
|
||||
}} />
|
||||
checked={ SettingsStore.getValue("audioNotificationsEnabled") }
|
||||
onChange={ this.onEnableAudioNotificationsChange } />
|
||||
</div>
|
||||
<div className="mx_UserNotifSettings_labelCell">
|
||||
<label htmlFor="enableDesktopAudioNotifications">
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
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.
|
||||
|
@ -68,9 +68,10 @@
|
||||
"What's New": "What's New",
|
||||
"Update": "Update",
|
||||
"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.",
|
||||
"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",
|
||||
"Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).",
|
||||
"Checking for an update...": "Checking for an update...",
|
||||
@ -98,18 +99,19 @@
|
||||
"Unavailable": "Unavailable",
|
||||
"Changelog": "Changelog",
|
||||
"Back": "Back",
|
||||
"Send Custom Event": "Send Custom Event",
|
||||
"You must specify an event type!": "You must specify an event type!",
|
||||
"Event sent!": "Event sent!",
|
||||
"Failed to send custom event.": "Failed to send custom event.",
|
||||
"Event Type": "Event Type",
|
||||
"Event Content": "Event Content",
|
||||
"State Key": "State Key",
|
||||
"Edit": "Edit",
|
||||
"Filter results": "Filter results",
|
||||
"Send Custom Event": "Send Custom Event",
|
||||
"Event Content": "Event Content",
|
||||
"Send Account Data": "Send Account Data",
|
||||
"Explore Account Data": "Explore Account Data",
|
||||
"Filter results": "Filter results",
|
||||
"Explore Room State": "Explore Room State",
|
||||
"Edit": "Edit",
|
||||
"Explore Account Data": "Explore Account Data",
|
||||
"Toolbox": "Toolbox",
|
||||
"Developer Tools": "Developer Tools",
|
||||
"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!",
|
||||
@ -147,8 +149,8 @@
|
||||
"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.",
|
||||
"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.",
|
||||
"<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.",
|
||||
"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.",
|
||||
"<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!",
|
||||
"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",
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
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.
|
||||
@ -23,12 +24,7 @@ html {
|
||||
}
|
||||
|
||||
body {
|
||||
/* 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;
|
||||
font-family: $font-family;
|
||||
font-size: 15px;
|
||||
background-color: $primary-bg-color;
|
||||
color: $primary-fg-color;
|
||||
@ -73,7 +69,7 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
||||
|
||||
/* Required by Firefox */
|
||||
textarea {
|
||||
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
|
||||
font-family: $font-family;
|
||||
}
|
||||
|
||||
/* Prevent ugly dotted highlight around selected elements in Firefox */
|
||||
@ -123,6 +119,23 @@ textarea {
|
||||
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 {
|
||||
position: fixed;
|
||||
z-index: 4000;
|
||||
@ -210,24 +223,19 @@ textarea {
|
||||
}
|
||||
|
||||
.mx_Dialog button, .mx_Dialog input[type="submit"] {
|
||||
border: 0px;
|
||||
height: 36px;
|
||||
border-radius: 40px;
|
||||
border: solid 1px $accent-color;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
|
||||
@mixin mx_DialogButton;
|
||||
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;
|
||||
|
||||
/* align images in buttons (eg spinners) */
|
||||
vertical-align: middle;
|
||||
// flip colours for the secondary ones
|
||||
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 {
|
||||
@ -292,26 +300,18 @@ textarea {
|
||||
color: $selection-fg-color;
|
||||
}
|
||||
|
||||
/** green button with rounded corners */
|
||||
.mx_textButton {
|
||||
color: $accent-fg-color;
|
||||
background-color: $accent-color;
|
||||
border-radius: 17px;
|
||||
text-align: center;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
cursor: pointer;
|
||||
display: inline;
|
||||
@mixin mx_DialogButton_small;
|
||||
}
|
||||
|
||||
.mx_textButton:hover {
|
||||
@mixin mx_DialogButton_hover;
|
||||
}
|
||||
|
||||
.mx_button_row {
|
||||
margin-top: 69px;
|
||||
}
|
||||
|
||||
.changelog_text {
|
||||
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
|
||||
}
|
||||
|
||||
.mx_Beta {
|
||||
color: red;
|
||||
margin-right: 10px;
|
||||
@ -332,3 +332,30 @@ textarea {
|
||||
border: 1px solid gray;
|
||||
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;
|
||||
}
|
||||
|
@ -11,10 +11,12 @@
|
||||
@import "./matrix-react-sdk/structures/_RoomStatusBar.scss";
|
||||
@import "./matrix-react-sdk/structures/_RoomView.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/_UserSettings.scss";
|
||||
@import "./matrix-react-sdk/structures/login/_Login.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/_ChatCreateOrReuseChatDialog.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/_RoleButton.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/_GroupUserSettings.scss";
|
||||
@import "./matrix-react-sdk/views/login/_InteractiveAuthEntryComponents.scss";
|
||||
@import "./matrix-react-sdk/views/login/_ServerConfig.scss";
|
||||
@import "./matrix-react-sdk/views/messages/_MEmoteBody.scss";
|
||||
@ -80,6 +84,7 @@
|
||||
@import "./vector-web/structures/_RoomSubList.scss";
|
||||
@import "./vector-web/structures/_ViewSource.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/dialogs/_ChangelogDialog.scss";
|
||||
@import "./vector-web/views/dialogs/_DevtoolsDialog.scss";
|
||||
|
@ -94,6 +94,60 @@ limitations under the License.
|
||||
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 {
|
||||
padding: 3px 6px 3px 6px;
|
||||
cursor: pointer;
|
||||
|
@ -122,13 +122,13 @@ limitations under the License.
|
||||
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_desc {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.mx_GroupTile_profile h3.mx_GroupTile_name {
|
||||
.mx_GroupTile_profile .mx_GroupTile_name {
|
||||
margin: 0px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ limitations under the License.
|
||||
padding-top: 24px;
|
||||
padding-bottom: 22px;
|
||||
|
||||
border-bottom: 1px solid $panel-divider-color;
|
||||
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@ -38,7 +40,7 @@ limitations under the License.
|
||||
.mx_SearchBox_search {
|
||||
flex: 1 1 auto;
|
||||
width: 0px;
|
||||
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
|
||||
font-family: $font-family;
|
||||
font-size: 12px;
|
||||
margin-top: -2px;
|
||||
height: 24px;
|
||||
|
@ -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;
|
||||
}
|
@ -64,30 +64,13 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_UserSettings_button {
|
||||
@mixin mx_DialogButton;
|
||||
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;
|
||||
padding: 7px;
|
||||
padding-left: 1.5em;
|
||||
padding-right: 1.5em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_UserSettings_button.mx_UserSettings_buttonSmall {
|
||||
height: 36px;
|
||||
padding: 4px;
|
||||
padding-left: 7px;
|
||||
padding-right: 7px;
|
||||
font-size: 12px;
|
||||
margin-right: 5px;
|
||||
line-height: 12px;
|
||||
.mx_UserSettings_button:hover {
|
||||
@mixin mx_DialogButton_hover;
|
||||
}
|
||||
|
||||
.mx_UserSettings_button.danger {
|
||||
|
@ -26,7 +26,6 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_Login h2 {
|
||||
color: $primary-fg-color;
|
||||
font-weight: 300;
|
||||
margin-top: 32px;
|
||||
margin-bottom: 20px;
|
||||
@ -80,15 +79,14 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_Login_submit {
|
||||
@mixin mx_DialogButton;
|
||||
width: 100%;
|
||||
margin-top: 35px;
|
||||
margin-bottom: 24px;
|
||||
width: 100%;
|
||||
border-radius: 40px;
|
||||
height: 40px;
|
||||
border: 0px;
|
||||
background-color: $accent-color;
|
||||
font-size: 15px;
|
||||
color: $accent-fg-color;
|
||||
}
|
||||
|
||||
.mx_Login_submit:hover {
|
||||
@mixin mx_DialogButton_hover;
|
||||
}
|
||||
|
||||
.mx_Login_submit:disabled {
|
||||
@ -137,8 +135,7 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_Login_forgot {
|
||||
font-size: 13px;
|
||||
opacity: 0.8;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.mx_Login_forgot:link {
|
||||
@ -224,7 +221,6 @@ limitations under the License.
|
||||
height: 16px;
|
||||
flex-shrink: 1;
|
||||
min-width: 0px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.mx_Login_phoneNumberField {
|
||||
|
@ -31,5 +31,5 @@ limitations under the License.
|
||||
.mx_BaseAvatar_image {
|
||||
border-radius: 40px;
|
||||
vertical-align: top;
|
||||
background-color: #fff;
|
||||
background-color: $avatar-bg-color;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -28,7 +28,7 @@ limitations under the License.
|
||||
{
|
||||
height: 26px;
|
||||
font-size: 14px;
|
||||
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
|
||||
font-family: $font-family;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
margin: 0 !important;
|
||||
|
@ -34,7 +34,7 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_ConfirmUserActionDialog_reasonField {
|
||||
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
|
||||
font-family: $font-family;
|
||||
font-size: 14px;
|
||||
color: $primary-fg-color;
|
||||
background-color: $primary-bg-color;
|
||||
|
@ -21,19 +21,7 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_EncryptedEventDialog .mx_MemberDeviceInfo_textButton {
|
||||
border: 0px;
|
||||
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;
|
||||
@mixin mx_DialogButton;
|
||||
background-color: $primary-bg-color;
|
||||
color: $accent-color;
|
||||
}
|
@ -43,22 +43,9 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_UnknownDeviceDialog .mx_MemberDeviceInfo_textButton {
|
||||
border: 0px;
|
||||
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;
|
||||
@mixin mx_DialogButton_small;
|
||||
background-color: $primary-bg-color;
|
||||
color: $accent-color;
|
||||
}
|
||||
|
||||
.mx_UnknownDeviceDialog .mx_UnknownDeviceDialog_deviceList li {
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -14,8 +14,9 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// .mx_AppsDrawer {
|
||||
// }
|
||||
.mx_AppsDrawer {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.mx_AppsContainer {
|
||||
display: flex;
|
||||
@ -75,17 +76,32 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_AppTileMenuBar {
|
||||
// height: 15px;
|
||||
margin: 0;
|
||||
padding: 2px 10px;
|
||||
// background-color: $e2e-verified-color;
|
||||
border-bottom: 1px solid $primary-hairline-color;
|
||||
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 {
|
||||
float: right;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mx_AppTileMenuBarWidget {
|
||||
// pointer-events: none;
|
||||
cursor: pointer;
|
||||
@ -101,7 +117,7 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_AppTileMenuBarWidget:hover {
|
||||
border: 1px solid $primary-hairline-color;
|
||||
border: 1px solid $primary-fg-color;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
@ -193,8 +209,12 @@ form.mx_Custom_Widget_Form div {
|
||||
|
||||
.mx_AppPermissionWarning {
|
||||
text-align: center;
|
||||
padding: 30px 0;
|
||||
background-color: $primary-bg-color;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mx_AppPermissionWarningImage {
|
||||
|
@ -156,18 +156,17 @@ limitations under the License.
|
||||
.mx_EventTile_redacted .mx_EventTile_line .mx_UnknownBody {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
background-image: $event-redacted-img;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.mx_EventTile.mx_EventTile_redacted .mx_EventTile_line {
|
||||
/*
|
||||
Prevent changing colour of the background because
|
||||
$event-redacted-img matches $primary-bg-color
|
||||
*/
|
||||
background-color: initial !important;
|
||||
height: 22px;
|
||||
width: 250px;
|
||||
border-radius: 11px;
|
||||
background: repeating-linear-gradient(
|
||||
-45deg,
|
||||
$event-redacted-fg-color,
|
||||
$event-redacted-fg-color 3px,
|
||||
transparent 3px,
|
||||
transparent 6px
|
||||
);
|
||||
box-shadow: 0px 0px 3px $event-redacted-border-color inset;
|
||||
}
|
||||
|
||||
.mx_EventTile_highlight,
|
||||
|
@ -26,19 +26,15 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_MemberDeviceInfo_textButton {
|
||||
color: $accent-fg-color;
|
||||
background-color: $accent-color;
|
||||
border-radius: 17px;
|
||||
text-align: center;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
border: 0px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
@mixin mx_DialogButton_small;
|
||||
margin: 2px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.mx_MemberDeviceInfo_textButton:hover {
|
||||
@mixin mx_DialogButton_hover;
|
||||
}
|
||||
|
||||
.mx_MemberDeviceInfo_deviceId {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ limitations under the License.
|
||||
.mx_MemberList_query,
|
||||
.mx_GroupMemberList_query,
|
||||
.mx_GroupRoomList_query {
|
||||
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
|
||||
font-family: $font-family;
|
||||
border-radius: 3px;
|
||||
border: 1px solid $input-border-color;
|
||||
padding: 9px;
|
||||
|
@ -55,9 +55,11 @@ limitations under the License.
|
||||
.mx_MessageComposer_noperm_error {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
color: $greyed-fg-color;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_input_wrapper {
|
||||
@ -135,7 +137,7 @@ limitations under the License.
|
||||
max-height: 120px;
|
||||
overflow: auto;
|
||||
/* 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 */
|
||||
@ -172,6 +174,8 @@ limitations under the License.
|
||||
.mx_MessageComposer_formatting {
|
||||
cursor: pointer;
|
||||
margin: 0 11px;
|
||||
width: 24px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_formatbar_wrapper {
|
||||
|
@ -42,22 +42,14 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_RoomHeader_textButton {
|
||||
height: 36px;
|
||||
background-color: $accent-color;
|
||||
border-radius: 36px;
|
||||
@mixin mx_DialogButton;
|
||||
margin-right: 8px;
|
||||
color: $accent-fg-color;
|
||||
line-height: 34px;
|
||||
margin-top: -2px;
|
||||
text-align: center;
|
||||
margin-top: -5px;
|
||||
order: 2;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/*
|
||||
flex: 0 0 90px;
|
||||
*/
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
.mx_RoomHeader_textButton:hover {
|
||||
@mixin mx_DialogButton_hover;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_textButton_danger {
|
||||
|
@ -50,10 +50,11 @@ limitations under the License.
|
||||
color: $primary-fg-color;
|
||||
background-color: $droptarget-bg-color;
|
||||
border-radius: 4px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.mx_RoomList_emptySubListTip .mx_RoleButton {
|
||||
vertical-align: -3px;
|
||||
vertical-align: -2px;
|
||||
}
|
||||
|
||||
.mx_RoomList_headerButtons {
|
||||
|
@ -22,18 +22,16 @@ limitations under the License.
|
||||
|
||||
.mx_RoomSettings_leaveButton,
|
||||
.mx_RoomSettings_unbanButton {
|
||||
@mixin mx_DialogButton;
|
||||
position: relative;
|
||||
height: 36px;
|
||||
background-color: $accent-color;
|
||||
border-radius: 36px;
|
||||
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 {
|
||||
position: relative;
|
||||
cursor: not-allowed;
|
||||
|
@ -21,7 +21,7 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_SearchableEntityList_query {
|
||||
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
|
||||
font-family: $font-family;
|
||||
border-radius: 3px;
|
||||
border: 1px solid $input-border-color;
|
||||
padding: 9px;
|
||||
|
@ -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)
|
||||
$primary-fg-color: #454545;
|
||||
@ -34,6 +40,7 @@ $preview-bar-bg-color: #f7f7f7;
|
||||
|
||||
// left-panel style muted accent color
|
||||
$secondary-accent-color: #eaf5f0;
|
||||
$tertiary-accent-color: #d3efe1;
|
||||
|
||||
// used by RoomDirectory permissions
|
||||
$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);
|
||||
|
||||
// used by AddressSelector
|
||||
$selected-color: #eaf5f0;
|
||||
$selected-color: $secondary-accent-color;
|
||||
|
||||
// selected for hoverover & selected event tiles
|
||||
$event-selected-color: #f7f7f7;
|
||||
@ -65,6 +72,7 @@ $menu-border-color: rgba(187, 187, 187, 0.5);
|
||||
$menu-bg-color: #f6f6f6;
|
||||
|
||||
$avatar-initial-color: #ffffff;
|
||||
$avatar-bg-color: #ffffff;
|
||||
|
||||
$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);
|
||||
|
||||
$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 redaction
|
||||
$event-redacted-img: url('../../img/redacted.jpg');
|
||||
$event-redacted-fg-color: #e2e2e2;
|
||||
$event-redacted-border-color: #cccccc;
|
||||
|
||||
// event timestamp
|
||||
$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-warning-color: #ba6363;
|
||||
|
||||
// presence
|
||||
$presence-online: #60de00;
|
||||
$presence-unavailable: #deb800;
|
||||
$presence-offline: #b7b7b7;
|
||||
|
||||
/*** ImageView ***/
|
||||
$lightbox-bg-color: #454545;
|
||||
$lightbox-fg-color: #ffffff;
|
||||
@ -127,3 +148,32 @@ $lightbox-border-color: #ffffff;
|
||||
|
||||
// unused?
|
||||
$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;
|
||||
}
|
||||
|
@ -29,6 +29,18 @@ $preview-bar-bg-color: #333;
|
||||
|
||||
// left-panel style muted accent 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
|
||||
$plinth-bg-color: #474747;
|
||||
@ -60,6 +72,7 @@ $menu-border-color: rgba(187, 187, 187, 0.5);
|
||||
$menu-bg-color: #373737;
|
||||
|
||||
$avatar-initial-color: #2d2d2d;
|
||||
$avatar-bg-color: #ffffff;
|
||||
|
||||
$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);
|
||||
|
||||
$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 redaction
|
||||
$event-redacted-img: url('../../img/redacted-dark.jpg');
|
||||
$event-redacted-fg-color: #606060;
|
||||
$event-redacted-border-color: #000000;
|
||||
|
||||
// event timestamp
|
||||
$event-timestamp-color: #acacac;
|
||||
@ -122,6 +143,25 @@ $lightbox-border-color: #ffffff;
|
||||
// unused?
|
||||
$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
|
||||
// better match the theme. Typically applied to dark grey 'off' buttons or
|
||||
// light grey 'on' buttons.
|
||||
|
@ -44,12 +44,13 @@ limitations under the License.
|
||||
|
||||
.mx_LeftPanel.collapsed .mx_BottomLeftMenu {
|
||||
flex: 0 0 160px;
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
|
||||
.mx_LeftPanel .mx_BottomLeftMenu {
|
||||
order: 3;
|
||||
|
||||
border-top: 1px solid rgba(118, 207, 166, 0.2);
|
||||
border-top: 1px solid $panel-divider-color;
|
||||
margin-left: 16px; /* gutter */
|
||||
margin-right: 16px; /* gutter */
|
||||
flex: 0 0 60px;
|
||||
@ -77,6 +78,7 @@ limitations under the License.
|
||||
.mx_BottomLeftMenu_options .mx_RoleButton {
|
||||
margin-left: 0px;
|
||||
margin-right: 10px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.mx_BottomLeftMenu_options .mx_BottomLeftMenu_settings {
|
||||
|
@ -33,14 +33,13 @@ limitations under the License.
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
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-right: 16px; /* gutter */
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
cursor: pointer;
|
||||
background-color: $roomsublist-label-bg-color;
|
||||
border-top: solid 2px $secondary-accent-color;
|
||||
background-color: $secondary-accent-color;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_label.mx_RoomSubList_fixed {
|
||||
@ -129,7 +128,7 @@ limitations under the License.
|
||||
height: 0;
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
border-top: 6px solid $accent-color;
|
||||
border-top: 6px solid $roomsublist-chevron-color;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_chevronUp {
|
||||
@ -137,14 +136,14 @@ limitations under the License.
|
||||
height: 0;
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
border-bottom: 6px solid $accent-color;
|
||||
border-bottom: 6px solid $roomsublist-chevron-color;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_chevronRight {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 5px solid transparent;
|
||||
border-left: 6px solid $accent-color;
|
||||
border-left: 6px solid $roomsublist-chevron-color;
|
||||
border-bottom: 5px solid transparent;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
@ -56,3 +56,7 @@ limitations under the License.
|
||||
.mx_MatrixToolbar_action {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.mx_MatrixToolbar_changelog {
|
||||
white-space: pre;
|
||||
}
|
@ -1,18 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<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: sketchtool 39 (31667) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>F69CBF5F-0BEC-47E8-B1DF-125D6376C0C9</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="Screens-revised" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="02_x-Chat-text-input-" transform="translate(-829.000000, -729.000000)">
|
||||
<g id="button_text_formatting" transform="translate(829.000000, 729.000000)">
|
||||
<rect id="Rectangle-111" fill="#F6F6F6" x="0" y="0" width="24" height="18" rx="9"></rect>
|
||||
<text id="Aa" font-family="OpenSans-Bold, Open Sans" font-size="12" font-weight="bold" letter-spacing="-1.20000005" fill="#4A4A4A">
|
||||
<tspan x="5" y="13">A</tspan>
|
||||
<tspan x="12.0792968" y="13" font-family="OpenSans-Italic, Open Sans" font-style="italic" font-weight="normal">a</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 18" style="enable-background:new 0 0 24 18;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#F6F6F6;}
|
||||
.st1{enable-background:new ;}
|
||||
.st2{fill:#4A4A4A;}
|
||||
</style>
|
||||
<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"/>
|
||||
<g class="st1">
|
||||
<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
|
||||
C9,6.2,8.6,7.5,8,9.4H10.3z"/>
|
||||
</g>
|
||||
<g class="st1">
|
||||
<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
|
||||
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>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
15
src/skins/vector/img/camera_green.svg
Normal 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 |
10
src/skins/vector/img/cancel_green.svg
Normal 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 |
@ -1,13 +1,11 @@
|
||||
<?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">
|
||||
<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">
|
||||
<g>
|
||||
|
||||
<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 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
|
||||
C482.616,119.952,483.445,100.116,471.723,88.393z"/>
|
||||
<polygon points="64.021,363.252 32,480 148.737,447.979 "/>
|
||||
</g>
|
||||
width="512px" height="512px" viewBox="0 0 512 512" xml:space="preserve">
|
||||
<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"/>
|
||||
<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
|
||||
C514.486,100.918,515.434,78.271,502.05,64.887z"/>
|
||||
<polygon fill="#000000" points="36.56,378.704 0,512 133.283,475.439"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 876 B After Width: | Height: | Size: 780 B |
11
src/skins/vector/img/edit_green.svg
Normal 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 |
@ -1,10 +1,19 @@
|
||||
<?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="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>
|
||||
<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
|
||||
V128.225H85.633V454.889z M468.958,43.042H362.479L326.828,0.45H185.173l-35.652,42.591H43.042v42.592h425.916V43.042z"/>
|
||||
<g>
|
||||
<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>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 738 B After Width: | Height: | Size: 1.6 KiB |
BIN
src/skins/vector/img/logos/riot-im-logo-1.png
Normal file
After Width: | Height: | Size: 14 KiB |
9
src/skins/vector/img/maximize.svg
Normal 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 |
8
src/skins/vector/img/minimize.svg
Normal 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 |
34
src/skins/vector/img/warning_yellow.svg
Normal 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 |
232
src/skins/vector/themes/status/css/_StatusLogin.scss
Normal 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;
|
||||
}
|
||||
|
||||
}
|
285
src/skins/vector/themes/status/css/_status.scss
Normal 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;
|
||||
}
|
4
src/skins/vector/themes/status/css/status.scss
Normal file
@ -0,0 +1,4 @@
|
||||
@import "../../../css/themes/_base.scss";
|
||||
@import "_status.scss";
|
||||
@import "../../../css/_components.scss";
|
||||
@import "_StatusLogin.scss";
|
1
src/skins/vector/themes/status/fonts/README
Normal file
@ -0,0 +1 @@
|
||||
We link out to status.im for fonts, although ideally we'd put them here.
|
BIN
src/skins/vector/themes/status/img/a.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
src/skins/vector/themes/status/img/d.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
1
src/skins/vector/themes/status/img/dot.svg
Normal 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 |
BIN
src/skins/vector/themes/status/img/g.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
src/skins/vector/themes/status/img/i.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
16
src/skins/vector/themes/status/img/logo.svg
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
src/skins/vector/themes/status/img/n.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
@ -20,15 +20,14 @@
|
||||
<meta name="msapplication-TileImage" content="vector-icons/mstile-144x144.png">
|
||||
<meta name="msapplication-config" content="vector-icons/browserconfig.xml">
|
||||
<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++) {
|
||||
var file = htmlWebpackPlugin.files.css[i];
|
||||
var match = file.match(/^bundles\/.*?\/theme-(.*)\.css$/);
|
||||
if (match) {
|
||||
var title = match[1].charAt(0).toUpperCase() + match[1].slice(1);
|
||||
var light = match[1] == 'light';
|
||||
%>
|
||||
<link rel="<%= light ? '' : 'alternate ' %>stylesheet" title="<%= title %>"
|
||||
href="<%= file %>">
|
||||
<link rel="stylesheet" disabled="disabled" title="<%= title %>" href="<%= file %>">
|
||||
<% } else { %>
|
||||
<link rel="stylesheet" href="<%= file %>">
|
||||
<% }
|
||||
@ -73,5 +72,7 @@
|
||||
<source src="media/busy.mp3" type="audio/mpeg" />
|
||||
</audio>
|
||||
<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>
|
||||
</html>
|
||||
|
@ -67,7 +67,6 @@ sdk.loadSkin(require('../component-index'));
|
||||
var VectorConferenceHandler = require('../VectorConferenceHandler');
|
||||
import Promise from 'bluebird';
|
||||
var request = require('browser-request');
|
||||
import * as UserSettingsStore from 'matrix-react-sdk/lib/UserSettingsStore';
|
||||
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
|
||||
import { _t } from 'matrix-react-sdk/lib/languageHandler';
|
||||
@ -78,6 +77,9 @@ import {parseQs, parseQsFromFragment} from './url_utils';
|
||||
import Platform from './platform';
|
||||
|
||||
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;
|
||||
|
||||
@ -244,25 +246,6 @@ async function loadApp() {
|
||||
// set the platform for react sdk (our Platform object automatically picks the right one)
|
||||
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
|
||||
// form "config.$domain.json" and if that fails, fall back to config.json.
|
||||
let configJson;
|
||||
@ -280,6 +263,70 @@ async function loadApp() {
|
||||
} catch (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')) {
|
||||
console.log('User has previously accepted risks in using an unsupported browser');
|
||||
@ -304,7 +351,7 @@ async function loadApp() {
|
||||
config={configJson}
|
||||
realQueryParams={params}
|
||||
startingFragmentQueryParams={fragparts.params}
|
||||
enableGuest={true}
|
||||
enableGuest={!configJson.disable_guests}
|
||||
onTokenLoginCompleted={onTokenLoginCompleted}
|
||||
initialScreenAfterLogin={getScreenFromLocation(window.location)}
|
||||
defaultDeviceDisplayName={platform.getDefaultDeviceDisplayName()}
|
||||
@ -328,7 +375,7 @@ async function loadApp() {
|
||||
}
|
||||
|
||||
async function loadLanguage() {
|
||||
const prefLang = UserSettingsStore.getLocalSetting('language');
|
||||
const prefLang = SettingsStore.getValue("language", null, /*excludeDefault=*/true);
|
||||
let langs = [];
|
||||
|
||||
if (!prefLang) {
|
||||
@ -340,6 +387,7 @@ async function loadLanguage() {
|
||||
}
|
||||
try {
|
||||
await languageHandler.setLanguage(langs);
|
||||
document.documentElement.setAttribute("lang", languageHandler.getCurrentLanguage());
|
||||
} catch (e) {
|
||||
console.error("Unable to set language", e);
|
||||
}
|
||||
|
@ -546,6 +546,8 @@ describe('loading:', function () {
|
||||
);
|
||||
});
|
||||
|
||||
/*
|
||||
// ILAG renders this obsolete. I think.
|
||||
it('should allow us to return to the app', function() {
|
||||
const login = ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('structures.login.Login')
|
||||
@ -568,6 +570,7 @@ describe('loading:', function () {
|
||||
matrixChat, sdk.getComponent('structures.HomePage'));
|
||||
});
|
||||
});
|
||||
*/
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -20,6 +20,7 @@ module.exports = {
|
||||
// CSS themes
|
||||
"theme-light": "./src/skins/vector/css/themes/light.scss",
|
||||
"theme-dark": "./src/skins/vector/css/themes/dark.scss",
|
||||
"theme-status": "./src/skins/vector/themes/status/css/status.scss",
|
||||
},
|
||||
module: {
|
||||
preLoaders: [
|
||||
|