Merge branch 'release-v0.9.8'
This commit is contained in:
commit
a12d7a2b66
72 changed files with 1531 additions and 794 deletions
23
.editorconfig
Normal file
23
.editorconfig
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2017 Aviral Dasgupta
|
||||
#
|
||||
# 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.
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset=utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
|
@ -10,3 +10,6 @@ include:
|
|||
|
||||
* Florent VIOLLEAU (https://github.com/floviolleau) <floviolleau at gmail dot com>
|
||||
Improve README.md for a better understanding of installation instructions
|
||||
|
||||
* Michael Telatynski (https://github.com/t3chguy)
|
||||
Improved consistency of inverted elements in dark theme across browsers
|
||||
|
|
119
CHANGELOG.md
119
CHANGELOG.md
|
@ -1,3 +1,122 @@
|
|||
Changes in [0.9.8](https://github.com/vector-im/riot-web/releases/tag/v0.9.8) (2017-04-12)
|
||||
==========================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.8-rc.3...v0.9.8)
|
||||
|
||||
* No changes
|
||||
|
||||
Changes in [0.9.8-rc.3](https://github.com/vector-im/riot-web/releases/tag/v0.9.8-rc.3) (2017-04-11)
|
||||
====================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.8-rc.2...v0.9.8-rc.3)
|
||||
|
||||
* Make the clear cache button work on desktop
|
||||
[\#3598](https://github.com/vector-im/riot-web/pull/3598)
|
||||
|
||||
Changes in [0.9.8-rc.2](https://github.com/vector-im/riot-web/releases/tag/v0.9.8-rc.2) (2017-04-10)
|
||||
====================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.8-rc.1...v0.9.8-rc.2)
|
||||
|
||||
* Redacted events bg: black lozenge -> torn paper
|
||||
[\#3596](https://github.com/vector-im/riot-web/pull/3596)
|
||||
* Add 'app' parameter to rageshake report
|
||||
[\#3594](https://github.com/vector-im/riot-web/pull/3594)
|
||||
|
||||
Changes in [0.9.8-rc.1](https://github.com/vector-im/riot-web/releases/tag/v0.9.8-rc.1) (2017-04-07)
|
||||
====================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.7...v0.9.8-rc.1)
|
||||
|
||||
* Add support for indexeddb sync in webworker
|
||||
[\#3578](https://github.com/vector-im/riot-web/pull/3578)
|
||||
* Add CSS to make Emote sender cursor : pointer
|
||||
[\#3574](https://github.com/vector-im/riot-web/pull/3574)
|
||||
* Remove rageshake server
|
||||
[\#3565](https://github.com/vector-im/riot-web/pull/3565)
|
||||
* Adjust CSS for matrix-org/matrix-react-sdk#789
|
||||
[\#3566](https://github.com/vector-im/riot-web/pull/3566)
|
||||
* Fix tests to reflect recent changes
|
||||
[\#3537](https://github.com/vector-im/riot-web/pull/3537)
|
||||
* Do not assume getTs will return comparable integer
|
||||
[\#3536](https://github.com/vector-im/riot-web/pull/3536)
|
||||
* Rename ReactPerf to Perf
|
||||
[\#3535](https://github.com/vector-im/riot-web/pull/3535)
|
||||
* Don't show phone number as target for email notifs
|
||||
[\#3530](https://github.com/vector-im/riot-web/pull/3530)
|
||||
* Fix people section again
|
||||
[\#3458](https://github.com/vector-im/riot-web/pull/3458)
|
||||
* dark theme invert inconsistent across browsers
|
||||
[\#3479](https://github.com/vector-im/riot-web/pull/3479)
|
||||
* CSS for adding phone number in UserSettings
|
||||
[\#3451](https://github.com/vector-im/riot-web/pull/3451)
|
||||
* Support for phone number registration/signin, mk2
|
||||
[\#3426](https://github.com/vector-im/riot-web/pull/3426)
|
||||
* Confirm redactions with a dialog
|
||||
[\#3470](https://github.com/vector-im/riot-web/pull/3470)
|
||||
* Better CSS for redactions
|
||||
[\#3453](https://github.com/vector-im/riot-web/pull/3453)
|
||||
* Fix the people section
|
||||
[\#3448](https://github.com/vector-im/riot-web/pull/3448)
|
||||
* Merge the two RoomTile context menus into one
|
||||
[\#3395](https://github.com/vector-im/riot-web/pull/3395)
|
||||
* Refactor screen set after login
|
||||
[\#3385](https://github.com/vector-im/riot-web/pull/3385)
|
||||
* CSS for redacted EventTiles
|
||||
[\#3379](https://github.com/vector-im/riot-web/pull/3379)
|
||||
* Height:100% for welcome pages on Safari
|
||||
[\#3340](https://github.com/vector-im/riot-web/pull/3340)
|
||||
* `view_room` dispatch from `onClick` RoomTile
|
||||
[\#3376](https://github.com/vector-im/riot-web/pull/3376)
|
||||
* Hide statusAreaBox_line entirely when inCall
|
||||
[\#3350](https://github.com/vector-im/riot-web/pull/3350)
|
||||
* Set padding-bottom: 0px for .mx_Dialog spinner
|
||||
[\#3351](https://github.com/vector-im/riot-web/pull/3351)
|
||||
* Support InteractiveAuth based registration
|
||||
[\#3333](https://github.com/vector-im/riot-web/pull/3333)
|
||||
* Expose notification option for username/MXID
|
||||
[\#3334](https://github.com/vector-im/riot-web/pull/3334)
|
||||
* Float the toggle in the top right of MELS
|
||||
[\#3190](https://github.com/vector-im/riot-web/pull/3190)
|
||||
* More aggressive rageshake log culling
|
||||
[\#3311](https://github.com/vector-im/riot-web/pull/3311)
|
||||
* Don't overflow directory network options
|
||||
[\#3282](https://github.com/vector-im/riot-web/pull/3282)
|
||||
* CSS for ban / kick reason prompt
|
||||
[\#3250](https://github.com/vector-im/riot-web/pull/3250)
|
||||
* Allow forgetting rooms you're banned from
|
||||
[\#3246](https://github.com/vector-im/riot-web/pull/3246)
|
||||
* Fix icon paths in manifest
|
||||
[\#3245](https://github.com/vector-im/riot-web/pull/3245)
|
||||
* Fix broken tests caused by adding IndexedDB support
|
||||
[\#3242](https://github.com/vector-im/riot-web/pull/3242)
|
||||
* CSS for un-ban button in RoomSettings
|
||||
[\#3227](https://github.com/vector-im/riot-web/pull/3227)
|
||||
* Remove z-index property on avatar initials
|
||||
[\#3239](https://github.com/vector-im/riot-web/pull/3239)
|
||||
* Reposition certain icons in the status bar
|
||||
[\#3233](https://github.com/vector-im/riot-web/pull/3233)
|
||||
* CSS for kick/ban confirmation dialog
|
||||
[\#3224](https://github.com/vector-im/riot-web/pull/3224)
|
||||
* Style for split-out interactive auth
|
||||
[\#3217](https://github.com/vector-im/riot-web/pull/3217)
|
||||
* Use the teamToken threaded through from react sdk
|
||||
[\#3196](https://github.com/vector-im/riot-web/pull/3196)
|
||||
* rageshake: Add file server with basic auth
|
||||
[\#3169](https://github.com/vector-im/riot-web/pull/3169)
|
||||
* Fix bug with home icon not appearing when logged in as team member
|
||||
[\#3162](https://github.com/vector-im/riot-web/pull/3162)
|
||||
* Add ISSUE_TEMPLATE
|
||||
[\#2836](https://github.com/vector-im/riot-web/pull/2836)
|
||||
* Store bug reports in separate directories
|
||||
[\#3150](https://github.com/vector-im/riot-web/pull/3150)
|
||||
* Quick and dirty support for custom welcome pages.
|
||||
[\#2575](https://github.com/vector-im/riot-web/pull/2575)
|
||||
* RTS Welcome Pages
|
||||
[\#3103](https://github.com/vector-im/riot-web/pull/3103)
|
||||
* rageshake: Abide by Go standards
|
||||
[\#3149](https://github.com/vector-im/riot-web/pull/3149)
|
||||
* Bug report server script
|
||||
[\#3072](https://github.com/vector-im/riot-web/pull/3072)
|
||||
* Bump olm version
|
||||
[\#3125](https://github.com/vector-im/riot-web/pull/3125)
|
||||
|
||||
Changes in [0.9.7](https://github.com/vector-im/riot-web/releases/tag/v0.9.7) (2017-02-04)
|
||||
==========================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.7-rc.3...v0.9.7)
|
||||
|
|
18
README.md
18
README.md
|
@ -21,6 +21,9 @@ released version of Riot:
|
|||
as desired. See below for details.
|
||||
1. Enter the URL into your browser and log into Riot!
|
||||
|
||||
Releases are signed by PGP, and can be checked against the public key
|
||||
at https://riot.im/packages/keys/riot-master.asc
|
||||
|
||||
Note that Chrome does not allow microphone or webcam access for sites served
|
||||
over http (except localhost), so for working VoIP you will need to serve Riot
|
||||
over https.
|
||||
|
@ -64,6 +67,18 @@ to build.
|
|||
(cd node_modules/matrix-js-sdk && npm install)
|
||||
(cd node_modules/matrix-react-sdk && npm install)
|
||||
```
|
||||
Whenever you git pull on riot-web you will also probably need to force an update
|
||||
to these dependencies - the easiest way is probably:
|
||||
```
|
||||
rm -rf node_modules/matrjx-{js,react}-sdk && npm i
|
||||
(cd node_modules/matrix-js-sdk && npm install)
|
||||
(cd node_modules/matrix-react-sdk && npm install)
|
||||
```
|
||||
However, we recommend setting up a proper development environment (see "Setting
|
||||
up a development environment" below) if you want to run your own copy of the
|
||||
`develop` branch, as it makes it much easier to keep these dependencies
|
||||
up-to-date. Or just use https://riot.im/develop - the continuous integration
|
||||
release of the develop branch.
|
||||
1. Configure the app by copying `config.sample.json` to `config.json` and
|
||||
modifying it (see below for details)
|
||||
1. `npm run dist` to build a tarball to deploy. Untaring this file will give
|
||||
|
@ -114,7 +129,8 @@ built it yourself.
|
|||
|
||||
To run as a desktop app:
|
||||
|
||||
1. Follow the instructions in 'Building From Source' above
|
||||
1. Follow the instructions in 'Building From Source' above, but run
|
||||
`npm run build` instead of `npm run dist` (since we don't need the tarball).
|
||||
2. Install electron and run it:
|
||||
|
||||
```
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"brand": "Riot",
|
||||
"integrations_ui_url": "https://scalar.vector.im/",
|
||||
"integrations_rest_url": "https://scalar.vector.im/api",
|
||||
"bug_report_endpoint_url": "https://riot.im/bugreports/submit",
|
||||
"enableLabs": true,
|
||||
"roomDirectory": {
|
||||
"servers": [
|
||||
|
|
10
package.json
10
package.json
|
@ -2,7 +2,7 @@
|
|||
"name": "riot-web",
|
||||
"productName": "Riot",
|
||||
"main": "electron/src/electron-main.js",
|
||||
"version": "0.9.7",
|
||||
"version": "0.9.8",
|
||||
"description": "A feature-rich client for Matrix.org",
|
||||
"author": "Vector Creations Ltd.",
|
||||
"repository": {
|
||||
|
@ -62,8 +62,8 @@
|
|||
"gfm.css": "^1.1.1",
|
||||
"highlight.js": "^9.0.0",
|
||||
"linkifyjs": "^2.1.3",
|
||||
"matrix-js-sdk": "0.7.5",
|
||||
"matrix-react-sdk": "0.8.6",
|
||||
"matrix-js-sdk": "0.7.6",
|
||||
"matrix-react-sdk": "0.8.7",
|
||||
"modernizr": "^3.1.0",
|
||||
"q": "^1.4.1",
|
||||
"react": "^15.4.0",
|
||||
|
@ -96,7 +96,7 @@
|
|||
"css-raw-loader": "^0.1.1",
|
||||
"electron-builder": "^11.2.4",
|
||||
"electron-builder-squirrel-windows": "^11.2.1",
|
||||
"emojione": "^2.2.3",
|
||||
"emojione": "^2.2.7",
|
||||
"eslint": "^3.14.0",
|
||||
"eslint-config-google": "^0.7.1",
|
||||
"eslint-plugin-flowtype": "^2.30.0",
|
||||
|
@ -138,7 +138,7 @@
|
|||
"build": {
|
||||
"appId": "im.riot.app",
|
||||
"category": "Network",
|
||||
"electronVersion": "1.4.14",
|
||||
"electronVersion": "1.6.2",
|
||||
"//asar=false": "https://github.com/electron-userland/electron-builder/issues/675",
|
||||
"asar": false,
|
||||
"dereference": true,
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -2,37 +2,37 @@
|
|||
"name": "Riot",
|
||||
"icons": [
|
||||
{
|
||||
"src": "\/icons\/android-chrome-36x36.png",
|
||||
"src": "android-chrome-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "\/icons\/android-chrome-48x48.png",
|
||||
"src": "android-chrome-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "\/icons\/android-chrome-72x72.png",
|
||||
"src": "android-chrome-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "\/icons\/android-chrome-96x96.png",
|
||||
"src": "android-chrome-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "\/icons\/android-chrome-144x144.png",
|
||||
"src": "android-chrome-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image\/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "\/icons\/android-chrome-192x192.png",
|
||||
"src": "android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png",
|
||||
"density": "4.0"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
set -e
|
||||
|
||||
export NVM_DIR="/home/jenkins/.nvm"
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
|
||||
nvm use 6
|
||||
|
||||
|
@ -11,13 +11,18 @@ set -x
|
|||
npm install
|
||||
|
||||
# apparently npm 3.10.3 on node 6.4.0 doesn't upgrade #develop target with npm install unless explicitly asked.
|
||||
npm install matrix-react-sdk matrix-js-sdk
|
||||
npm install matrix-react-sdk matrix-js-sdk olm
|
||||
|
||||
# install olm. A naive 'npm i ./olm/olm-*.tgz' fails because it uses the url
|
||||
# from our package.json (or even matrix-js-sdk's) in preference.
|
||||
tar -C olm -xz < olm/olm-*.tgz
|
||||
rm -r node_modules/olm
|
||||
cp -r olm/package node_modules/olm
|
||||
#
|
||||
# disabled for now, to avoid the annoying scenario of a release doing something
|
||||
# different to /develop. Instead, add it to the 'npm install' list above.
|
||||
# -- rav 2016/02/03
|
||||
#tar -C olm -xz < olm/olm-*.tgz
|
||||
#rm -r node_modules/olm
|
||||
#cp -r olm/package node_modules/olm
|
||||
|
||||
|
||||
# we may be using dev branches of js-sdk and react-sdk, in which case we need to build them
|
||||
(cd node_modules/matrix-js-sdk && npm install)
|
||||
|
|
|
@ -30,6 +30,8 @@ import structures$BottomLeftMenu from './components/structures/BottomLeftMenu';
|
|||
structures$BottomLeftMenu && (module.exports.components['structures.BottomLeftMenu'] = structures$BottomLeftMenu);
|
||||
import structures$CompatibilityPage from './components/structures/CompatibilityPage';
|
||||
structures$CompatibilityPage && (module.exports.components['structures.CompatibilityPage'] = structures$CompatibilityPage);
|
||||
import structures$HomePage from './components/structures/HomePage';
|
||||
structures$HomePage && (module.exports.components['structures.HomePage'] = structures$HomePage);
|
||||
import structures$LeftPanel from './components/structures/LeftPanel';
|
||||
structures$LeftPanel && (module.exports.components['structures.LeftPanel'] = structures$LeftPanel);
|
||||
import structures$RightPanel from './components/structures/RightPanel';
|
||||
|
@ -44,10 +46,8 @@ import structures$ViewSource from './components/structures/ViewSource';
|
|||
structures$ViewSource && (module.exports.components['structures.ViewSource'] = structures$ViewSource);
|
||||
import views$context_menus$MessageContextMenu from './components/views/context_menus/MessageContextMenu';
|
||||
views$context_menus$MessageContextMenu && (module.exports.components['views.context_menus.MessageContextMenu'] = views$context_menus$MessageContextMenu);
|
||||
import views$context_menus$NotificationStateContextMenu from './components/views/context_menus/NotificationStateContextMenu';
|
||||
views$context_menus$NotificationStateContextMenu && (module.exports.components['views.context_menus.NotificationStateContextMenu'] = views$context_menus$NotificationStateContextMenu);
|
||||
import views$context_menus$RoomTagContextMenu from './components/views/context_menus/RoomTagContextMenu';
|
||||
views$context_menus$RoomTagContextMenu && (module.exports.components['views.context_menus.RoomTagContextMenu'] = views$context_menus$RoomTagContextMenu);
|
||||
import views$context_menus$RoomTileContextMenu from './components/views/context_menus/RoomTileContextMenu';
|
||||
views$context_menus$RoomTileContextMenu && (module.exports.components['views.context_menus.RoomTileContextMenu'] = views$context_menus$RoomTileContextMenu);
|
||||
import views$dialogs$BugReportDialog from './components/views/dialogs/BugReportDialog';
|
||||
views$dialogs$BugReportDialog && (module.exports.components['views.dialogs.BugReportDialog'] = views$dialogs$BugReportDialog);
|
||||
import views$dialogs$ChangelogDialog from './components/views/dialogs/ChangelogDialog';
|
||||
|
|
|
@ -27,12 +27,14 @@ module.exports = React.createClass({
|
|||
|
||||
propTypes: {
|
||||
collapsed: React.PropTypes.bool.isRequired,
|
||||
teamToken: React.PropTypes.string,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return({
|
||||
directoryHover : false,
|
||||
roomsHover : false,
|
||||
homeHover: false,
|
||||
peopleHover : false,
|
||||
settingsHover : false,
|
||||
});
|
||||
|
@ -63,6 +65,19 @@ module.exports = React.createClass({
|
|||
this.setState({ roomsHover: false });
|
||||
},
|
||||
|
||||
// Home button events
|
||||
onHomeClick: function() {
|
||||
dis.dispatch({ action: 'view_home_page' });
|
||||
},
|
||||
|
||||
onHomeMouseEnter: function() {
|
||||
this.setState({ homeHover: true });
|
||||
},
|
||||
|
||||
onHomeMouseLeave: function() {
|
||||
this.setState({ homeHover: false });
|
||||
},
|
||||
|
||||
// People events
|
||||
onPeopleClick: function() {
|
||||
dis.dispatch({ action: 'view_create_chat' });
|
||||
|
@ -99,9 +114,21 @@ module.exports = React.createClass({
|
|||
|
||||
render: function() {
|
||||
var TintableSvg = sdk.getComponent('elements.TintableSvg');
|
||||
|
||||
var homeButton;
|
||||
if (this.props.teamToken) {
|
||||
homeButton = (
|
||||
<AccessibleButton className="mx_BottomLeftMenu_homePage" onClick={ this.onHomeClick } onMouseEnter={ this.onHomeMouseEnter } onMouseLeave={ this.onHomeMouseLeave } >
|
||||
<TintableSvg src="img/icons-home.svg" width="25" height="25" />
|
||||
{ this.getLabel("Welcome page", this.state.homeHover) }
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_BottomLeftMenu">
|
||||
<div className="mx_BottomLeftMenu_options">
|
||||
{ homeButton }
|
||||
<AccessibleButton className="mx_BottomLeftMenu_people" onClick={ this.onPeopleClick } onMouseEnter={ this.onPeopleMouseEnter } onMouseLeave={ this.onPeopleMouseLeave } >
|
||||
<TintableSvg src="img/icons-people.svg" width="25" height="25" />
|
||||
{ this.getLabel("Start chat", this.state.peopleHover) }
|
||||
|
|
40
src/components/structures/HomePage.js
Normal file
40
src/components/structures/HomePage.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
|
||||
import sdk from 'matrix-react-sdk';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'HomePage',
|
||||
|
||||
propTypes: {
|
||||
teamServerUrl: React.PropTypes.string.isRequired,
|
||||
teamToken: React.PropTypes.string.isRequired,
|
||||
collapsedRhs: React.PropTypes.bool,
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="mx_HomePage">
|
||||
<iframe src={`${this.props.teamServerUrl}/static/${this.props.teamToken}/home.html`}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
|
@ -28,6 +28,11 @@ var CallHandler = require("matrix-react-sdk/lib/CallHandler");
|
|||
var LeftPanel = React.createClass({
|
||||
displayName: 'LeftPanel',
|
||||
|
||||
propTypes: {
|
||||
collapsed: React.PropTypes.bool.isRequired,
|
||||
teamToken: React.PropTypes.string,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
showCallElement: null,
|
||||
|
@ -124,7 +129,7 @@ var LeftPanel = React.createClass({
|
|||
collapsed={this.props.collapsed}
|
||||
searchFilter={this.state.searchFilter}
|
||||
ConferenceHandler={VectorConferenceHandler} />
|
||||
<BottomLeftMenu collapsed={this.props.collapsed}/>
|
||||
<BottomLeftMenu collapsed={this.props.collapsed} teamToken={this.props.teamToken}/>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ module.exports = React.createClass({
|
|||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to get public room list",
|
||||
description: err.message
|
||||
description: "The server may be unavailable or overloaded",
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -208,9 +208,10 @@ module.exports = React.createClass({
|
|||
}, function(err) {
|
||||
modal.close();
|
||||
this.refreshRoomList();
|
||||
console.error("Failed to " + step + ": " + err);
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to "+step,
|
||||
description: err.toString()
|
||||
title: "Error",
|
||||
description: "Failed to " + step,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -146,12 +146,20 @@ var RoomSubList = React.createClass({
|
|||
}
|
||||
},
|
||||
|
||||
onRoomTileClick(roomId) {
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: roomId,
|
||||
});
|
||||
},
|
||||
|
||||
tsOfNewestEvent: function(room) {
|
||||
for (var i = room.timeline.length - 1; i >= 0; --i) {
|
||||
var ev = room.timeline[i];
|
||||
if (Unread.eventTriggersUnreadCount(ev) ||
|
||||
(ev.sender && ev.sender.userId === MatrixClientPeg.get().credentials.userId))
|
||||
{
|
||||
if (ev.getTs() &&
|
||||
(Unread.eventTriggersUnreadCount(ev) ||
|
||||
(ev.getSender() === MatrixClientPeg.get().credentials.userId))
|
||||
) {
|
||||
return ev.getTs();
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +167,7 @@ var RoomSubList = React.createClass({
|
|||
// we might only have events that don't trigger the unread indicator,
|
||||
// in which case use the oldest event even if normally it wouldn't count.
|
||||
// This is better than just assuming the last event was forever ago.
|
||||
if (room.timeline.length) {
|
||||
if (room.timeline.length && room.timeline[0].getTs()) {
|
||||
return room.timeline[0].getTs();
|
||||
} else {
|
||||
return Number.MAX_SAFE_INTEGER;
|
||||
|
@ -364,7 +372,9 @@ var RoomSubList = React.createClass({
|
|||
highlight={ room.getUnreadNotificationCount('highlight') > 0 || self.props.label === 'Invites' }
|
||||
isInvite={ self.props.label === 'Invites' }
|
||||
refreshSubList={ self._updateSubListCount }
|
||||
incomingCall={ null } />
|
||||
incomingCall={ null }
|
||||
onClick={ self.onRoomTileClick }
|
||||
/>
|
||||
);
|
||||
});
|
||||
},
|
||||
|
@ -408,7 +418,7 @@ var RoomSubList = React.createClass({
|
|||
if (this.props.incomingCall) {
|
||||
var self = this;
|
||||
// Check if the incoming call is for this section
|
||||
var incomingCallRoom = this.state.sortedList.filter(function(room) {
|
||||
var incomingCallRoom = this.props.list.filter(function(room) {
|
||||
return self.props.incomingCall.roomId === room.roomId;
|
||||
});
|
||||
|
||||
|
@ -496,9 +506,10 @@ var RoomSubList = React.createClass({
|
|||
// Do any final stuff here
|
||||
}).fail(function(err) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
console.error("Failed to add tag " + self.props.tagName + " to room" + err);
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to add tag " + self.props.tagName + " to room",
|
||||
description: err.toString()
|
||||
title: "Error",
|
||||
description: "Failed to add tag " + self.props.tagName + " to room",
|
||||
});
|
||||
});
|
||||
break;
|
||||
|
|
|
@ -45,6 +45,9 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onAction: function(payload) {
|
||||
// Disabling this as I find it really really annoying, and was used to the
|
||||
// previous behaviour - see https://github.com/vector-im/riot-web/issues/3348
|
||||
/*
|
||||
switch (payload.action) {
|
||||
// Clear up the text field when a room is selected.
|
||||
case 'view_room':
|
||||
|
@ -53,6 +56,7 @@ module.exports = React.createClass({
|
|||
}
|
||||
break;
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
onChange: function() {
|
||||
|
|
|
@ -62,11 +62,14 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onRedactClick: function() {
|
||||
const ConfirmRedactDialog = sdk.getComponent("dialogs.ConfirmRedactDialog");
|
||||
Modal.createDialog(ConfirmRedactDialog, {
|
||||
onFinished: (proceed) => {
|
||||
if (!proceed) return;
|
||||
|
||||
MatrixClientPeg.get().redactEvent(
|
||||
this.props.mxEvent.getRoomId(), this.props.mxEvent.getId()
|
||||
).done(function() {
|
||||
// message should disappear by itself
|
||||
}, function(e) {
|
||||
).catch(function(e) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
// display error message stating you couldn't delete this.
|
||||
var code = e.errcode || e.statusCode;
|
||||
|
@ -74,7 +77,9 @@ module.exports = React.createClass({
|
|||
title: "Error",
|
||||
description: "You cannot delete this message. (" + code + ")"
|
||||
});
|
||||
});
|
||||
}).done();
|
||||
},
|
||||
}, 'mx_Dialog_confirmredact');
|
||||
if (this.props.onFinished) this.props.onFinished();
|
||||
},
|
||||
|
||||
|
@ -121,7 +126,7 @@ module.exports = React.createClass({
|
|||
);
|
||||
}
|
||||
|
||||
if (!eventStatus) { // sent
|
||||
if (!eventStatus && !this.props.mxEvent.isRedacted()) { // sent and not redacted
|
||||
redactButton = (
|
||||
<div className="mx_MessageContextMenu_field" onClick={this.onRedactClick}>
|
||||
Redact
|
||||
|
|
|
@ -1,144 +0,0 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var q = require("q");
|
||||
var React = require('react');
|
||||
var classNames = require('classnames');
|
||||
var RoomNotifs = require('matrix-react-sdk/lib/RoomNotifs');
|
||||
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'NotificationStateContextMenu',
|
||||
|
||||
propTypes: {
|
||||
room: React.PropTypes.object.isRequired,
|
||||
/* callback called when the menu is dismissed */
|
||||
onFinished: React.PropTypes.func,
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
roomNotifState: RoomNotifs.getRoomNotifsState(this.props.room.roomId),
|
||||
}
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this._unmounted = false;
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this._unmounted = true;
|
||||
},
|
||||
|
||||
_save: function(newState) {
|
||||
const oldState = this.state.roomNotifState;
|
||||
const roomId = this.props.room.roomId;
|
||||
var cli = MatrixClientPeg.get();
|
||||
|
||||
if (cli.isGuest()) return;
|
||||
|
||||
this.setState({
|
||||
roomNotifState: newState,
|
||||
});
|
||||
RoomNotifs.setRoomNotifsState(this.props.room.roomId, newState).done(() => {
|
||||
// delay slightly so that the user can see their state change
|
||||
// before closing the menu
|
||||
return q.delay(500).then(() => {
|
||||
if (this._unmounted) return;
|
||||
// Close the context menu
|
||||
if (this.props.onFinished) {
|
||||
this.props.onFinished();
|
||||
};
|
||||
});
|
||||
}, (error) => {
|
||||
// TODO: some form of error notification to the user
|
||||
// to inform them that their state change failed.
|
||||
// For now we at least set the state back
|
||||
if (this._unmounted) return;
|
||||
this.setState({
|
||||
roomNotifState: oldState,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_onClickAlertMe: function() {
|
||||
this._save(RoomNotifs.ALL_MESSAGES_LOUD);
|
||||
},
|
||||
|
||||
_onClickAllNotifs: function() {
|
||||
this._save(RoomNotifs.ALL_MESSAGES);
|
||||
},
|
||||
|
||||
_onClickMentions: function() {
|
||||
this._save(RoomNotifs.MENTIONS_ONLY);
|
||||
},
|
||||
|
||||
_onClickMute: function() {
|
||||
this._save(RoomNotifs.MUTE);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var alertMeClasses = classNames({
|
||||
'mx_NotificationStateContextMenu_field': true,
|
||||
'mx_NotificationStateContextMenu_fieldSet': this.state.roomNotifState == RoomNotifs.ALL_MESSAGES_LOUD,
|
||||
});
|
||||
|
||||
var allNotifsClasses = classNames({
|
||||
'mx_NotificationStateContextMenu_field': true,
|
||||
'mx_NotificationStateContextMenu_fieldSet': this.state.roomNotifState == RoomNotifs.ALL_MESSAGES,
|
||||
});
|
||||
|
||||
var mentionsClasses = classNames({
|
||||
'mx_NotificationStateContextMenu_field': true,
|
||||
'mx_NotificationStateContextMenu_fieldSet': this.state.roomNotifState == RoomNotifs.MENTIONS_ONLY,
|
||||
});
|
||||
|
||||
var muteNotifsClasses = classNames({
|
||||
'mx_NotificationStateContextMenu_field': true,
|
||||
'mx_NotificationStateContextMenu_fieldSet': this.state.roomNotifState == RoomNotifs.MUTE,
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="mx_NotificationStateContextMenu_picker" >
|
||||
<img src="img/notif-slider.svg" width="20" height="107" />
|
||||
</div>
|
||||
<div className={ alertMeClasses } onClick={this._onClickAlertMe} >
|
||||
<img className="mx_NotificationStateContextMenu_activeIcon" src="img/notif-active.svg" width="12" height="12" />
|
||||
<img className="mx_NotificationStateContextMenu_icon mx_filterFlipColor" src="img/icon-context-mute-off-copy.svg" width="16" height="12" />
|
||||
All messages (loud)
|
||||
</div>
|
||||
<div className={ allNotifsClasses } onClick={this._onClickAllNotifs} >
|
||||
<img className="mx_NotificationStateContextMenu_activeIcon" src="img/notif-active.svg" width="12" height="12" />
|
||||
<img className="mx_NotificationStateContextMenu_icon mx_filterFlipColor" src="img/icon-context-mute-off.svg" width="16" height="12" />
|
||||
All messages
|
||||
</div>
|
||||
<div className={ mentionsClasses } onClick={this._onClickMentions} >
|
||||
<img className="mx_NotificationStateContextMenu_activeIcon" src="img/notif-active.svg" width="12" height="12" />
|
||||
<img className="mx_NotificationStateContextMenu_icon mx_filterFlipColor" src="img/icon-context-mute-mentions.svg" width="16" height="12" />
|
||||
Mentions only
|
||||
</div>
|
||||
<div className={ muteNotifsClasses } onClick={this._onClickMute} >
|
||||
<img className="mx_NotificationStateContextMenu_activeIcon" src="img/notif-active.svg" width="12" height="12" />
|
||||
<img className="mx_NotificationStateContextMenu_icon mx_filterFlipColor" src="img/icon-context-mute.svg" width="16" height="12" />
|
||||
Mute
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
|
@ -1,253 +0,0 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var q = require("q");
|
||||
var React = require('react');
|
||||
var classNames = require('classnames');
|
||||
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||
var DMRoomMap = require('matrix-react-sdk/lib/utils/DMRoomMap');
|
||||
var Rooms = require('matrix-react-sdk/lib/Rooms');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'RoomTagContextMenu',
|
||||
|
||||
propTypes: {
|
||||
room: React.PropTypes.object.isRequired,
|
||||
/* callback called when the menu is dismissed */
|
||||
onFinished: React.PropTypes.func,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
const dmRoomMap = new DMRoomMap(MatrixClientPeg.get());
|
||||
return {
|
||||
isFavourite: this.props.room.tags.hasOwnProperty("m.favourite"),
|
||||
isLowPriority: this.props.room.tags.hasOwnProperty("m.lowpriority"),
|
||||
isDirectMessage: Boolean(dmRoomMap.getUserIdForRoomId(this.props.room.roomId)),
|
||||
};
|
||||
},
|
||||
|
||||
_toggleTag: function(tagNameOn, tagNameOff) {
|
||||
var self = this;
|
||||
const roomId = this.props.room.roomId;
|
||||
var cli = MatrixClientPeg.get();
|
||||
if (!cli.isGuest()) {
|
||||
q.delay(500).then(function() {
|
||||
if (tagNameOff !== null && tagNameOff !== undefined) {
|
||||
cli.deleteRoomTag(roomId, tagNameOff).finally(function() {
|
||||
// Close the context menu
|
||||
if (self.props.onFinished) {
|
||||
self.props.onFinished();
|
||||
};
|
||||
}).fail(function(err) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to remove tag " + tagNameOff + " from room",
|
||||
description: err.toString()
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (tagNameOn !== null && tagNameOn !== undefined) {
|
||||
// If the tag ordering meta data is required, it is added by
|
||||
// the RoomSubList when it sorts its rooms
|
||||
cli.setRoomTag(roomId, tagNameOn, {}).finally(function() {
|
||||
// Close the context menu
|
||||
if (self.props.onFinished) {
|
||||
self.props.onFinished();
|
||||
};
|
||||
}).fail(function(err) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to add tag " + tagNameOn + " to room",
|
||||
description: err.toString()
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_onClickFavourite: function() {
|
||||
// Tag room as 'Favourite'
|
||||
if (!this.state.isFavourite && this.state.isLowPriority) {
|
||||
this.setState({
|
||||
isFavourite: true,
|
||||
isLowPriority: false,
|
||||
});
|
||||
this._toggleTag("m.favourite", "m.lowpriority");
|
||||
} else if (this.state.isFavourite) {
|
||||
this.setState({isFavourite: false});
|
||||
this._toggleTag(null, "m.favourite");
|
||||
} else if (!this.state.isFavourite) {
|
||||
this.setState({isFavourite: true});
|
||||
this._toggleTag("m.favourite");
|
||||
}
|
||||
},
|
||||
|
||||
_onClickLowPriority: function() {
|
||||
// Tag room as 'Low Priority'
|
||||
if (!this.state.isLowPriority && this.state.isFavourite) {
|
||||
this.setState({
|
||||
isFavourite: false,
|
||||
isLowPriority: true,
|
||||
});
|
||||
this._toggleTag("m.lowpriority", "m.favourite");
|
||||
} else if (this.state.isLowPriority) {
|
||||
this.setState({isLowPriority: false});
|
||||
this._toggleTag(null, "m.lowpriority");
|
||||
} else if (!this.state.isLowPriority) {
|
||||
this.setState({isLowPriority: true});
|
||||
this._toggleTag("m.lowpriority");
|
||||
}
|
||||
},
|
||||
|
||||
_onClickDM: function() {
|
||||
const newIsDirectMessage = !this.state.isDirectMessage;
|
||||
this.setState({
|
||||
isDirectMessage: newIsDirectMessage,
|
||||
});
|
||||
|
||||
if (MatrixClientPeg.get().isGuest()) return;
|
||||
|
||||
let newTarget;
|
||||
if (newIsDirectMessage) {
|
||||
const guessedTarget = Rooms.guessDMRoomTarget(
|
||||
this.props.room,
|
||||
this.props.room.getMember(MatrixClientPeg.get().credentials.userId),
|
||||
);
|
||||
newTarget = guessedTarget.userId;
|
||||
} else {
|
||||
newTarget = null;
|
||||
}
|
||||
|
||||
// give some time for the user to see the icon change first, since
|
||||
// this will hide the context menu once it completes
|
||||
q.delay(500).done(() => {
|
||||
return Rooms.setDMRoom(this.props.room.roomId, newTarget).finally(() => {
|
||||
// Close the context menu
|
||||
if (this.props.onFinished) {
|
||||
this.props.onFinished();
|
||||
};
|
||||
}, (err) => {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to set Direct Message status of room",
|
||||
description: err.toString()
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_onClickLeave: function() {
|
||||
// Leave room
|
||||
dis.dispatch({
|
||||
action: 'leave_room',
|
||||
room_id: this.props.room.roomId,
|
||||
});
|
||||
|
||||
// Close the context menu
|
||||
if (this.props.onFinished) {
|
||||
this.props.onFinished();
|
||||
};
|
||||
},
|
||||
|
||||
_onClickForget: function() {
|
||||
// FIXME: duplicated with RoomSettings (and dead code in RoomView)
|
||||
MatrixClientPeg.get().forget(this.props.room.roomId).done(function() {
|
||||
dis.dispatch({ action: 'view_next_room' });
|
||||
}, function(err) {
|
||||
var errCode = err.errcode || "unknown error code";
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Error",
|
||||
description: `Failed to forget room (${errCode})`
|
||||
});
|
||||
});
|
||||
|
||||
// Close the context menu
|
||||
if (this.props.onFinished) {
|
||||
this.props.onFinished();
|
||||
};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
const myMember = this.props.room.getMember(myUserId);
|
||||
|
||||
const favouriteClasses = classNames({
|
||||
'mx_RoomTagContextMenu_field': true,
|
||||
'mx_RoomTagContextMenu_fieldSet': this.state.isFavourite,
|
||||
'mx_RoomTagContextMenu_fieldDisabled': false,
|
||||
});
|
||||
|
||||
const lowPriorityClasses = classNames({
|
||||
'mx_RoomTagContextMenu_field': true,
|
||||
'mx_RoomTagContextMenu_fieldSet': this.state.isLowPriority,
|
||||
'mx_RoomTagContextMenu_fieldDisabled': false,
|
||||
});
|
||||
|
||||
const leaveClasses = classNames({
|
||||
'mx_RoomTagContextMenu_field': true,
|
||||
'mx_RoomTagContextMenu_fieldSet': false,
|
||||
'mx_RoomTagContextMenu_fieldDisabled': false,
|
||||
});
|
||||
|
||||
const dmClasses = classNames({
|
||||
'mx_RoomTagContextMenu_field': true,
|
||||
'mx_RoomTagContextMenu_fieldSet': this.state.isDirectMessage,
|
||||
'mx_RoomTagContextMenu_fieldDisabled': false,
|
||||
});
|
||||
|
||||
if (myMember && myMember.membership === "leave") {
|
||||
return (
|
||||
<div>
|
||||
<div className={ leaveClasses } onClick={ this._onClickForget } >
|
||||
<img className="mx_RoomTagContextMenu_icon" src="img/icon_context_delete.svg" width="15" height="15" />
|
||||
Forget
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={ favouriteClasses } onClick={this._onClickFavourite} >
|
||||
<img className="mx_RoomTagContextMenu_icon" src="img/icon_context_fave.svg" width="15" height="15" />
|
||||
<img className="mx_RoomTagContextMenu_icon_set" src="img/icon_context_fave_on.svg" width="15" height="15" />
|
||||
Favourite
|
||||
</div>
|
||||
<div className={ lowPriorityClasses } onClick={this._onClickLowPriority} >
|
||||
<img className="mx_RoomTagContextMenu_icon" src="img/icon_context_low.svg" width="15" height="15" />
|
||||
<img className="mx_RoomTagContextMenu_icon_set" src="img/icon_context_low_on.svg" width="15" height="15" />
|
||||
Low Priority
|
||||
</div>
|
||||
<div className={ dmClasses } onClick={this._onClickDM} >
|
||||
<img className="mx_RoomTagContextMenu_icon" src="img/icon_context_person.svg" width="15" height="15" />
|
||||
<img className="mx_RoomTagContextMenu_icon_set" src="img/icon_context_person_on.svg" width="15" height="15" />
|
||||
Direct Chat
|
||||
</div>
|
||||
<hr className="mx_RoomTagContextMenu_separator" />
|
||||
<div className={ leaveClasses } onClick={(myMember && myMember.membership === "join") ? this._onClickLeave : null} >
|
||||
<img className="mx_RoomTagContextMenu_icon" src="img/icon_context_delete.svg" width="15" height="15" />
|
||||
Leave
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
392
src/components/views/context_menus/RoomTileContextMenu.js
Normal file
392
src/components/views/context_menus/RoomTileContextMenu.js
Normal file
|
@ -0,0 +1,392 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import q from 'q';
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import sdk from 'matrix-react-sdk';
|
||||
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
|
||||
import dis from 'matrix-react-sdk/lib/dispatcher';
|
||||
import DMRoomMap from 'matrix-react-sdk/lib/utils/DMRoomMap';
|
||||
import * as Rooms from 'matrix-react-sdk/lib/Rooms';
|
||||
import * as RoomNotifs from 'matrix-react-sdk/lib/RoomNotifs';
|
||||
import Modal from 'matrix-react-sdk/lib/Modal';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'RoomTileContextMenu',
|
||||
|
||||
propTypes: {
|
||||
room: React.PropTypes.object.isRequired,
|
||||
/* callback called when the menu is dismissed */
|
||||
onFinished: React.PropTypes.func,
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
const dmRoomMap = new DMRoomMap(MatrixClientPeg.get());
|
||||
return {
|
||||
roomNotifState: RoomNotifs.getRoomNotifsState(this.props.room.roomId),
|
||||
isFavourite: this.props.room.tags.hasOwnProperty("m.favourite"),
|
||||
isLowPriority: this.props.room.tags.hasOwnProperty("m.lowpriority"),
|
||||
isDirectMessage: Boolean(dmRoomMap.getUserIdForRoomId(this.props.room.roomId)),
|
||||
}
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this._unmounted = false;
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this._unmounted = true;
|
||||
},
|
||||
|
||||
_toggleTag: function(tagNameOn, tagNameOff) {
|
||||
var self = this;
|
||||
const roomId = this.props.room.roomId;
|
||||
var cli = MatrixClientPeg.get();
|
||||
if (!cli.isGuest()) {
|
||||
q.delay(500).then(function() {
|
||||
if (tagNameOff !== null && tagNameOff !== undefined) {
|
||||
cli.deleteRoomTag(roomId, tagNameOff).finally(function() {
|
||||
// Close the context menu
|
||||
if (self.props.onFinished) {
|
||||
self.props.onFinished();
|
||||
};
|
||||
}).fail(function(err) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to remove tag " + tagNameOff + " from room",
|
||||
description: err.toString()
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (tagNameOn !== null && tagNameOn !== undefined) {
|
||||
// If the tag ordering meta data is required, it is added by
|
||||
// the RoomSubList when it sorts its rooms
|
||||
cli.setRoomTag(roomId, tagNameOn, {}).finally(function() {
|
||||
// Close the context menu
|
||||
if (self.props.onFinished) {
|
||||
self.props.onFinished();
|
||||
};
|
||||
}).fail(function(err) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to add tag " + tagNameOn + " to room",
|
||||
description: err.toString()
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_onClickFavourite: function() {
|
||||
// Tag room as 'Favourite'
|
||||
if (!this.state.isFavourite && this.state.isLowPriority) {
|
||||
this.setState({
|
||||
isFavourite: true,
|
||||
isLowPriority: false,
|
||||
});
|
||||
this._toggleTag("m.favourite", "m.lowpriority");
|
||||
} else if (this.state.isFavourite) {
|
||||
this.setState({isFavourite: false});
|
||||
this._toggleTag(null, "m.favourite");
|
||||
} else if (!this.state.isFavourite) {
|
||||
this.setState({isFavourite: true});
|
||||
this._toggleTag("m.favourite");
|
||||
}
|
||||
},
|
||||
|
||||
_onClickLowPriority: function() {
|
||||
// Tag room as 'Low Priority'
|
||||
if (!this.state.isLowPriority && this.state.isFavourite) {
|
||||
this.setState({
|
||||
isFavourite: false,
|
||||
isLowPriority: true,
|
||||
});
|
||||
this._toggleTag("m.lowpriority", "m.favourite");
|
||||
} else if (this.state.isLowPriority) {
|
||||
this.setState({isLowPriority: false});
|
||||
this._toggleTag(null, "m.lowpriority");
|
||||
} else if (!this.state.isLowPriority) {
|
||||
this.setState({isLowPriority: true});
|
||||
this._toggleTag("m.lowpriority");
|
||||
}
|
||||
},
|
||||
|
||||
_onClickDM: function() {
|
||||
const newIsDirectMessage = !this.state.isDirectMessage;
|
||||
this.setState({
|
||||
isDirectMessage: newIsDirectMessage,
|
||||
});
|
||||
|
||||
if (MatrixClientPeg.get().isGuest()) return;
|
||||
|
||||
Rooms.guessAndSetDMRoom(
|
||||
this.props.room, newIsDirectMessage
|
||||
).delay(500).finally(() => {
|
||||
// Close the context menu
|
||||
if (this.props.onFinished) {
|
||||
this.props.onFinished();
|
||||
};
|
||||
}, (err) => {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to set Direct Message status of room",
|
||||
description: err.toString()
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_onClickLeave: function() {
|
||||
// Leave room
|
||||
dis.dispatch({
|
||||
action: 'leave_room',
|
||||
room_id: this.props.room.roomId,
|
||||
});
|
||||
|
||||
// Close the context menu
|
||||
if (this.props.onFinished) {
|
||||
this.props.onFinished();
|
||||
};
|
||||
},
|
||||
|
||||
_onClickReject: function() {
|
||||
dis.dispatch({
|
||||
action: 'reject_invite',
|
||||
room_id: this.props.room.roomId,
|
||||
});
|
||||
|
||||
// Close the context menu
|
||||
if (this.props.onFinished) {
|
||||
this.props.onFinished();
|
||||
};
|
||||
},
|
||||
|
||||
_onClickForget: function() {
|
||||
// FIXME: duplicated with RoomSettings (and dead code in RoomView)
|
||||
MatrixClientPeg.get().forget(this.props.room.roomId).done(function() {
|
||||
dis.dispatch({ action: 'view_next_room' });
|
||||
}, function(err) {
|
||||
var errCode = err.errcode || "unknown error code";
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Error",
|
||||
description: `Failed to forget room (${errCode})`
|
||||
});
|
||||
});
|
||||
|
||||
// Close the context menu
|
||||
if (this.props.onFinished) {
|
||||
this.props.onFinished();
|
||||
};
|
||||
},
|
||||
|
||||
_saveNotifState: function(newState) {
|
||||
const oldState = this.state.roomNotifState;
|
||||
const roomId = this.props.room.roomId;
|
||||
var cli = MatrixClientPeg.get();
|
||||
|
||||
if (cli.isGuest()) return;
|
||||
|
||||
this.setState({
|
||||
roomNotifState: newState,
|
||||
});
|
||||
RoomNotifs.setRoomNotifsState(this.props.room.roomId, newState).done(() => {
|
||||
// delay slightly so that the user can see their state change
|
||||
// before closing the menu
|
||||
return q.delay(500).then(() => {
|
||||
if (this._unmounted) return;
|
||||
// Close the context menu
|
||||
if (this.props.onFinished) {
|
||||
this.props.onFinished();
|
||||
};
|
||||
});
|
||||
}, (error) => {
|
||||
// TODO: some form of error notification to the user
|
||||
// to inform them that their state change failed.
|
||||
// For now we at least set the state back
|
||||
if (this._unmounted) return;
|
||||
this.setState({
|
||||
roomNotifState: oldState,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_onClickAlertMe: function() {
|
||||
this._saveNotifState(RoomNotifs.ALL_MESSAGES_LOUD);
|
||||
},
|
||||
|
||||
_onClickAllNotifs: function() {
|
||||
this._saveNotifState(RoomNotifs.ALL_MESSAGES);
|
||||
},
|
||||
|
||||
_onClickMentions: function() {
|
||||
this._saveNotifState(RoomNotifs.MENTIONS_ONLY);
|
||||
},
|
||||
|
||||
_onClickMute: function() {
|
||||
this._saveNotifState(RoomNotifs.MUTE);
|
||||
},
|
||||
|
||||
_renderNotifMenu: function() {
|
||||
var alertMeClasses = classNames({
|
||||
'mx_RoomTileContextMenu_notif_field': true,
|
||||
'mx_RoomTileContextMenu_notif_fieldSet': this.state.roomNotifState == RoomNotifs.ALL_MESSAGES_LOUD,
|
||||
});
|
||||
|
||||
var allNotifsClasses = classNames({
|
||||
'mx_RoomTileContextMenu_notif_field': true,
|
||||
'mx_RoomTileContextMenu_notif_fieldSet': this.state.roomNotifState == RoomNotifs.ALL_MESSAGES,
|
||||
});
|
||||
|
||||
var mentionsClasses = classNames({
|
||||
'mx_RoomTileContextMenu_notif_field': true,
|
||||
'mx_RoomTileContextMenu_notif_fieldSet': this.state.roomNotifState == RoomNotifs.MENTIONS_ONLY,
|
||||
});
|
||||
|
||||
var muteNotifsClasses = classNames({
|
||||
'mx_RoomTileContextMenu_notif_field': true,
|
||||
'mx_RoomTileContextMenu_notif_fieldSet': this.state.roomNotifState == RoomNotifs.MUTE,
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="mx_RoomTileContextMenu_notif_picker" >
|
||||
<img src="img/notif-slider.svg" width="20" height="107" />
|
||||
</div>
|
||||
<div className={ alertMeClasses } onClick={this._onClickAlertMe} >
|
||||
<img className="mx_RoomTileContextMenu_notif_activeIcon" src="img/notif-active.svg" width="12" height="12" />
|
||||
<img className="mx_RoomTileContextMenu_notif_icon mx_filterFlipColor" src="img/icon-context-mute-off-copy.svg" width="16" height="12" />
|
||||
All messages (loud)
|
||||
</div>
|
||||
<div className={ allNotifsClasses } onClick={this._onClickAllNotifs} >
|
||||
<img className="mx_RoomTileContextMenu_notif_activeIcon" src="img/notif-active.svg" width="12" height="12" />
|
||||
<img className="mx_RoomTileContextMenu_notif_icon mx_filterFlipColor" src="img/icon-context-mute-off.svg" width="16" height="12" />
|
||||
All messages
|
||||
</div>
|
||||
<div className={ mentionsClasses } onClick={this._onClickMentions} >
|
||||
<img className="mx_RoomTileContextMenu_notif_activeIcon" src="img/notif-active.svg" width="12" height="12" />
|
||||
<img className="mx_RoomTileContextMenu_notif_icon mx_filterFlipColor" src="img/icon-context-mute-mentions.svg" width="16" height="12" />
|
||||
Mentions only
|
||||
</div>
|
||||
<div className={ muteNotifsClasses } onClick={this._onClickMute} >
|
||||
<img className="mx_RoomTileContextMenu_notif_activeIcon" src="img/notif-active.svg" width="12" height="12" />
|
||||
<img className="mx_RoomTileContextMenu_notif_icon mx_filterFlipColor" src="img/icon-context-mute.svg" width="16" height="12" />
|
||||
Mute
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
_renderLeaveMenu: function(membership) {
|
||||
if (!membership) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let leaveClickHandler = null;
|
||||
let leaveText = null;
|
||||
|
||||
switch (membership) {
|
||||
case "join":
|
||||
leaveClickHandler = this._onClickLeave;
|
||||
leaveText = "Leave";
|
||||
break;
|
||||
case "leave":
|
||||
case "ban":
|
||||
leaveClickHandler = this._onClickForget;
|
||||
leaveText = "Forget";
|
||||
break;
|
||||
case "invite":
|
||||
leaveClickHandler = this._onClickReject;
|
||||
leaveText = "Reject";
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="mx_RoomTileContextMenu_leave" onClick={ leaveClickHandler } >
|
||||
<img className="mx_RoomTileContextMenu_tag_icon" src="img/icon_context_delete.svg" width="15" height="15" />
|
||||
{ leaveText }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
_renderRoomTagMenu: function() {
|
||||
const favouriteClasses = classNames({
|
||||
'mx_RoomTileContextMenu_tag_field': true,
|
||||
'mx_RoomTileContextMenu_tag_fieldSet': this.state.isFavourite,
|
||||
'mx_RoomTileContextMenu_tag_fieldDisabled': false,
|
||||
});
|
||||
|
||||
const lowPriorityClasses = classNames({
|
||||
'mx_RoomTileContextMenu_tag_field': true,
|
||||
'mx_RoomTileContextMenu_tag_fieldSet': this.state.isLowPriority,
|
||||
'mx_RoomTileContextMenu_tag_fieldDisabled': false,
|
||||
});
|
||||
|
||||
const dmClasses = classNames({
|
||||
'mx_RoomTileContextMenu_tag_field': true,
|
||||
'mx_RoomTileContextMenu_tag_fieldSet': this.state.isDirectMessage,
|
||||
'mx_RoomTileContextMenu_tag_fieldDisabled': false,
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={ favouriteClasses } onClick={this._onClickFavourite} >
|
||||
<img className="mx_RoomTileContextMenu_tag_icon" src="img/icon_context_fave.svg" width="15" height="15" />
|
||||
<img className="mx_RoomTileContextMenu_tag_icon_set" src="img/icon_context_fave_on.svg" width="15" height="15" />
|
||||
Favourite
|
||||
</div>
|
||||
<div className={ lowPriorityClasses } onClick={this._onClickLowPriority} >
|
||||
<img className="mx_RoomTileContextMenu_tag_icon" src="img/icon_context_low.svg" width="15" height="15" />
|
||||
<img className="mx_RoomTileContextMenu_tag_icon_set" src="img/icon_context_low_on.svg" width="15" height="15" />
|
||||
Low Priority
|
||||
</div>
|
||||
<div className={ dmClasses } onClick={this._onClickDM} >
|
||||
<img className="mx_RoomTileContextMenu_tag_icon" src="img/icon_context_person.svg" width="15" height="15" />
|
||||
<img className="mx_RoomTileContextMenu_tag_icon_set" src="img/icon_context_person_on.svg" width="15" height="15" />
|
||||
Direct Chat
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const myMember = this.props.room.getMember(
|
||||
MatrixClientPeg.get().credentials.userId
|
||||
);
|
||||
|
||||
// Can't set notif level or tags on non-join rooms
|
||||
if (myMember.membership !== 'join') {
|
||||
return this._renderLeaveMenu(myMember.membership);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{ this._renderNotifMenu() }
|
||||
<hr className="mx_RoomTileContextMenu_separator" />
|
||||
{ this._renderLeaveMenu(myMember.membership) }
|
||||
<hr className="mx_RoomTileContextMenu_separator" />
|
||||
{ this._renderRoomTagMenu() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
|
@ -23,6 +23,8 @@ var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
|||
var DateUtils = require('matrix-react-sdk/lib/DateUtils');
|
||||
var filesize = require('filesize');
|
||||
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
|
||||
const Modal = require('matrix-react-sdk/lib/Modal');
|
||||
const sdk = require('matrix-react-sdk');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'ImageView',
|
||||
|
@ -62,12 +64,14 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onRedactClick: function() {
|
||||
const ConfirmRedactDialog = sdk.getComponent("dialogs.ConfirmRedactDialog");
|
||||
Modal.createDialog(ConfirmRedactDialog, {
|
||||
onFinished: (proceed) => {
|
||||
if (!proceed) return;
|
||||
var self = this;
|
||||
MatrixClientPeg.get().redactEvent(
|
||||
this.props.mxEvent.getRoomId(), this.props.mxEvent.getId()
|
||||
).done(function() {
|
||||
if (self.props.onFinished) self.props.onFinished();
|
||||
}, function(e) {
|
||||
).catch(function(e) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
// display error message stating you couldn't delete this.
|
||||
var code = e.errcode || e.statusCode;
|
||||
|
@ -75,6 +79,8 @@ module.exports = React.createClass({
|
|||
title: "Error",
|
||||
description: "You cannot delete this image. (" + code + ")"
|
||||
});
|
||||
}).done();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -16,14 +16,16 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var DragSource = require('react-dnd').DragSource;
|
||||
var DropTarget = require('react-dnd').DropTarget;
|
||||
import React from 'react';
|
||||
import {DragSource} from 'react-dnd';
|
||||
import {DropTarget} from 'react-dnd';
|
||||
|
||||
var dis = require("matrix-react-sdk/lib/dispatcher");
|
||||
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||
var sdk = require('matrix-react-sdk');
|
||||
var RoomTile = require('matrix-react-sdk/lib/components/views/rooms/RoomTile');
|
||||
import dis from 'matrix-react-sdk/lib/dispatcher';
|
||||
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
|
||||
import sdk from 'matrix-react-sdk';
|
||||
import RoomTile from 'matrix-react-sdk/lib/components/views/rooms/RoomTile';
|
||||
import * as Rooms from 'matrix-react-sdk/lib/Rooms';
|
||||
import Modal from 'matrix-react-sdk/lib/Modal';
|
||||
|
||||
/**
|
||||
* Defines a new Component, DNDRoomTile that wraps RoomTile, making it draggable.
|
||||
|
@ -72,21 +74,49 @@ var roomTileSource = {
|
|||
item.targetList.forceUpdate(); // as we're not using state
|
||||
}
|
||||
|
||||
const prevTag = item.originalList.props.tagName;
|
||||
const newTag = item.targetList.props.tagName;
|
||||
|
||||
if (monitor.didDrop() && item.targetList.props.editable) {
|
||||
// Evil hack to get DMs behaving
|
||||
if ((prevTag === undefined && newTag === 'im.vector.fake.direct') ||
|
||||
(prevTag === 'im.vector.fake.direct' && newTag === undefined)
|
||||
) {
|
||||
Rooms.guessAndSetDMRoom(
|
||||
item.room, newTag === 'im.vector.fake.direct',
|
||||
).done(() => {
|
||||
item.originalList.removeRoomTile(item.room);
|
||||
}, (err) => {
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
console.error("Failed to set direct chat tag " + err);
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Error",
|
||||
description: "Failed to set direct chat tag",
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// More evilness: We will still be dealing with moving to favourites/low prio,
|
||||
// but we avoid ever doing a request with 'im.vector.fake.direct`.
|
||||
|
||||
// if we moved lists, remove the old tag
|
||||
if (item.targetList !== item.originalList && item.originalList.props.tagName) {
|
||||
if (prevTag && prevTag !== 'im.vector.fake.direct' &&
|
||||
item.targetList !== item.originalList
|
||||
) {
|
||||
// commented out attempts to set a spinner on our target component as component is actually
|
||||
// the original source component being dragged, not our target. To fix we just need to
|
||||
// move all of this to endDrop in the target instead. FIXME later.
|
||||
|
||||
//component.state.set({ spinner: component.state.spinner ? component.state.spinner++ : 1 });
|
||||
MatrixClientPeg.get().deleteRoomTag(item.room.roomId, item.originalList.props.tagName).finally(function() {
|
||||
MatrixClientPeg.get().deleteRoomTag(item.room.roomId, prevTag).finally(function() {
|
||||
//component.state.set({ spinner: component.state.spinner-- });
|
||||
}).fail(function(err) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
console.error("Failed to remove tag " + prevTag + " from room: " + err);
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to remove tag " + item.originalList.props.tagName + " from room",
|
||||
description: err.toString()
|
||||
title: "Error",
|
||||
description: "Failed to remove tag " + prevTag + " from room",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -97,15 +127,18 @@ var roomTileSource = {
|
|||
}
|
||||
|
||||
// if we moved lists or the ordering changed, add the new tag
|
||||
if (item.targetList.props.tagName && (item.targetList !== item.originalList || newOrder)) {
|
||||
if (newTag && newTag !== 'im.vector.fake.direct' &&
|
||||
(item.targetList !== item.originalList || newOrder)
|
||||
) {
|
||||
//component.state.set({ spinner: component.state.spinner ? component.state.spinner++ : 1 });
|
||||
MatrixClientPeg.get().setRoomTag(item.room.roomId, item.targetList.props.tagName, newOrder).finally(function() {
|
||||
MatrixClientPeg.get().setRoomTag(item.room.roomId, newTag, newOrder).finally(function() {
|
||||
//component.state.set({ spinner: component.state.spinner-- });
|
||||
}).fail(function(err) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
console.error("Failed to add tag " + newTag + " to room: " + err);
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to add tag " + item.targetList.props.tagName + " to room",
|
||||
description: err.toString()
|
||||
title: "Error",
|
||||
description: "Failed to add tag " + newTag + " to room",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ module.exports = React.createClass({
|
|||
else {
|
||||
return (
|
||||
<div className="mx_RoomDropTarget">
|
||||
<div className="mx_RoomDropTarget_avatar"></div>
|
||||
<div className="mx_RoomDropTarget_label">
|
||||
{ this.props.label }
|
||||
</div>
|
||||
|
|
|
@ -238,9 +238,10 @@ module.exports = React.createClass({
|
|||
self._refreshFromServer();
|
||||
}, function(error) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
console.error("Failed to change settings: " + error);
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Can't change settings",
|
||||
description: error.toString(),
|
||||
title: "Error",
|
||||
description: "Failed to change settings",
|
||||
onFinished: self._refreshFromServer
|
||||
});
|
||||
});
|
||||
|
@ -307,9 +308,10 @@ module.exports = React.createClass({
|
|||
self._refreshFromServer();
|
||||
}, function(error) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
console.error("Can't update user notification settings: " + error);
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Can't update user notification settings",
|
||||
description: error.toString(),
|
||||
title: "Error",
|
||||
description: "Can't update user notification settings",
|
||||
onFinished: self._refreshFromServer
|
||||
});
|
||||
});
|
||||
|
@ -348,9 +350,10 @@ module.exports = React.createClass({
|
|||
|
||||
var onError = function(error) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
console.error("Failed to update keywords: " + error);
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Can't update keywords",
|
||||
description: error.toString(),
|
||||
title: "Error",
|
||||
description: "Failed to update keywords",
|
||||
onFinished: self._refreshFromServer
|
||||
});
|
||||
}
|
||||
|
@ -458,8 +461,8 @@ module.exports = React.createClass({
|
|||
'.m.rule.master': 'master',
|
||||
|
||||
// The default push rules displayed by Vector UI
|
||||
// XXX: .m.rule.contains_user_name is not managed (not a fancy rule for Vector?)
|
||||
'.m.rule.contains_display_name': 'vector',
|
||||
'.m.rule.contains_user_name': 'vector',
|
||||
'.m.rule.room_one_to_one': 'vector',
|
||||
'.m.rule.message': 'vector',
|
||||
'.m.rule.invite_for_me': 'vector',
|
||||
|
@ -512,6 +515,7 @@ module.exports = React.createClass({
|
|||
|
||||
var vectorRuleIds = [
|
||||
'.m.rule.contains_display_name',
|
||||
'.m.rule.contains_user_name',
|
||||
'_keywords',
|
||||
'.m.rule.room_one_to_one',
|
||||
'.m.rule.message',
|
||||
|
@ -715,20 +719,17 @@ module.exports = React.createClass({
|
|||
);
|
||||
}
|
||||
|
||||
var emailNotificationsRow;
|
||||
if (this.props.threepids.filter(function(tp) {
|
||||
if (tp.medium == "email") {
|
||||
return true;
|
||||
}
|
||||
}).length == 0) {
|
||||
const emailThreepids = this.props.threepids.filter((tp) => tp.medium === "email");
|
||||
let emailNotificationsRow;
|
||||
if (emailThreepids.length === 0) {
|
||||
emailNotificationsRow = <div>
|
||||
Add an email address above to configure email notifications
|
||||
</div>;
|
||||
} else {
|
||||
// This only supports the first email address in your profile for now
|
||||
emailNotificationsRow = this.emailNotificationsRow(
|
||||
this.props.threepids[0].address,
|
||||
"Enable email notifications ("+this.props.threepids[0].address+")"
|
||||
emailThreepids[0].address,
|
||||
"Enable email notifications ("+emailThreepids[0].address+")"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -63,10 +63,20 @@ class VectorPushRuleDefinition {
|
|||
*/
|
||||
module.exports = {
|
||||
// Messages containing user's display name
|
||||
// (skip contains_user_name which is too geeky)
|
||||
".m.rule.contains_display_name": new VectorPushRuleDefinition({
|
||||
kind: "override",
|
||||
description: "Messages containing my name",
|
||||
description: "Messages containing my display name",
|
||||
vectorStateToActions: { // The actions for each vector state, or null to disable the rule.
|
||||
on: StandardActions.ACTION_NOTIFY,
|
||||
loud: StandardActions.ACTION_HIGHLIGHT_DEFAULT_SOUND,
|
||||
off: StandardActions.ACTION_DISABLED
|
||||
}
|
||||
}),
|
||||
|
||||
// Messages containing user's username (localpart/MXID)
|
||||
".m.rule.contains_user_name": new VectorPushRuleDefinition({
|
||||
kind: "override",
|
||||
description: "Messages containing my user name",
|
||||
vectorStateToActions: { // The actions for each vector state, or null to disable the rule.
|
||||
on: StandardActions.ACTION_NOTIFY,
|
||||
loud: StandardActions.ACTION_HIGHLIGHT_DEFAULT_SOUND,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -134,7 +135,7 @@ textarea {
|
|||
.mx_Dialog_wrapper.mx_Dialog_spinner .mx_Dialog {
|
||||
width: auto;
|
||||
border-radius: 8px;
|
||||
padding-left: 0px;
|
||||
padding: 0px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
@ -152,6 +153,7 @@ textarea {
|
|||
font-size: 15px;
|
||||
position: relative;
|
||||
padding-left: 58px;
|
||||
padding-bottom: 36px;
|
||||
width: 60%;
|
||||
max-width: 704px;
|
||||
box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.2);
|
||||
|
@ -184,6 +186,17 @@ textarea {
|
|||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mx_Dialog_cancelButton {
|
||||
position: absolute;
|
||||
right: 11px;
|
||||
top: 13px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_Dialog_cancelButton object {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mx_Dialog_content {
|
||||
margin: 24px 58px 68px 0;
|
||||
font-size: 14px;
|
||||
|
@ -191,10 +204,6 @@ textarea {
|
|||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.mx_Dialog_buttons {
|
||||
padding-bottom: 36px;
|
||||
}
|
||||
|
||||
.mx_Dialog button, .mx_Dialog input[type="submit"] {
|
||||
border: 0px;
|
||||
height: 36px;
|
||||
|
@ -286,6 +295,10 @@ textarea {
|
|||
display: inline;
|
||||
}
|
||||
|
||||
.mx_button_row {
|
||||
margin-top: 69px;
|
||||
}
|
||||
|
||||
.changelog_text {
|
||||
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
|
||||
}
|
||||
|
|
|
@ -13,17 +13,22 @@
|
|||
@import "./matrix-react-sdk/structures/login/_Login.scss";
|
||||
@import "./matrix-react-sdk/views/avatars/_BaseAvatar.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";
|
||||
@import "./matrix-react-sdk/views/dialogs/_ConfirmUserActionDialog.scss";
|
||||
@import "./matrix-react-sdk/views/dialogs/_EncryptedEventDialog.scss";
|
||||
@import "./matrix-react-sdk/views/dialogs/_SetDisplayNameDialog.scss";
|
||||
@import "./matrix-react-sdk/views/dialogs/_UnknownDeviceDialog.scss";
|
||||
@import "./matrix-react-sdk/views/elements/_AddressSelector.scss";
|
||||
@import "./matrix-react-sdk/views/elements/_AddressTile.scss";
|
||||
@import "./matrix-react-sdk/views/elements/_DirectorySearchBox.scss";
|
||||
@import "./matrix-react-sdk/views/elements/_Dropdown.scss";
|
||||
@import "./matrix-react-sdk/views/elements/_MemberEventListSummary.scss";
|
||||
@import "./matrix-react-sdk/views/elements/_ProgressBar.scss";
|
||||
@import "./matrix-react-sdk/views/elements/_RichText.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";
|
||||
@import "./matrix-react-sdk/views/messages/_MImageBody.scss";
|
||||
@import "./matrix-react-sdk/views/messages/_MNoticeBody.scss";
|
||||
@import "./matrix-react-sdk/views/messages/_MTextBody.scss";
|
||||
|
@ -53,14 +58,14 @@
|
|||
@import "./matrix-react-sdk/views/voip/_VideoView.scss";
|
||||
@import "./vector-web/_fonts.scss";
|
||||
@import "./vector-web/structures/_CompatibilityPage.scss";
|
||||
@import "./vector-web/structures/_HomePage.scss";
|
||||
@import "./vector-web/structures/_LeftPanel.scss";
|
||||
@import "./vector-web/structures/_RightPanel.scss";
|
||||
@import "./vector-web/structures/_RoomDirectory.scss";
|
||||
@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/_NotificationStateContextMenu.scss";
|
||||
@import "./vector-web/views/context_menus/_RoomTagContextMenu.scss";
|
||||
@import "./vector-web/views/context_menus/_RoomTileContextMenu.scss";
|
||||
@import "./vector-web/views/dialogs/_ChangelogDialog.scss";
|
||||
@import "./vector-web/views/directory/_NetworkDropdown.scss";
|
||||
@import "./vector-web/views/elements/_ImageView.scss";
|
||||
|
|
|
@ -90,16 +90,13 @@ limitations under the License.
|
|||
*/
|
||||
overflow-x: auto;
|
||||
|
||||
/* XXX: Hack: apparently if you try to nest a flex-box
|
||||
* within a non-flex-box within a flex-box, the height
|
||||
* of the innermost element gets miscalculated if the
|
||||
* parents are both auto. Height has to be auto here
|
||||
* for RoomView to correctly fit when the Toolbar is shown.
|
||||
* Ideally we'd launch straight into the RoomView at this
|
||||
* point, but instead we fudge it and make the middlePanel
|
||||
* flex itself.
|
||||
*/
|
||||
display: flex;
|
||||
|
||||
/* To fix https://github.com/vector-im/riot-web/issues/3298 where Safari
|
||||
needed height 100% all the way down to the HomePage. Height does not
|
||||
have to be auto, empirically.
|
||||
*/
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mx_MatrixChat .mx_RightPanel {
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
|
||||
.mx_RoomStatusBar {
|
||||
margin-left: 65px;
|
||||
min-height: 34px;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
/* position the indicator in the same place horizontally as .mx_EventTile_avatar. */
|
||||
|
@ -24,7 +24,7 @@ limitations under the License.
|
|||
padding-left: 17px;
|
||||
padding-right: 12px;
|
||||
margin-left: -73px;
|
||||
margin-top: 8px;
|
||||
margin-top: 15px;
|
||||
float: left;
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
|
@ -72,6 +72,7 @@ limitations under the License.
|
|||
|
||||
.mx_RoomStatusBar_typingIndicatorAvatars {
|
||||
width: 52px;
|
||||
margin-top: -1px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
|
@ -102,6 +103,7 @@ limitations under the License.
|
|||
|
||||
.mx_RoomStatusBar_scrollDownIndicator {
|
||||
cursor: pointer;
|
||||
padding-left: 1px;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_unreadMessagesBar {
|
||||
|
@ -112,7 +114,7 @@ limitations under the License.
|
|||
|
||||
.mx_RoomStatusBar_connectionLostBar {
|
||||
margin-top: 19px;
|
||||
height: 58px;
|
||||
min-height: 58px;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_connectionLostBar img {
|
||||
|
@ -144,7 +146,9 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_RoomStatusBar_typingBar {
|
||||
padding-top: 10px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
|
||||
color: $primary-fg-color;
|
||||
opacity: 0.5;
|
||||
overflow-y: hidden;
|
||||
|
|
|
@ -206,11 +206,14 @@ hr.mx_RoomView_myReadMarker {
|
|||
}
|
||||
|
||||
.mx_RoomView_inCall .mx_RoomView_statusAreaBox_line {
|
||||
border-top: 1px hidden;
|
||||
margin-top: 2px;
|
||||
border: none;
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
.mx_RoomView_inCall .mx_MessageComposer_wrapper {
|
||||
border-top: 2px hidden;
|
||||
padding-top: 1px;
|
||||
}
|
||||
|
||||
.mx_RoomView_inCall .mx_RoomView_statusAreaBox {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -101,6 +102,15 @@ limitations under the License.
|
|||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.mx_UserSettings_importExportButtons {
|
||||
padding-top: 10px;
|
||||
padding-left: 40px;
|
||||
}
|
||||
|
||||
.mx_UserSettings_importExportButtons .mx_UserSettings_button {
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.mx_UserSettings_toggle input {
|
||||
width: 16px;
|
||||
margin-right: 8px;
|
||||
|
@ -166,6 +176,12 @@ limitations under the License.
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
input.mx_UserSettings_phoneNumberField {
|
||||
margin-left: 3px;
|
||||
width: 172px;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.mx_UserSettings_changePasswordButton {
|
||||
float: right;
|
||||
margin-right: 32px;
|
||||
|
|
|
@ -66,6 +66,10 @@ limitations under the License.
|
|||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.mx_Login_username {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.mx_Login_fieldLabel {
|
||||
margin-top: -10px;
|
||||
margin-left: 8px;
|
||||
|
@ -163,3 +167,16 @@ limitations under the License.
|
|||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.mx_Login_phoneSection {
|
||||
display: table;
|
||||
}
|
||||
|
||||
.mx_Login_phoneCountry {
|
||||
display: table-cell;
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
.mx_Login_phoneNumberField {
|
||||
width: 210px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ limitations under the License.
|
|||
|
||||
.mx_BaseAvatar_initial {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
color: $avatar-initial-color;
|
||||
text-align: center;
|
||||
speak: none;
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
Copyright 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
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_ChatCreateOrReuseDialog .mx_ChatCreateOrReuseDialog_tiles {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.mx_ChatCreateOrReuseDialog .mx_Dialog_content {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.mx_ChatCreateOrReuseDialog .mx_RoomTile_badge {
|
||||
display: none;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Copyright 2017 Vector Creations 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_ConfirmUserActionDialog .mx_Dialog_content {
|
||||
min-height: 48px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.mx_ConfirmUserActionDialog_avatar {
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.mx_ConfirmUserActionDialog_name {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.mx_ConfirmUserActionDialog_userId {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.mx_ConfirmUserActionDialog_reasonField {
|
||||
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
|
||||
font-size: 14px;
|
||||
color: $primary-fg-color;
|
||||
|
||||
border-radius: 3px;
|
||||
border: solid 1px $input-border-color;
|
||||
line-height: 36px;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
|
||||
margin-bottom: 24px;
|
||||
|
||||
width: 90%;
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
Copyright 2017 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_Dropdown {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_Dropdown_input {
|
||||
position: relative;
|
||||
border-radius: 3px;
|
||||
border: 1px solid $strong-input-border-color;
|
||||
font-weight: 300;
|
||||
font-size: 13px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.mx_Dropdown_arrow {
|
||||
border-color: $primary-fg-color transparent transparent;
|
||||
border-style: solid;
|
||||
border-width: 5px 5px 0;
|
||||
display: block;
|
||||
height: 0;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 14px;
|
||||
width: 0
|
||||
}
|
||||
|
||||
.mx_Dropdown_option {
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.mx_Dropdown_option img {
|
||||
margin: 5px;
|
||||
width: 25px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
input.mx_Dropdown_option, input.mx_Dropdown_option:focus {
|
||||
border: 0;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
// XXX: hack to prevent text box being too big and pushing
|
||||
// its parent out / overlapping the dropdown arrow. Only really
|
||||
// works in the Country dropdown.
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.mx_Dropdown_menu {
|
||||
position: absolute;
|
||||
left: -1px;
|
||||
right: -1px;
|
||||
top: 100%;
|
||||
z-index: 2;
|
||||
margin: 0;
|
||||
padding: 0px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid $accent-color;
|
||||
background-color: $primary-bg-color;
|
||||
max-height: 200px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.mx_Dropdown_menu .mx_Dropdown_option_highlight {
|
||||
background-color: $focus-bg-color;
|
||||
}
|
||||
|
||||
.mx_Dropdown_menu {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mx_Dropdown_searchPrompt {
|
||||
font-weight: normal;
|
||||
margin-left: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
|
@ -14,6 +14,10 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_MemberEventListSummary {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_TextualEvent.mx_MemberEventListSummary_summary {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
@ -31,6 +35,15 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_MemberEventListSummary_toggle {
|
||||
color:$accent-color;
|
||||
cursor:pointer;
|
||||
color: $accent-color;
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.mx_MemberEventListSummary_line {
|
||||
border-bottom: 1px solid $primary-hairline-color;
|
||||
margin-left: 63px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
// XXX: bleurgh, what is this? These classes totally break the component
|
||||
// naming scheme; it's completely unclear where or how they're being used
|
||||
// --Matthew
|
||||
|
||||
.mx_UserPill {
|
||||
color: white;
|
||||
background-color: $accent-color;
|
||||
|
@ -25,13 +29,13 @@
|
|||
padding: .2em 0;
|
||||
margin: 0;
|
||||
font-size: 85%;
|
||||
background-color: rgba(0,0,0,.04);
|
||||
background-color: $rte-code-bg-color;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.mx_Markdown_HR {
|
||||
display: block;
|
||||
background: #e7e7e7;
|
||||
background: $rte-bg-color;
|
||||
}
|
||||
|
||||
.mx_Markdown_STRIKETHROUGH {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Copyright 2017 Vector Creations 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_InteractiveAuthEntryComponents_msisdnWrapper {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mx_InteractiveAuthEntryComponents_msisdnEntry {
|
||||
font-size: 200%;
|
||||
font-weight: bold;
|
||||
border: 1px solid $strong-input-border-color;
|
||||
border-radius: 3px;
|
||||
width: 6em;
|
||||
}
|
||||
|
||||
.mx_InteractiveAuthEntryComponents_msisdnEntry:focus {
|
||||
border: 1px solid $accent-color;
|
||||
}
|
||||
|
||||
.mx_InteractiveAuthEntryComponents_msisdnSubmit {
|
||||
margin-top: 4px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
// XXX: This should be a common button class
|
||||
.mx_InteractiveAuthEntryComponents_msisdnSubmit:disabled {
|
||||
background-color: $light-fg-color;
|
||||
cursor: default;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Copyright 2017 Vector Creations 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_MEmoteBody_sender {
|
||||
cursor: pointer;
|
||||
}
|
|
@ -130,6 +130,23 @@ limitations under the License.
|
|||
color: $event-notsent-color;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.mx_EventTile_highlight,
|
||||
.mx_EventTile_highlight .markdown-body
|
||||
{
|
||||
|
@ -251,6 +268,12 @@ limitations under the License.
|
|||
padding-left: 60px;
|
||||
}
|
||||
|
||||
.mx_EventTile_selected.mx_EventTile_info .mx_EventTile_line,
|
||||
.mx_EventTile:hover.mx_EventTile_verified.mx_EventTile_info .mx_EventTile_line,
|
||||
.mx_EventTile:hover.mx_EventTile_unverified.mx_EventTile_info .mx_EventTile_line {
|
||||
padding-left: 78px;
|
||||
}
|
||||
|
||||
.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line {
|
||||
border-left: $e2e-verified-color 5px solid;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ limitations under the License.
|
|||
.mx_LinkPreviewWidget_title {
|
||||
display: inline;
|
||||
font-weight: bold;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.mx_LinkPreviewWidget_siteName {
|
||||
|
|
|
@ -48,11 +48,10 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_MemberInfo_avatar .mx_BaseAvatar {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.mx_MemberInfo_avatar .mx_BaseAvatar.mx_BaseAvatar_image {
|
||||
cursor: pointer;
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
.mx_MemberInfo_profile {
|
||||
|
|
|
@ -28,7 +28,7 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_MemberList .mx_Spinner {
|
||||
flex: 0;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.mx_MemberList_chevron {
|
||||
|
|
|
@ -22,6 +22,8 @@ limitations under the License.
|
|||
flex-direction: column;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
background-color: $preview-bar-bg-color;
|
||||
-webkit-align-items: center;
|
||||
}
|
||||
|
||||
.mx_RoomPreviewBar_wrapper {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -20,6 +21,7 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_RoomSettings_leaveButton,
|
||||
.mx_RoomSettings_unbanButton,
|
||||
.mx_RoomSettings_integrationsButton,
|
||||
.mx_RoomSettings_integrationsButton_error {
|
||||
position: relative;
|
||||
|
@ -30,11 +32,15 @@ limitations under the License.
|
|||
color: $accent-fg-color;
|
||||
line-height: 34px;
|
||||
text-align: center;
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
.mx_RoomSettings_leaveButton,
|
||||
.mx_RoomSettings_integrationsButton,
|
||||
.mx_RoomSettings_integrationsButton_error {
|
||||
float: right;
|
||||
}
|
||||
.mx_RoomSettings_integrationsButton_error {
|
||||
pointer: not-allowed;
|
||||
}
|
||||
|
@ -50,6 +56,9 @@ limitations under the License.
|
|||
background-color: $accent-color;
|
||||
color: $accent-fg-color;
|
||||
}
|
||||
.mx_RoomSettings_unbanButton {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_e2eIcon {
|
||||
padding-left: 4px;
|
||||
|
|
|
@ -59,41 +59,6 @@ limitations under the License.
|
|||
z-index: 2;
|
||||
}
|
||||
|
||||
.mx_RoomTile:hover .mx_RoomTile_avatar_container:before,
|
||||
.mx_RoomTile_avatar_container.mx_RoomTile_avatar_roomTagMenu:before {
|
||||
display: block;
|
||||
position: absolute;
|
||||
content: "";
|
||||
border-radius: 40px;
|
||||
background-image: url("../../img/icons_ellipsis.svg");
|
||||
background-size: 25px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.mx_RoomTile:hover .mx_RoomTile_avatar_container:after,
|
||||
.mx_RoomTile_avatar_container.mx_RoomTile_avatar_roomTagMenu:after {
|
||||
display: block;
|
||||
position: absolute;
|
||||
content: "";
|
||||
border-radius: 40px;
|
||||
background: $primary-fg-color;
|
||||
bottom: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
opacity: 0.6;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.collapsed .mx_RoomTile:hover .mx_RoomTile_avatar_container:before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.collapsed .mx_RoomTile:hover .mx_RoomTile_avatar_container:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_RoomTile_name {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
@ -164,13 +129,13 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_RoomTile .mx_RoomTile_badge.mx_RoomTile_badgeButton,
|
||||
.mx_RoomTile.mx_RoomTile_notificationStateMenu .mx_RoomTile_badge {
|
||||
.mx_RoomTile.mx_RoomTile_menuDisplayed .mx_RoomTile_badge {
|
||||
letter-spacing: 0.1em;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.mx_RoomTile.mx_RoomTile_noBadges .mx_RoomTile_badge.mx_RoomTile_badgeButton,
|
||||
.mx_RoomTile.mx_RoomTile_notificationStateMenu.mx_RoomTile_noBadges .mx_RoomTile_badge {
|
||||
.mx_RoomTile.mx_RoomTile_menuDisplayed.mx_RoomTile_noBadges .mx_RoomTile_badge {
|
||||
background-color: $neutral-badge-color;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,11 +20,17 @@ limitations under the License.
|
|||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px solid $primary-hairline-color;
|
||||
|
||||
/* in absence of img */
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.mx_TopUnreadMessagesBar_scrollUp {
|
||||
display: inline;
|
||||
cursor: pointer;
|
||||
|
||||
/* in absence of img */
|
||||
padding-left: 65px;
|
||||
}
|
||||
|
||||
.mx_TopUnreadMessagesBar_scrollUp img {
|
||||
|
|
|
@ -24,7 +24,7 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_IntegrationsManager iframe {
|
||||
background-color: $primary-bg-color;
|
||||
background-color: #fff;
|
||||
border: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
|
|
@ -18,6 +18,8 @@ $selection-fg-color: $primary-bg-color;
|
|||
// red warning colour
|
||||
$warning-color: #ff0064;
|
||||
|
||||
$preview-bar-bg-color: #f7f7f7;
|
||||
|
||||
// left-panel style muted accent color
|
||||
$secondary-accent-color: #eaf5f0;
|
||||
|
||||
|
@ -72,6 +74,9 @@ $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);
|
||||
|
||||
// ********************
|
||||
|
||||
$roomtile-name-color: rgba(69, 69, 69, 0.8);
|
||||
|
@ -88,6 +93,9 @@ $event-encrypting-color: #abddbc;
|
|||
$event-sending-color: #ddd;
|
||||
$event-notsent-color: #f44;
|
||||
|
||||
// event redaction
|
||||
$event-redacted-img: url('../../img/redacted.jpg');
|
||||
|
||||
// event timestamp
|
||||
$event-timestamp-color: #acacac;
|
||||
|
||||
|
|
|
@ -13,11 +13,13 @@ $light-fg-color: #747474;
|
|||
$accent-fg-color: $primary-bg-color;
|
||||
$accent-color: #76CFA6;
|
||||
|
||||
$selection-fg-color: $primary-bg-color;
|
||||
$selection-fg-color: $primary-fg-color;
|
||||
|
||||
// red warning colour
|
||||
$warning-color: #ff0064;
|
||||
|
||||
$preview-bar-bg-color: #333;
|
||||
|
||||
// left-panel style muted accent color
|
||||
$secondary-accent-color: $primary-bg-color;
|
||||
|
||||
|
@ -28,7 +30,7 @@ $plinth-bg-color: #474747;
|
|||
$droptarget-bg-color: rgba(45,45,45,0.5);
|
||||
|
||||
// used by AddressSelector
|
||||
$selected-color: #eaf5f0;
|
||||
$selected-color: #000000;
|
||||
|
||||
// selected for hoverover & selected event tiles
|
||||
$event-selected-color: #353535;
|
||||
|
@ -72,6 +74,9 @@ $settings-grey-fg-color: #a2a2a2;
|
|||
$voip-decline-color: #f48080;
|
||||
$voip-accept-color: #80f480;
|
||||
|
||||
$rte-bg-color: #353535;
|
||||
$rte-code-bg-color: #000;
|
||||
|
||||
// ********************
|
||||
|
||||
$roomtile-name-color: rgba(186, 186, 186, 0.8);
|
||||
|
@ -85,9 +90,12 @@ $roomsublist-label-bg-color: #454545;
|
|||
|
||||
// event tile lifecycle
|
||||
$event-encrypting-color: rgba(171, 221, 188, 0.4);
|
||||
$event-sending-color: #ddd;
|
||||
$event-sending-color: #888;
|
||||
$event-notsent-color: #f44;
|
||||
|
||||
// event redaction
|
||||
$event-redacted-img: url('../../img/redacted-dark.jpg');
|
||||
|
||||
// event timestamp
|
||||
$event-timestamp-color: #acacac;
|
||||
|
||||
|
@ -110,18 +118,30 @@ $progressbar-color: #000;
|
|||
// better match the theme. Typically applied to dark grey 'off' buttons or
|
||||
// light grey 'on' buttons.
|
||||
.mx_filterFlipColor {
|
||||
filter: invert();
|
||||
filter: invert(1);
|
||||
}
|
||||
|
||||
.gm-scrollbar .thumb {
|
||||
filter: invert();
|
||||
filter: invert(1);
|
||||
}
|
||||
|
||||
.mx_EventTile_content .markdown-body pre,
|
||||
.mx_EventTile_content .markdown-body code {
|
||||
filter: invert();
|
||||
}
|
||||
// markdown overrides:
|
||||
.mx_EventTile_content .markdown-body {
|
||||
pre, code {
|
||||
filter: invert(1);
|
||||
}
|
||||
|
||||
.mx_EventTile_content .markdown-body pre code {
|
||||
pre code {
|
||||
filter: none;
|
||||
}
|
||||
|
||||
table {
|
||||
tr {
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
tr:nth-child(2n) {
|
||||
background-color: #080808;
|
||||
}
|
||||
}
|
||||
}
|
34
src/skins/vector/css/vector-web/structures/_HomePage.scss
Normal file
34
src/skins/vector/css/vector-web/structures/_HomePage.scss
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
Copyright 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations 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_HomePage {
|
||||
max-width: 960px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-y: hidden;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.mx_HomePage iframe {
|
||||
width: 100%;
|
||||
height: 90%;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.mx_HomePage_body {
|
||||
margin-left: 63px;
|
||||
}
|
|
@ -64,6 +64,7 @@ limitations under the License.
|
|||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mx_LeftPanel .mx_BottomLeftMenu_homePage,
|
||||
.mx_LeftPanel .mx_BottomLeftMenu_directory,
|
||||
.mx_LeftPanel .mx_BottomLeftMenu_createRoom,
|
||||
.mx_LeftPanel .mx_BottomLeftMenu_people,
|
||||
|
@ -72,6 +73,7 @@ limitations under the License.
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.collapsed .mx_BottomLeftMenu_homePage,
|
||||
.collapsed .mx_BottomLeftMenu_directory,
|
||||
.collapsed .mx_BottomLeftMenu_createRoom,
|
||||
.collapsed .mx_BottomLeftMenu_people,
|
||||
|
@ -81,6 +83,7 @@ limitations under the License.
|
|||
padding-bottom: 3px ! important;
|
||||
}
|
||||
|
||||
.mx_LeftPanel .mx_BottomLeftMenu_homePage,
|
||||
.mx_LeftPanel .mx_BottomLeftMenu_directory,
|
||||
.mx_LeftPanel .mx_BottomLeftMenu_createRoom,
|
||||
.mx_LeftPanel .mx_BottomLeftMenu_people {
|
||||
|
|
|
@ -42,7 +42,7 @@ limitations under the License.
|
|||
|
||||
.mx_RightPanel_headerButton {
|
||||
cursor: pointer;
|
||||
flex: 0;
|
||||
flex: 0 0 auto;
|
||||
vertical-align: top;
|
||||
padding-left: 4px;
|
||||
padding-right: 5px;
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
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_NotificationStateContextMenu_picker {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: 5px;
|
||||
}
|
||||
|
||||
.mx_NotificationStateContextMenu_field {
|
||||
padding-top: 4px;
|
||||
padding-right: 6px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 8px; /* 20px */
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mx_NotificationStateContextMenu_field.mx_NotificationStateContextMenu_fieldSet {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mx_NotificationStateContextMenu_field.mx_NotificationStateContextMenu_fieldDisabled {
|
||||
color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.mx_NotificationStateContextMenu_icon {
|
||||
padding-right: 4px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.mx_NotificationStateContextMenu_activeIcon {
|
||||
display: inline-block;
|
||||
opacity: 0;
|
||||
position: relative;
|
||||
left: -5px;
|
||||
}
|
||||
|
||||
.mx_NotificationStateContextMenu_fieldSet .mx_NotificationStateContextMenu_activeIcon {
|
||||
opacity: 1;
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
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_RoomTagContextMenu_field {
|
||||
padding-top: 8px;
|
||||
padding-right: 20px;
|
||||
padding-bottom: 8px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_field:first-child {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_field:last-child {
|
||||
padding-bottom: 4px;
|
||||
color: $warning-color;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_field.mx_RoomTagContextMenu_fieldSet {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_field.mx_RoomTagContextMenu_fieldSet .mx_RoomTagContextMenu_icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_field.mx_RoomTagContextMenu_fieldSet .mx_RoomTagContextMenu_icon_set {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_field.mx_RoomTagContextMenu_fieldDisabled {
|
||||
color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_icon {
|
||||
padding-right: 8px;
|
||||
padding-left: 4px;
|
||||
display: inline-block
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_icon_set {
|
||||
padding-right: 8px;
|
||||
padding-left: 4px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_separator {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
border-right-style: none;
|
||||
border-top-style: solid;
|
||||
border-top-width: 1px;
|
||||
border-color: $menu-border-color;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_fieldSet .mx_RoomTagContextMenu_icon {
|
||||
/* Something to indicate that the icon is the set tag */
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
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_RoomTileContextMenu_tag_field, .mx_RoomTileContextMenu_leave {
|
||||
padding-top: 8px;
|
||||
padding-right: 20px;
|
||||
padding-bottom: 8px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldSet {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldSet .mx_RoomTileContextMenu_tag_icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldSet .mx_RoomTileContextMenu_tag_icon_set {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldDisabled {
|
||||
color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_tag_icon {
|
||||
padding-right: 8px;
|
||||
padding-left: 4px;
|
||||
display: inline-block
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_tag_icon_set {
|
||||
padding-right: 8px;
|
||||
padding-left: 4px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_separator {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
border-right-style: none;
|
||||
border-top-style: solid;
|
||||
border-top-width: 1px;
|
||||
border-color: $menu-border-color;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_leave {
|
||||
color: $warning-color;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_tag_fieldSet .mx_RoomTileContextMenu_tag_icon {
|
||||
/* Something to indicate that the icon is the set tag */
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_notif_picker {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: 5px;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_notif_field {
|
||||
padding-top: 4px;
|
||||
padding-right: 6px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 8px; /* 20px */
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_notif_field.mx_RoomTileContextMenu_notif_fieldSet {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_notif_field.mx_RoomTileContextMenu_notif_fieldDisabled {
|
||||
color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_notif_icon {
|
||||
padding-right: 4px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_notif_activeIcon {
|
||||
display: inline-block;
|
||||
opacity: 0;
|
||||
position: relative;
|
||||
left: -5px;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_notif_fieldSet .mx_RoomTileContextMenu_notif_activeIcon {
|
||||
opacity: 1;
|
||||
}
|
|
@ -44,6 +44,9 @@ limitations under the License.
|
|||
line-height: 35px;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.mx_NetworkDropdown_networkoption img {
|
||||
|
|
|
@ -38,21 +38,12 @@ limitations under the License.
|
|||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
.mx_RoomDropTarget_avatar {
|
||||
background-color: $primary-bg-color;
|
||||
border-radius: 24px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
float: left;
|
||||
margin-left: 7px;
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
.mx_RoomDropTarget_label {
|
||||
position: relative;
|
||||
margin-top: 3px;
|
||||
line-height: 21px;
|
||||
z-index: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.collapsed .mx_RoomDropTarget_avatar {
|
||||
|
|
27
src/skins/vector/img/icons-home.svg
Normal file
27
src/skins/vector/img/icons-home.svg
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?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" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 25 25" style="enable-background:new 0 0 25 25;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st1{fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||
</style>
|
||||
<g id="Layer_1">
|
||||
<title>81230A28-D944-4572-B5DB-C03CAA2B1FCA</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<g id="Symbols">
|
||||
<g id="Left-nav-default" transform="translate(-50.000000, -725.000000)">
|
||||
<g id="Left-panel">
|
||||
<g>
|
||||
<g id="icons_people" transform="translate(50.000000, 725.000000)">
|
||||
<path id="Oval-1-Copy-7" fill="#76cfa6" d="M12.5,25C19.4,25,25,19.4,25,12.5S19.4,0,12.5,0S0,5.6,0,12.5S5.6,25,12.5,25z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Layer_2">
|
||||
<rect x="7.8" y="10.7" class="st1" stroke="#ffffff" width="9.4" height="7.4"/>
|
||||
<polygon class="st1" stroke="#ffffff" points="12.5,6 6.2,10.7 18.8,10.7 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/skins/vector/img/redacted-dark.jpg
Normal file
BIN
src/skins/vector/img/redacted-dark.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
BIN
src/skins/vector/img/redacted.jpg
Normal file
BIN
src/skins/vector/img/redacted.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
|
@ -37,7 +37,18 @@
|
|||
<body style="height: 100%;">
|
||||
<section id="matrixchat" style="height: 100%;"></section>
|
||||
<noscript>Sorry, Riot requires JavaScript to be enabled.</noscript>
|
||||
<% for (var i=0; i < htmlWebpackPlugin.files.js.length; i++) {%>
|
||||
<% for (var i=0; i < htmlWebpackPlugin.files.js.length; i++) {
|
||||
// Not a particularly graceful way of not putting the indexeddb worker script
|
||||
// into the main page
|
||||
if (_.endsWith(htmlWebpackPlugin.files.js[i], 'indexeddb-worker.js')) {
|
||||
%>
|
||||
<script>
|
||||
window.vector_indexeddb_worker_script = '<%= htmlWebpackPlugin.files.js[i] %>';
|
||||
</script>
|
||||
<%
|
||||
continue;
|
||||
}
|
||||
%>
|
||||
<script src="<%= htmlWebpackPlugin.files.js[i] %>"></script>
|
||||
<% } %>
|
||||
<img src="img/warning.svg" width="24" height="23" style="visibility: hidden; position: absolute; top: 0px; left: 0px;"/>
|
||||
|
@ -62,24 +73,5 @@
|
|||
<source src="media/busy.mp3" type="audio/mpeg" />
|
||||
</audio>
|
||||
<audio id="remoteAudio"/>
|
||||
<script>
|
||||
if (
|
||||
window.location.host === 'www.vector.im' ||
|
||||
window.location.host === 'vector.im' ||
|
||||
window.location.host === 'www.riot.im' ||
|
||||
window.location.host === 'riot.im'
|
||||
) {
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-54779209-2', 'auto');
|
||||
ga('send', 'pageview', window.location.pathname + window.location.search + window.location.hash);
|
||||
}
|
||||
else {
|
||||
var ga = null;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -49,7 +50,7 @@ rageshake.init().then(() => {
|
|||
// access via the console
|
||||
global.React = require("react");
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
global.ReactPerf = require("react-addons-perf");
|
||||
global.Perf = require("react-addons-perf");
|
||||
}
|
||||
|
||||
var RunModernizrTests = require("./modernizr"); // this side-effects a global
|
||||
|
@ -67,11 +68,15 @@ import url from 'url';
|
|||
import {parseQs, parseQsFromFragment} from './url_utils';
|
||||
import Platform from './platform';
|
||||
|
||||
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
|
||||
|
||||
var lastLocationHashSet = null;
|
||||
|
||||
var CallHandler = require("matrix-react-sdk/lib/CallHandler");
|
||||
CallHandler.setConferenceHandler(VectorConferenceHandler);
|
||||
|
||||
MatrixClientPeg.setIndexedDbWorkerScript(window.vector_indexeddb_worker_script);
|
||||
|
||||
function checkBrowserFeatures(featureList) {
|
||||
if (!window.Modernizr) {
|
||||
console.error("Cannot check features - Modernizr global is missing.");
|
||||
|
@ -101,15 +106,24 @@ var validBrowser = checkBrowserFeatures([
|
|||
"objectfit"
|
||||
]);
|
||||
|
||||
// Parse the given window.location and return parameters that can be used when calling
|
||||
// MatrixChat.showScreen(screen, params)
|
||||
function getScreenFromLocation(location) {
|
||||
const fragparts = parseQsFromFragment(location);
|
||||
return {
|
||||
screen: fragparts.location.substring(1),
|
||||
params: fragparts.params,
|
||||
}
|
||||
}
|
||||
|
||||
// Here, we do some crude URL analysis to allow
|
||||
// deep-linking.
|
||||
function routeUrl(location) {
|
||||
if (!window.matrixChat) return;
|
||||
|
||||
console.log("Routing URL "+location);
|
||||
var fragparts = parseQsFromFragment(location);
|
||||
window.matrixChat.showScreen(fragparts.location.substring(1),
|
||||
fragparts.params);
|
||||
console.log("Routing URL ", location.href);
|
||||
const s = getScreenFromLocation(location);
|
||||
window.matrixChat.showScreen(s.screen, s.params);
|
||||
}
|
||||
|
||||
function onHashChange(ev) {
|
||||
|
@ -120,23 +134,13 @@ function onHashChange(ev) {
|
|||
routeUrl(window.location);
|
||||
}
|
||||
|
||||
var loaded = false;
|
||||
var lastLoadedScreen = null;
|
||||
|
||||
// This will be called whenever the SDK changes screens,
|
||||
// so a web page can update the URL bar appropriately.
|
||||
var onNewScreen = function(screen) {
|
||||
console.log("newscreen "+screen);
|
||||
// just remember the most recent screen while we are loading, so that the
|
||||
// user doesn't see the URL bar doing a dance
|
||||
if (!loaded) {
|
||||
lastLoadedScreen = screen;
|
||||
} else {
|
||||
var hash = '#/' + screen;
|
||||
lastLocationHashSet = hash;
|
||||
window.location.hash = hash;
|
||||
if (ga) ga('send', 'pageview', window.location.pathname + window.location.search + window.location.hash);
|
||||
}
|
||||
}
|
||||
|
||||
// We use this to work out what URL the SDK should
|
||||
|
@ -148,16 +152,30 @@ var onNewScreen = function(screen) {
|
|||
// If we're in electron, we should never pass through a file:// URL otherwise
|
||||
// the identity server will try to 302 the browser to it, which breaks horribly.
|
||||
// so in that instance, hardcode to use riot.im/app for now instead.
|
||||
var makeRegistrationUrl = function() {
|
||||
var makeRegistrationUrl = function(params) {
|
||||
let url;
|
||||
if (window.location.protocol === "file:") {
|
||||
return 'https://riot.im/app/#/register';
|
||||
}
|
||||
else {
|
||||
return window.location.protocol + '//' +
|
||||
url = 'https://riot.im/app/#/register';
|
||||
} else {
|
||||
url = (
|
||||
window.location.protocol + '//' +
|
||||
window.location.host +
|
||||
window.location.pathname +
|
||||
'#/register';
|
||||
'#/register'
|
||||
);
|
||||
}
|
||||
|
||||
const keys = Object.keys(params);
|
||||
for (let i = 0; i < keys.length; ++i) {
|
||||
if (i == 0) {
|
||||
url += '?';
|
||||
} else {
|
||||
url += '&';
|
||||
}
|
||||
const k = keys[i];
|
||||
url += k + '=' + encodeURIComponent(params[k]);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
window.addEventListener('hashchange', onHashChange);
|
||||
|
@ -254,31 +272,22 @@ async function loadApp() {
|
|||
} else if (validBrowser) {
|
||||
UpdateChecker.start();
|
||||
|
||||
var MatrixChat = sdk.getComponent('structures.MatrixChat');
|
||||
|
||||
const MatrixChat = sdk.getComponent('structures.MatrixChat');
|
||||
window.matrixChat = ReactDOM.render(
|
||||
<MatrixChat
|
||||
onNewScreen={onNewScreen}
|
||||
registrationUrl={makeRegistrationUrl()}
|
||||
makeRegistrationUrl={makeRegistrationUrl}
|
||||
ConferenceHandler={VectorConferenceHandler}
|
||||
config={configJson}
|
||||
realQueryParams={params}
|
||||
startingFragmentQueryParams={fragparts.params}
|
||||
enableGuest={true}
|
||||
onLoadCompleted={onLoadCompleted}
|
||||
initialScreenAfterLogin={getScreenFromLocation(window.location)}
|
||||
defaultDeviceDisplayName={PlatformPeg.get().getDefaultDeviceDisplayName()}
|
||||
/>,
|
||||
document.getElementById('matrixchat')
|
||||
);
|
||||
|
||||
routeUrl(window.location);
|
||||
|
||||
// we didn't propagate screen changes to the URL bar while we were loading; do it now.
|
||||
loaded = true;
|
||||
if (lastLoadedScreen) {
|
||||
onNewScreen(lastLoadedScreen);
|
||||
lastLoadedScreen = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.error("Browser is missing required features.");
|
||||
|
|
21
src/vector/indexedbd-worker.js
Normal file
21
src/vector/indexedbd-worker.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
Copyright 2017 Vector Creations 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.
|
||||
*/
|
||||
|
||||
import {IndexedDBStoreWorker} from 'matrix-js-sdk/lib/indexeddb-worker.js';
|
||||
|
||||
const remoteWorker = new IndexedDBStoreWorker(postMessage);
|
||||
|
||||
onmessage = remoteWorker.onMessage;
|
|
@ -139,4 +139,8 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
|||
requestNotificationPermission() : Promise {
|
||||
return q('granted');
|
||||
}
|
||||
|
||||
reload() {
|
||||
electron.remote.getCurrentWebContents().reload();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -206,4 +206,10 @@ export default class WebPlatform extends VectorBasePlatform {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
reload() {
|
||||
// forceReload=false since we don't really need new HTML/JS files
|
||||
// we just need to restart the JS runtime.
|
||||
window.location.reload(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -314,17 +314,24 @@ class IndexedDBLogStore {
|
|||
let size = 0;
|
||||
for (let i = 0; i < allLogIds.length; i++) {
|
||||
let lines = await fetchLogs(allLogIds[i]);
|
||||
|
||||
// always include at least one log file, but only include
|
||||
// subsequent ones if they won't take us over the MAX_LOG_SIZE
|
||||
if (i > 0 && size + lines.length > MAX_LOG_SIZE) {
|
||||
// the remaining log IDs should be removed. If we go out of
|
||||
// bounds this is just []
|
||||
//
|
||||
// XXX: there's nothing stopping the current session exceeding
|
||||
// MAX_LOG_SIZE. We ought to think about culling it.
|
||||
removeLogIds = allLogIds.slice(i + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
logs.push({
|
||||
lines: lines,
|
||||
id: allLogIds[i],
|
||||
});
|
||||
size += lines.length;
|
||||
if (size > MAX_LOG_SIZE) {
|
||||
// the remaining log IDs should be removed. If we go out of
|
||||
// bounds this is just []
|
||||
removeLogIds = allLogIds.slice(i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (removeLogIds.length > 0) {
|
||||
console.log("Removing logs: ", removeLogIds);
|
||||
|
@ -481,10 +488,12 @@ module.exports = {
|
|||
text: (
|
||||
userText || "User did not supply any additional text."
|
||||
),
|
||||
app: 'riot-web',
|
||||
version: version,
|
||||
user_agent: userAgent,
|
||||
},
|
||||
json: true,
|
||||
timeout: 5 * 60 * 1000,
|
||||
}, (err, res) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
|
|
|
@ -23,6 +23,7 @@ var jssdk = require('matrix-js-sdk');
|
|||
var sdk = require('matrix-react-sdk');
|
||||
var peg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||
var PageTypes = require('matrix-react-sdk/lib/PageTypes');
|
||||
var MatrixChat = sdk.getComponent('structures.MatrixChat');
|
||||
var RoomDirectory = sdk.getComponent('structures.RoomDirectory');
|
||||
var RoomPreviewBar = sdk.getComponent('rooms.RoomPreviewBar');
|
||||
|
@ -90,12 +91,13 @@ describe('joining a room', function () {
|
|||
matrixChat = ReactDOM.render(mc, parentDiv);
|
||||
|
||||
// switch to the Directory
|
||||
dis.dispatch({
|
||||
action: 'view_room_directory',
|
||||
});
|
||||
matrixChat._setPage(PageTypes.RoomDirectory);
|
||||
|
||||
var roomView;
|
||||
httpBackend.flush().then(() => {
|
||||
// wait for /sync to happen
|
||||
return q.delay(1).then(() => {
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
var roomDir = ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, RoomDirectory);
|
||||
|
||||
|
|
|
@ -104,6 +104,23 @@ describe('loading:', function () {
|
|||
}
|
||||
}
|
||||
|
||||
// Parse the given window.location and return parameters that can be used when calling
|
||||
// MatrixChat.showScreen(screen, params)
|
||||
function getScreenFromLocation(location) {
|
||||
const fragparts = parseQsFromFragment(location);
|
||||
return {
|
||||
screen: fragparts.location.substring(1),
|
||||
params: fragparts.params,
|
||||
}
|
||||
}
|
||||
|
||||
function routeUrl(location, matrixChat) {
|
||||
console.log(Date.now() + "Routing URL " + location);
|
||||
const s = getScreenFromLocation(location);
|
||||
console.log("Showing screen", s);
|
||||
matrixChat.showScreen(s.screen, s.params);
|
||||
}
|
||||
|
||||
const MatrixChat = sdk.getComponent('structures.MatrixChat');
|
||||
const fragParts = parseQsFromFragment(windowLocation);
|
||||
var params = parseQs(windowLocation);
|
||||
|
@ -118,16 +135,10 @@ describe('loading:', function () {
|
|||
startingFragmentQueryParams={fragParts.params}
|
||||
enableGuest={true}
|
||||
onLoadCompleted={loadCompleteDefer.resolve}
|
||||
initialScreenAfterLogin={getScreenFromLocation(windowLocation)}
|
||||
/>, parentDiv
|
||||
);
|
||||
|
||||
function routeUrl(location, matrixChat) {
|
||||
console.log(Date.now() + " Routing URL "+location);
|
||||
var fragparts = parseQsFromFragment(location);
|
||||
matrixChat.showScreen(fragparts.location.substring(1),
|
||||
fragparts.params);
|
||||
}
|
||||
|
||||
// pause for a cycle, then simulate the window.onload handler
|
||||
window.setTimeout(() => {
|
||||
console.log(Date.now() + " simulating window.onload");
|
||||
|
@ -188,15 +199,17 @@ describe('loading:', function () {
|
|||
let login = ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('structures.login.Login'));
|
||||
httpBackend.when('POST', '/login').check(function(req) {
|
||||
console.log(req);
|
||||
expect(req.data.type).toEqual('m.login.password');
|
||||
expect(req.data.user).toEqual('user');
|
||||
expect(req.data.identifier.type).toEqual('m.id.user');
|
||||
expect(req.data.identifier.user).toEqual('user');
|
||||
expect(req.data.password).toEqual('pass');
|
||||
}).respond(200, {
|
||||
user_id: '@user:id',
|
||||
device_id: 'DEVICE_ID',
|
||||
access_token: 'access_token',
|
||||
});
|
||||
login.onPasswordLogin("user", "pass")
|
||||
login.onPasswordLogin("user", undefined, undefined, "pass")
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// Wait for another trip around the event loop for the UI to update
|
||||
|
@ -474,7 +487,8 @@ function awaitRoomView(matrixChat, retryLimit, retryCount) {
|
|||
retryCount = 0;
|
||||
}
|
||||
|
||||
if (!matrixChat.state.ready) {
|
||||
if (matrixChat.state.loading ||
|
||||
!(matrixChat.state.loggedIn && matrixChat.state.ready)) {
|
||||
console.log(Date.now() + " Awaiting room view: not ready yet.");
|
||||
if (retryCount >= retryLimit) {
|
||||
throw new Error("MatrixChat still not ready after " +
|
||||
|
|
|
@ -6,6 +6,7 @@ var HtmlWebpackPlugin = require('html-webpack-plugin');
|
|||
module.exports = {
|
||||
entry: {
|
||||
"bundle": "./src/vector/index.js",
|
||||
"indexeddb-worker": "./src/vector/indexedbd-worker.js",
|
||||
|
||||
// We ship olm.js as a separate lump of javascript. This makes it get
|
||||
// loaded via a separate <script/> tag in index.html (which loads it
|
||||
|
|
Loading…
Reference in a new issue