mirror of
https://github.com/SchildiChat/element-web.git
synced 2024-10-01 01:26:12 -04:00
Merge branch 'develop'
This commit is contained in:
commit
04b51f6f0f
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,3 +1,8 @@
|
||||
node_modules
|
||||
vector/bundle.*
|
||||
lib
|
||||
.DS_Store
|
||||
key.pem
|
||||
cert.pem
|
||||
vector/components.css
|
||||
packages/
|
||||
|
14
.modernizr.json
Normal file
14
.modernizr.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"minify": true,
|
||||
"classPrefix": "modernizr_",
|
||||
"options": [
|
||||
"setClasses"
|
||||
],
|
||||
"feature-detects": [
|
||||
"test/css/displaytable",
|
||||
"test/css/flexbox",
|
||||
"test/es5/specification",
|
||||
"test/css/objectfit",
|
||||
"test/storage/localstorage"
|
||||
]
|
||||
}
|
@ -7,3 +7,6 @@ include:
|
||||
|
||||
* https://github.com/neko259
|
||||
Improved scrollbar CSS
|
||||
|
||||
* Florent VIOLLEAU (https://github.com/floviolleau) <floviolleau at gmail dot com>
|
||||
Improve README.md for a better understanding of installation instructions
|
||||
|
129
README.md
129
README.md
@ -9,18 +9,37 @@ Getting started
|
||||
===============
|
||||
|
||||
1. Install or update `node.js` so that your `npm` is at least at version `2.0.0`
|
||||
2. Clone the repo: `git clone https://github.com/vector-im/vector-web.git`
|
||||
3. Switch to the SDK directory: `cd vector-web`
|
||||
4. Install the prerequisites: `npm install`
|
||||
5. Start the development builder and a testing server: `npm start`
|
||||
6. Wait a few seconds for the initial build to finish.
|
||||
7. Open http://127.0.0.1:8080/ in your browser to see your newly built Vector.
|
||||
1. Clone the repo: `git clone https://github.com/vector-im/vector-web.git`
|
||||
1. Switch to the vector directory: `cd vector-web`
|
||||
1. Install the prerequisites: `npm install`
|
||||
1. Start the development builder and a testing server: `npm start`
|
||||
1. Wait a few seconds for the initial build to finish (the command won't
|
||||
terminate: it's running a web server for you).
|
||||
1. Open http://127.0.0.1:8080/ in your browser to see your newly built Vector.
|
||||
|
||||
With `npm start`, any changes you make to the source files will cause a rebuild so
|
||||
your changes will show up when you refresh.
|
||||
your changes will show up when you refresh. This development server also disables
|
||||
caching, so do NOT use it in production.
|
||||
|
||||
Configuring
|
||||
===========
|
||||
|
||||
Configure the app by modifying the `config.json` file:
|
||||
|
||||
1. `default_hs_url` is the default home server url.
|
||||
1. `default_is_url` is the default identity server url (this is the server used
|
||||
for verifying third party identifiers like email addresses). If this is blank,
|
||||
registering with an email address or adding an email address to your account
|
||||
will not work.
|
||||
|
||||
You will need to re-run `npm run build` after editing `config.json`.
|
||||
|
||||
Deployment
|
||||
==========
|
||||
|
||||
For production use, run `npm run build` to build all the necessary files
|
||||
into the `vector` directory and run your own server.
|
||||
into the `vector` directory. You can then mount the vector directory on
|
||||
your webserver to actually serve up the app, which is entirely static content.
|
||||
|
||||
Development
|
||||
===========
|
||||
@ -30,31 +49,89 @@ setup above, and your changes will cause an instant rebuild.
|
||||
|
||||
However, all serious development on Vector happens on the `develop` branch. This typically
|
||||
depends on the `develop` snapshot versions of `matrix-react-sdk` and `matrix-js-sdk`
|
||||
too, which isn't expressed in Vector's `package.json`. To do this, check out
|
||||
the `develop` branches of these libraries and then use `npm link` to tell Vector
|
||||
about them:
|
||||
too, which can't be installed automatically due to https://github.com/npm/npm/issues/3055.
|
||||
To get the right dependencies, check out the `develop` branches of these libraries and
|
||||
then use `ln -s` to tell Vector about them:
|
||||
|
||||
[Be aware that there may be problems with this process under npm version 3.]
|
||||
|
||||
First clone and build `matrix-js-sdk`:
|
||||
|
||||
1. `git clone git@github.com:matrix-org/matrix-js-sdk.git`
|
||||
1. `pushd matrix-js-sdk`
|
||||
1. `git checkout develop`
|
||||
1. `npm install`
|
||||
1. `npm install source-map-loader` # because webpack is made of fail (https://github.com/webpack/webpack/issues/1472)
|
||||
1. `popd`
|
||||
|
||||
Then similarly with `matrix-react-sdk`:
|
||||
|
||||
1. `git clone git@github.com:matrix-org/matrix-react-sdk.git`
|
||||
2. `cd matrix-react-sdk`
|
||||
3. `git checkout develop`
|
||||
4. `npm install`
|
||||
5. `npm start` (to start the dev rebuilder)
|
||||
6. `cd ../vector-web`
|
||||
7. Link the react sdk package into the example:
|
||||
`npm link path/to/your/react/sdk`
|
||||
1. `pushd matrix-react-sdk`
|
||||
1. `git checkout develop`
|
||||
1. `npm install`
|
||||
1. `rm -r node_modules/matrix-js-sdk; ln -s ../../matrix-js-sdk node_modules/`
|
||||
1. `popd`
|
||||
|
||||
Similarly, you may need to `npm link path/to/your/js/sdk` in your `matrix-react-sdk`
|
||||
directory.
|
||||
Finally, build and start vector itself:
|
||||
|
||||
1. `git clone git@github.com:vector-im/vector-web.git`
|
||||
1. `cd vector-web`
|
||||
1. `git checkout develop`
|
||||
1. `npm install`
|
||||
1. `rm -r node_modules/matrix-js-sdk; ln -s ../../matrix-js-sdk node_modules/`
|
||||
1. `rm -r node_modules/matrix-react-sdk; ln -s ../../matrix-react-sdk node_modules/`
|
||||
1. `npm start`
|
||||
1. Wait a few seconds for the initial build to finish; you should see something like:
|
||||
|
||||
```
|
||||
Hash: b0af76309dd56d7275c8
|
||||
Version: webpack 1.12.14
|
||||
Time: 14533ms
|
||||
Asset Size Chunks Chunk Names
|
||||
bundle.js 4.2 MB 0 [emitted] main
|
||||
bundle.css 91.5 kB 0 [emitted] main
|
||||
bundle.js.map 5.29 MB 0 [emitted] main
|
||||
bundle.css.map 116 kB 0 [emitted] main
|
||||
+ 1013 hidden modules
|
||||
```
|
||||
Remember, the command will not terminate since it runs the web server
|
||||
and rebuilds source files when they change.
|
||||
1. Open http://127.0.0.1:8080/ in your browser to see your newly built Vector.
|
||||
|
||||
When you make changes to `matrix-js-sdk` or `matrix-react-sdk`, you will need
|
||||
to run `npm run build` in the relevant directory. You can do this automatically
|
||||
by instead running `npm start` in each directory, to start a development
|
||||
builder which will watch for changes to the files and rebuild automatically.
|
||||
|
||||
If you add or remove any components from the Vector skin, you will need to rebuild
|
||||
the skin's index by running, `npm run reskindex`.
|
||||
|
||||
You may need to run `npm i source-map-loader` in matrix-js-sdk if you get errors
|
||||
about "Cannot resolve module 'source-map-loader'" due to shortcomings in webpack.
|
||||
Enabling encryption
|
||||
===================
|
||||
|
||||
Deployment
|
||||
==========
|
||||
End-to-end encryption in Vector and Matrix is not yet considered ready for
|
||||
day-to-day use; it is experimental and should be considered only as a
|
||||
proof-of-concept. See https://matrix.org/jira/browse/SPEC-162 for an overview
|
||||
of the current progress.
|
||||
|
||||
Just run `npm build` and then mount the `vector` directory on your webserver to
|
||||
actually serve up the app, which is entirely static content.
|
||||
To build a version of vector with support for end-to-end encryption, install
|
||||
the olm module with `npm i https://matrix.org/packages/npm/olm/olm-0.1.0.tgz`
|
||||
before running `npm start`. The olm library will be detected and used if
|
||||
available.
|
||||
|
||||
To enable encryption for a room, type
|
||||
|
||||
```
|
||||
/encrypt on
|
||||
```
|
||||
|
||||
in the message bar in that room. Vector will then generate a set of keys, and
|
||||
encrypt all outgoing messages in that room. (Note that other people in that
|
||||
room will send messages in the clear unless they also `/encrypt on`.)
|
||||
|
||||
Note that historical encrypted messages cannot currently be decoded - history
|
||||
is therefore lost when the page is reloaded.
|
||||
|
||||
There is currently no visual indication of whether encryption is enabled for a
|
||||
room, or whether a particular message was encrypted.
|
||||
|
170
deploy/redeploy.py
Executable file
170
deploy/redeploy.py
Executable file
@ -0,0 +1,170 @@
|
||||
#!/usr/bin/env python
|
||||
from __future__ import print_function
|
||||
import json, requests, tarfile, argparse, os, errno
|
||||
from urlparse import urljoin
|
||||
from flask import Flask, jsonify, request, abort
|
||||
app = Flask(__name__)
|
||||
|
||||
arg_jenkins_url, arg_extract_path, arg_should_clean, arg_symlink = (
|
||||
None, None, None, None
|
||||
)
|
||||
|
||||
def download_file(url):
|
||||
local_filename = url.split('/')[-1]
|
||||
r = requests.get(url, stream=True)
|
||||
with open(local_filename, 'wb') as f:
|
||||
for chunk in r.iter_content(chunk_size=1024):
|
||||
if chunk: # filter out keep-alive new chunks
|
||||
f.write(chunk)
|
||||
return local_filename
|
||||
|
||||
def untar_to(tarball, dest):
|
||||
with tarfile.open(tarball) as tar:
|
||||
tar.extractall(dest)
|
||||
|
||||
def create_symlink(source, linkname):
|
||||
try:
|
||||
os.symlink(source, linkname)
|
||||
except OSError, e:
|
||||
if e.errno == errno.EEXIST:
|
||||
# atomic modification
|
||||
os.symlink(source, linkname + ".tmp")
|
||||
os.rename(linkname + ".tmp", linkname)
|
||||
else:
|
||||
raise e
|
||||
|
||||
@app.route("/", methods=["POST"])
|
||||
def on_receive_jenkins_poke():
|
||||
# {
|
||||
# "name": "VectorWebDevelop",
|
||||
# "build": {
|
||||
# "number": 8
|
||||
# }
|
||||
# }
|
||||
incoming_json = request.get_json()
|
||||
if not incoming_json:
|
||||
abort(400, "No JSON provided!")
|
||||
return
|
||||
print("Incoming JSON: %s" % (incoming_json,))
|
||||
|
||||
job_name = incoming_json.get("name")
|
||||
if not isinstance(job_name, basestring):
|
||||
abort(400, "Bad job name: %s" % (job_name,))
|
||||
return
|
||||
|
||||
build_num = incoming_json.get("build", {}).get("number", 0)
|
||||
if not build_num or build_num <= 0 or not isinstance(build_num, int):
|
||||
abort(400, "Missing or bad build number")
|
||||
return
|
||||
|
||||
artifact_url = urljoin(
|
||||
arg_jenkins_url, "job/%s/%s/api/json" % (job_name, build_num)
|
||||
)
|
||||
artifact_response = requests.get(artifact_url).json()
|
||||
|
||||
# {
|
||||
# "actions": [],
|
||||
# "artifacts": [
|
||||
# {
|
||||
# "displayPath": "vector-043f6991a4ed-react-20f77d1224ef-js-0a7efe3e8bd5.tar.gz",
|
||||
# "fileName": "vector-043f6991a4ed-react-20f77d1224ef-js-0a7efe3e8bd5.tar.gz",
|
||||
# "relativePath": "vector-043f6991a4ed-react-20f77d1224ef-js-0a7efe3e8bd5.tar.gz"
|
||||
# }
|
||||
# ],
|
||||
# "building": false,
|
||||
# "description": null,
|
||||
# "displayName": "#11",
|
||||
# "duration": 137976,
|
||||
# "estimatedDuration": 132008,
|
||||
# "executor": null,
|
||||
# "fullDisplayName": "VectorWebDevelop #11",
|
||||
# "id": "11",
|
||||
# "keepLog": false,
|
||||
# "number": 11,
|
||||
# "queueId": 12254,
|
||||
# "result": "SUCCESS",
|
||||
# "timestamp": 1454432640079,
|
||||
# "url": "http://matrix.org/jenkins/job/VectorWebDevelop/11/",
|
||||
# "builtOn": "",
|
||||
# "changeSet": {},
|
||||
# "culprits": []
|
||||
# }
|
||||
if artifact_response.get("result") != "SUCCESS":
|
||||
abort(404, "Not deploying. Build was not marked as SUCCESS.")
|
||||
return
|
||||
|
||||
if len(artifact_response.get("artifacts", [])) != 1:
|
||||
abort(404, "Not deploying. Build has an unexpected number of artifacts.")
|
||||
return
|
||||
|
||||
tar_gz_path = artifact_response["artifacts"][0]["relativePath"]
|
||||
if not tar_gz_path.endswith(".tar.gz"):
|
||||
abort(404, "Not deploying. Artifact is not a .tar.gz file")
|
||||
return
|
||||
|
||||
tar_gz_url = urljoin(
|
||||
arg_jenkins_url, "job/%s/%s/artifact/%s" % (job_name, build_num, tar_gz_path)
|
||||
)
|
||||
|
||||
print("Retrieving .tar.gz file: %s" % tar_gz_url)
|
||||
filename = download_file(tar_gz_url)
|
||||
print("Downloaded file: %s" % filename)
|
||||
name_str = filename.replace(".tar.gz", "")
|
||||
untar_location = os.path.join(arg_extract_path, name_str)
|
||||
untar_to(filename, untar_location)
|
||||
|
||||
if arg_should_clean:
|
||||
os.remove(filename)
|
||||
|
||||
# stamp the version somewhere JS can get to it
|
||||
with open(os.path.join(untar_location, "vector/version"), "w") as stamp_file:
|
||||
stamp_file.write(name_str)
|
||||
|
||||
create_symlink(source=os.path.join(untar_location, "vector"), linkname=arg_symlink)
|
||||
|
||||
return jsonify({})
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser("Runs a Vector redeployment server.")
|
||||
parser.add_argument(
|
||||
"-j", "--jenkins", dest="jenkins", default="http://matrix.org/jenkins/", help=(
|
||||
"The base URL of the Jenkins web server. This will be hit to get the\
|
||||
built artifacts (the .gz file) for redeploying."
|
||||
)
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p", "--port", dest="port", default=4000, type=int, help=(
|
||||
"The port to listen on for requests from Jenkins."
|
||||
)
|
||||
)
|
||||
parser.add_argument(
|
||||
"-e", "--extract", dest="extract", default="./extracted", help=(
|
||||
"The location to extract .tar.gz files to."
|
||||
)
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c", "--clean", dest="clean", action="store_true", default=False, help=(
|
||||
"Remove .tar.gz files after they have been downloaded and extracted."
|
||||
)
|
||||
)
|
||||
parser.add_argument(
|
||||
"-s", "--symlink", dest="symlink", default="./latest", help=(
|
||||
"Write a symlink to this location pointing to the extracted tarball. \
|
||||
New builds will keep overwriting this symlink. The symlink will point \
|
||||
to the /vector directory INSIDE the tarball."
|
||||
)
|
||||
)
|
||||
args = parser.parse_args()
|
||||
if args.jenkins.endswith("/"): # important for urljoin
|
||||
arg_jenkins_url = args.jenkins
|
||||
else:
|
||||
arg_jenkins_url = args.jenkins + "/"
|
||||
arg_extract_path = args.extract
|
||||
arg_should_clean = args.clean
|
||||
arg_symlink = args.symlink
|
||||
print(
|
||||
"Listening on port %s. Extracting to %s%s. Symlinking to %s. Jenkins URL: %s" %
|
||||
(args.port, arg_extract_path,
|
||||
" (clean after)" if arg_should_clean else "", arg_symlink, arg_jenkins_url)
|
||||
)
|
||||
app.run(host="0.0.0.0", port=args.port, debug=True)
|
14
jenkins.sh
Executable file
14
jenkins.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/bash -l
|
||||
export NVM_DIR="/home/jenkins/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
|
||||
nvm use 4
|
||||
npm install
|
||||
(cd node_modules/matrix-react-sdk && npm run build) # npm doesn't do this when dependencies point at github.com >:(
|
||||
npm run build # Dumps artificats to /vector
|
||||
|
||||
# gzip up ./vector
|
||||
rm vector-*.tar.gz || true # rm previous artifacts without failing if it doesn't exist
|
||||
REACT_SHA=$(grep 'gitHead' node_modules/matrix-react-sdk/package.json | cut -d \" -f 4 | head -c 12) # node_modules deps from 'npm install' don't have a .git dir so can't rev-parse.
|
||||
JSSDK_SHA=$(grep 'gitHead' node_modules/matrix-js-sdk/package.json | cut -d \" -f 4 | head -c 12) # But they do set the commit in package.json under 'gitHead' which we're grabbing here.
|
||||
VECTOR_SHA=$(git rev-parse --short=12 HEAD) # use the ACTUAL SHA rather than assume develop
|
||||
tar -zcvhf vector-$VECTOR_SHA-react-$REACT_SHA-js-$JSSDK_SHA.tar.gz vector #g[z]ip, [c]reate archive, [v]erbose, [f]ilename, [h]ard-dereference (do not archive symlinks)
|
36
package.json
36
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vector-web",
|
||||
"version": "0.1.2",
|
||||
"version": "0.2.0",
|
||||
"description": "Vector webapp",
|
||||
"author": "matrix.org",
|
||||
"repository": {
|
||||
@ -9,40 +9,56 @@
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"style": "bundle.css",
|
||||
"matrix-react-parent": "matrix-react-sdk",
|
||||
"scripts": {
|
||||
"reskindex": "reskindex vector -h src/skins/vector/header",
|
||||
"build:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/bundle.css -c uglifycss --no-watch",
|
||||
"reskindex": "reskindex -h src/header",
|
||||
"build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js",
|
||||
"build:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css --no-watch",
|
||||
"build:compile": "babel --source-maps -d lib src",
|
||||
"build:bundle": "NODE_ENV=production webpack -p lib/vector/index.js vector/bundle.js",
|
||||
"build": "npm run build:css && npm run build:compile && npm run build:bundle",
|
||||
"package": "npm run build && mkdir -p packages && tar chvzf packages/vector-`git describe --dirty || echo unknown`.tar.gz vector",
|
||||
"start:js": "webpack -w src/vector/index.js vector/bundle.js",
|
||||
"start:skins:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/bundle.css",
|
||||
"start:js:prod": "NODE_ENV=production webpack -w src/vector/index.js vector/bundle.js",
|
||||
"start:skins:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css",
|
||||
"//cache": "Note the -c 1 below due to https://code.google.com/p/chromium/issues/detail?id=508270",
|
||||
"start": "parallelshell \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
|
||||
"clean": "rimraf lib vector/bundle.css vector/bundle.js vector/bundle.js.map",
|
||||
"start:prod": "parallelshell \"npm run start:js:prod\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
|
||||
"clean": "rimraf lib vector/bundle.css vector/bundle.js vector/bundle.js.map vector/webpack.css*",
|
||||
"prepublish": "npm run build:css && npm run build:compile"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-polyfill": "^6.5.0",
|
||||
"classnames": "^2.1.2",
|
||||
"extract-text-webpack-plugin": "^0.9.1",
|
||||
"filesize": "^3.1.2",
|
||||
"flux": "~2.0.3",
|
||||
"gemini-scrollbar": "^1.3.0",
|
||||
"gfm.css": "^1.1.1",
|
||||
"highlight.js": "^9.0.0",
|
||||
"linkifyjs": "^2.0.0-beta.4",
|
||||
"matrix-js-sdk": "^0.3.0",
|
||||
"matrix-react-sdk": "^0.0.2",
|
||||
"matrix-js-sdk": "^0.4.0",
|
||||
"matrix-react-sdk": "^0.1.0",
|
||||
"modernizr": "^3.1.0",
|
||||
"q": "^1.4.1",
|
||||
"react": "^0.13.3",
|
||||
"react-loader": "^1.4.0"
|
||||
"react": "^0.14.2",
|
||||
"react-dnd": "^2.0.2",
|
||||
"react-dnd-html5-backend": "^2.0.0",
|
||||
"react-dom": "^0.14.2",
|
||||
"react-gemini-scrollbar": "^2.0.1",
|
||||
"sanitize-html": "^1.11.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel": "^5.8.23",
|
||||
"babel-core": "^5.8.25",
|
||||
"babel-loader": "^5.3.2",
|
||||
"catw": "^1.0.1",
|
||||
"css-raw-loader": "^0.1.1",
|
||||
"http-server": "^0.8.4",
|
||||
"json-loader": "^0.5.3",
|
||||
"parallelshell": "^1.2.0",
|
||||
"rimraf": "^2.4.3",
|
||||
"source-map-loader": "^0.1.5",
|
||||
"uglifycss": "0.0.15"
|
||||
"webpack": "^1.12.13"
|
||||
}
|
||||
}
|
||||
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||
|
||||
module.exports = {
|
||||
avatarUrlForMember: function(member, width, height, resizeMethod) {
|
||||
var url = member.getAvatarUrl(
|
||||
MatrixClientPeg.get().getHomeserverUrl(),
|
||||
width,
|
||||
height,
|
||||
resizeMethod
|
||||
);
|
||||
if (!url) {
|
||||
// member can be null here currently since on invites, the JS SDK
|
||||
// does not have enough info to build a RoomMember object for
|
||||
// the inviter.
|
||||
url = this.defaultAvatarUrlForString(member ? member.userId : '');
|
||||
}
|
||||
return url;
|
||||
},
|
||||
|
||||
defaultAvatarUrlForString: function(s) {
|
||||
var total = 0;
|
||||
for (var i = 0; i < s.length; ++i) {
|
||||
total += s.charCodeAt(i);
|
||||
}
|
||||
switch (total % 3) {
|
||||
case 0:
|
||||
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9QjNbxSKP4eagAFnTseHFErFYLBaLxWKxWCwWi8Vi8cX4CzAABSwCRWJw31gAAAAASUVORK5CYII=";
|
||||
case 1:
|
||||
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9chOaxgCP4eagAFk9seHFErFYLBaLxWKxWCwWi8Vi8cX4CzAAtKMCks/JG8MAAAAASUVORK5CYII=";
|
||||
case 2:
|
||||
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9YzNayQCP4eagADldseHFErFYLBaLxWKxWCwWi8Vi8cX4CzAAyiACeHwPiu4AAAAASUVORK5CYII=";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
|
||||
// Shamelessly ripped off Modal.js. There's probably a better way
|
||||
// of doing reusable widgets like dialog boxes & menus where we go and
|
||||
// pass in a custom control as the actual body.
|
||||
|
||||
module.exports = {
|
||||
ContextualMenuContainerId: "mx_ContextualMenu_Container",
|
||||
|
||||
getOrCreateContainer: function() {
|
||||
var container = document.getElementById(this.ContextualMenuContainerId);
|
||||
|
||||
if (!container) {
|
||||
container = document.createElement("div");
|
||||
container.id = this.ContextualMenuContainerId;
|
||||
document.body.appendChild(container);
|
||||
}
|
||||
|
||||
return container;
|
||||
},
|
||||
|
||||
createMenu: function (Element, props) {
|
||||
var self = this;
|
||||
|
||||
var closeMenu = function() {
|
||||
React.unmountComponentAtNode(self.getOrCreateContainer());
|
||||
|
||||
if (props && props.onFinished) props.onFinished.apply(null, arguments);
|
||||
};
|
||||
|
||||
var position = {
|
||||
top: props.top - 20,
|
||||
};
|
||||
|
||||
var chevron = null;
|
||||
if (props.left) {
|
||||
chevron = <img className="mx_ContextualMenu_chevron_left" src="img/chevron-left.png" width="9" height="16" />
|
||||
position.left = props.left + 8;
|
||||
} else {
|
||||
chevron = <img className="mx_ContextualMenu_chevron_right" src="img/chevron-right.png" width="9" height="16" />
|
||||
position.right = props.right + 8;
|
||||
}
|
||||
|
||||
var className = 'mx_ContextualMenu_wrapper';
|
||||
|
||||
// FIXME: If a menu uses getDefaultProps it clobbers the onFinished
|
||||
// property set here so you can't close the menu from a button click!
|
||||
var menu = (
|
||||
<div className={className}>
|
||||
<div className="mx_ContextualMenu" style={position}>
|
||||
{chevron}
|
||||
<Element {...props} onFinished={closeMenu}/>
|
||||
</div>
|
||||
<div className="mx_ContextualMenu_background" onClick={closeMenu}></div>
|
||||
</div>
|
||||
);
|
||||
|
||||
React.render(menu, this.getOrCreateContainer());
|
||||
|
||||
return {close: closeMenu};
|
||||
},
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -85,15 +85,15 @@ ConferenceCall.prototype._getConferenceUserRoom = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if this room member is in fact a conference bot.
|
||||
* @param {RoomMember} The room member to check
|
||||
* Check if this user ID is in fact a conference bot.
|
||||
* @param {string} userId The user ID to check.
|
||||
* @return {boolean} True if it is a conference bot.
|
||||
*/
|
||||
module.exports.isConferenceUser = function(roomMember) {
|
||||
if (roomMember.userId.indexOf("@" + USER_PREFIX) !== 0) {
|
||||
module.exports.isConferenceUser = function(userId) {
|
||||
if (userId.indexOf("@" + USER_PREFIX) !== 0) {
|
||||
return false;
|
||||
}
|
||||
var base64part = roomMember.userId.split(":")[0].substring(1 + USER_PREFIX.length);
|
||||
var base64part = userId.split(":")[0].substring(1 + USER_PREFIX.length);
|
||||
if (base64part) {
|
||||
var decoded = new Buffer(base64part, "base64").toString();
|
||||
// ! $STUFF : $STUFF
|
50
src/component-index.js
Normal file
50
src/component-index.js
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS FILE IS AUTO-GENERATED
|
||||
* You can edit it you like, but your changes will be overwritten,
|
||||
* so you'd just be trying to swim upstream like a salmon.
|
||||
* You are not a salmon.
|
||||
*/
|
||||
|
||||
module.exports.components = require('matrix-react-sdk/lib/component-index').components;
|
||||
|
||||
module.exports.components['structures.BottomLeftMenu'] = require('./components/structures/BottomLeftMenu');
|
||||
module.exports.components['structures.CompatibilityPage'] = require('./components/structures/CompatibilityPage');
|
||||
module.exports.components['structures.LeftPanel'] = require('./components/structures/LeftPanel');
|
||||
module.exports.components['structures.RightPanel'] = require('./components/structures/RightPanel');
|
||||
module.exports.components['structures.RoomDirectory'] = require('./components/structures/RoomDirectory');
|
||||
module.exports.components['structures.RoomSubList'] = require('./components/structures/RoomSubList');
|
||||
module.exports.components['structures.ViewSource'] = require('./components/structures/ViewSource');
|
||||
module.exports.components['views.elements.ImageView'] = require('./components/views/elements/ImageView');
|
||||
module.exports.components['views.elements.Spinner'] = require('./components/views/elements/Spinner');
|
||||
module.exports.components['views.globals.GuestWarningBar'] = require('./components/views/globals/GuestWarningBar');
|
||||
module.exports.components['views.globals.MatrixToolbar'] = require('./components/views/globals/MatrixToolbar');
|
||||
module.exports.components['views.globals.NewVersionBar'] = require('./components/views/globals/NewVersionBar');
|
||||
module.exports.components['views.login.VectorCustomServerDialog'] = require('./components/views/login/VectorCustomServerDialog');
|
||||
module.exports.components['views.login.VectorLoginFooter'] = require('./components/views/login/VectorLoginFooter');
|
||||
module.exports.components['views.login.VectorLoginHeader'] = require('./components/views/login/VectorLoginHeader');
|
||||
module.exports.components['views.messages.DateSeparator'] = require('./components/views/messages/DateSeparator');
|
||||
module.exports.components['views.messages.MessageTimestamp'] = require('./components/views/messages/MessageTimestamp');
|
||||
module.exports.components['views.messages.SenderProfile'] = require('./components/views/messages/SenderProfile');
|
||||
module.exports.components['views.rooms.BottomLeftMenuTile'] = require('./components/views/rooms/BottomLeftMenuTile');
|
||||
module.exports.components['views.rooms.MessageContextMenu'] = require('./components/views/rooms/MessageContextMenu');
|
||||
module.exports.components['views.rooms.RoomDNDView'] = require('./components/views/rooms/RoomDNDView');
|
||||
module.exports.components['views.rooms.RoomDropTarget'] = require('./components/views/rooms/RoomDropTarget');
|
||||
module.exports.components['views.rooms.RoomTooltip'] = require('./components/views/rooms/RoomTooltip');
|
||||
module.exports.components['views.rooms.SearchBar'] = require('./components/views/rooms/SearchBar');
|
||||
module.exports.components['views.settings.Notifications'] = require('./components/views/settings/Notifications');
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -40,19 +40,19 @@ module.exports = React.createClass({
|
||||
return <div className="mx_RoomTile_name">{name}</div>
|
||||
}
|
||||
else if (this.state.hover) {
|
||||
var RoomTooltip = sdk.getComponent("molecules.RoomTooltip");
|
||||
var RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
|
||||
return <RoomTooltip name={name}/>;
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var BottomLeftMenuTile = sdk.getComponent('molecules.BottomLeftMenuTile');
|
||||
var BottomLeftMenuTile = sdk.getComponent('rooms.BottomLeftMenuTile');
|
||||
return (
|
||||
<div className="mx_BottomLeftMenu">
|
||||
<div className="mx_BottomLeftMenu_options">
|
||||
<BottomLeftMenuTile collapsed={ this.props.collapsed } img="img/create-big.png" label="Create new room" onClick={ this.onCreateRoomClick }/>
|
||||
<BottomLeftMenuTile collapsed={ this.props.collapsed } img="img/directory-big.png" label="Directory" onClick={ this.onRoomDirectoryClick }/>
|
||||
<BottomLeftMenuTile collapsed={ this.props.collapsed } img="img/settings-big.png" label="Settings" onClick={ this.onSettingsClick }/>
|
||||
<BottomLeftMenuTile collapsed={ this.props.collapsed } img="img/create-big.svg" label="Start chat" onClick={ this.onCreateRoomClick }/>
|
||||
<BottomLeftMenuTile collapsed={ this.props.collapsed } img="img/directory-big.svg" label="Directory" onClick={ this.onRoomDirectoryClick }/>
|
||||
<BottomLeftMenuTile collapsed={ this.props.collapsed } img="img/settings-big.svg" label="Settings" onClick={ this.onSettingsClick }/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
62
src/components/structures/CompatibilityPage.js
Normal file
62
src/components/structures/CompatibilityPage.js
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
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 React = require('react');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'CompatibilityPage',
|
||||
propTypes: {
|
||||
onAccept: React.PropTypes.func
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
onAccept: function() {} // NOP
|
||||
};
|
||||
},
|
||||
|
||||
onAccept: function() {
|
||||
this.props.onAccept();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
|
||||
return (
|
||||
<div className="mx_CompatibilityPage">
|
||||
<div className="mx_CompatibilityPage_box">
|
||||
<p>Sorry, your browser is <b>not</b> able to run Vector.</p>
|
||||
<p>
|
||||
Buttons and images may appear out of place, communication may
|
||||
not be possible and all manner of chaos may be unleashed.
|
||||
</p>
|
||||
<p>
|
||||
Please install <a href={"https://www.google.com/chrome"}>Chrome</a> for
|
||||
the best experience.
|
||||
</p>
|
||||
<p>
|
||||
Though if you like taking risks with your life, you can still try it
|
||||
out by clicking that you understand the risks involved.
|
||||
</p>
|
||||
<button onClick={this.onAccept}>
|
||||
I understand the risks and wish to continue
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
125
src/components/structures/LeftPanel.js
Normal file
125
src/components/structures/LeftPanel.js
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
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 React = require('react');
|
||||
var DragDropContext = require('react-dnd').DragDropContext;
|
||||
var HTML5Backend = require('react-dnd-html5-backend');
|
||||
var sdk = require('matrix-react-sdk')
|
||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||
|
||||
var VectorConferenceHandler = require('../../VectorConferenceHandler');
|
||||
var CallHandler = require("matrix-react-sdk/lib/CallHandler");
|
||||
|
||||
var LeftPanel = React.createClass({
|
||||
displayName: 'LeftPanel',
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
showCallElement: null,
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(newProps) {
|
||||
this._recheckCallElement(newProps.selectedRoom);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
dis.unregister(this.dispatcherRef);
|
||||
},
|
||||
|
||||
onAction: function(payload) {
|
||||
switch (payload.action) {
|
||||
// listen for call state changes to prod the render method, which
|
||||
// may hide the global CallView if the call it is tracking is dead
|
||||
case 'call_state':
|
||||
this._recheckCallElement(this.props.selectedRoom);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_recheckCallElement: function(selectedRoomId) {
|
||||
// if we aren't viewing a room with an ongoing call, but there is an
|
||||
// active call, show the call element - we need to do this to make
|
||||
// audio/video not crap out
|
||||
var activeCall = CallHandler.getAnyActiveCall();
|
||||
var callForRoom = CallHandler.getCallForRoom(selectedRoomId);
|
||||
var showCall = (activeCall && activeCall.call_state === 'connected' && !callForRoom);
|
||||
this.setState({
|
||||
showCallElement: showCall
|
||||
});
|
||||
},
|
||||
|
||||
onHideClick: function() {
|
||||
dis.dispatch({
|
||||
action: 'hide_left_panel',
|
||||
});
|
||||
},
|
||||
|
||||
onCallViewClick: function() {
|
||||
var call = CallHandler.getAnyActiveCall();
|
||||
if (call) {
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: call.roomId,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var RoomList = sdk.getComponent('rooms.RoomList');
|
||||
var BottomLeftMenu = sdk.getComponent('structures.BottomLeftMenu');
|
||||
|
||||
var collapseButton;
|
||||
var classes = "mx_LeftPanel";
|
||||
if (this.props.collapsed) {
|
||||
classes += " collapsed";
|
||||
}
|
||||
else {
|
||||
// Hide the collapse button until we work out how to display it in the new skin
|
||||
// collapseButton = <img className="mx_LeftPanel_hideButton" onClick={ this.onHideClick } src="img/hide.png" width="12" height="20" alt="<"/>
|
||||
}
|
||||
|
||||
var callPreview;
|
||||
if (this.state.showCallElement && !this.props.collapsed) {
|
||||
var CallView = sdk.getComponent('voip.CallView');
|
||||
callPreview = (
|
||||
<CallView
|
||||
className="mx_LeftPanel_callView" onClick={this.onCallViewClick}
|
||||
ConferenceHandler={VectorConferenceHandler} />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<aside className={classes}>
|
||||
{ collapseButton }
|
||||
{ callPreview }
|
||||
<RoomList
|
||||
selectedRoom={this.props.selectedRoom}
|
||||
collapsed={this.props.collapsed}
|
||||
ConferenceHandler={VectorConferenceHandler} />
|
||||
<BottomLeftMenu collapsed={this.props.collapsed}/>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = DragDropContext(HTML5Backend)(LeftPanel);
|
173
src/components/structures/RightPanel.js
Normal file
173
src/components/structures/RightPanel.js
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
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 React = require('react');
|
||||
var sdk = require('matrix-react-sdk')
|
||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||
var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
|
||||
var rate_limited_func = require('matrix-react-sdk/lib/ratelimitedfunc');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'RightPanel',
|
||||
|
||||
Phase : {
|
||||
MemberList: 'MemberList',
|
||||
FileList: 'FileList',
|
||||
MemberInfo: 'MemberInfo',
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
var cli = MatrixClientPeg.get();
|
||||
cli.on("RoomState.members", this.onRoomStateMember);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
dis.unregister(this.dispatcherRef);
|
||||
if (MatrixClientPeg.get()) {
|
||||
MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember);
|
||||
}
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
phase : this.Phase.MemberList
|
||||
}
|
||||
},
|
||||
|
||||
onMemberListButtonClick: function() {
|
||||
if (this.props.collapsed) {
|
||||
this.setState({ phase: this.Phase.MemberList });
|
||||
dis.dispatch({
|
||||
action: 'show_right_panel',
|
||||
});
|
||||
}
|
||||
else {
|
||||
dis.dispatch({
|
||||
action: 'hide_right_panel',
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
onRoomStateMember: function(ev, state, member) {
|
||||
// redraw the badge on the membership list
|
||||
if (this.state.phase == this.Phase.MemberList && member.roomId === this.props.roomId) {
|
||||
this._delayedUpdate();
|
||||
}
|
||||
else if (this.state.phase === this.Phase.MemberInfo && member.roomId === this.props.roomId &&
|
||||
member.userId === this.state.member.userId) {
|
||||
// refresh the member info (e.g. new power level)
|
||||
this._delayedUpdate();
|
||||
}
|
||||
},
|
||||
|
||||
_delayedUpdate: new rate_limited_func(function() {
|
||||
this.forceUpdate();
|
||||
}, 500),
|
||||
|
||||
onAction: function(payload) {
|
||||
if (payload.action === "view_user") {
|
||||
if (payload.member) {
|
||||
this.setState({
|
||||
phase: this.Phase.MemberInfo,
|
||||
member: payload.member,
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.setState({
|
||||
phase: this.Phase.MemberList
|
||||
});
|
||||
}
|
||||
}
|
||||
if (payload.action === "view_room") {
|
||||
if (this.state.phase === this.Phase.MemberInfo) {
|
||||
this.setState({
|
||||
phase: this.Phase.MemberList
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var MemberList = sdk.getComponent('rooms.MemberList');
|
||||
var TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||
var buttonGroup;
|
||||
var panel;
|
||||
|
||||
var filesHighlight;
|
||||
var membersHighlight;
|
||||
if (!this.props.collapsed) {
|
||||
if (this.state.phase == this.Phase.MemberList || this.state.phase === this.Phase.MemberInfo) {
|
||||
membersHighlight = <div className="mx_RightPanel_headerButton_highlight"></div>;
|
||||
}
|
||||
else if (this.state.phase == this.Phase.FileList) {
|
||||
filesHighlight = <div className="mx_RightPanel_headerButton_highlight"></div>;
|
||||
}
|
||||
}
|
||||
|
||||
var membersBadge;
|
||||
if ((this.state.phase == this.Phase.MemberList || this.state.phase === this.Phase.MemberInfo) && this.props.roomId) {
|
||||
var cli = MatrixClientPeg.get();
|
||||
var room = cli.getRoom(this.props.roomId);
|
||||
if (room) {
|
||||
membersBadge = <div className="mx_RightPanel_headerButton_badge">{ room.getJoinedMembers().length }</div>;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.props.roomId) {
|
||||
buttonGroup =
|
||||
<div className="mx_RightPanel_headerButtonGroup">
|
||||
<div className="mx_RightPanel_headerButton" title="Members" onClick={ this.onMemberListButtonClick }>
|
||||
<TintableSvg src="img/members.svg" width="17" height="22"/>
|
||||
{ membersBadge }
|
||||
{ membersHighlight }
|
||||
</div>
|
||||
<div className="mx_RightPanel_headerButton mx_RightPanel_filebutton" title="Files">
|
||||
<TintableSvg src="img/files.svg" width="17" height="22"/>
|
||||
{ filesHighlight }
|
||||
</div>
|
||||
</div>;
|
||||
|
||||
if (!this.props.collapsed) {
|
||||
if(this.state.phase == this.Phase.MemberList) {
|
||||
panel = <MemberList roomId={this.props.roomId} key={this.props.roomId} />
|
||||
}
|
||||
else if(this.state.phase == this.Phase.MemberInfo) {
|
||||
var MemberInfo = sdk.getComponent('rooms.MemberInfo');
|
||||
panel = <MemberInfo roomId={this.props.roomId} member={this.state.member} key={this.props.roomId} />
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var classes = "mx_RightPanel";
|
||||
if (this.props.collapsed) {
|
||||
classes += " collapsed";
|
||||
}
|
||||
|
||||
return (
|
||||
<aside className={classes}>
|
||||
<div className="mx_RightPanel_header">
|
||||
{ buttonGroup }
|
||||
</div>
|
||||
{ panel }
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
176
src/components/structures/RoomDirectory.js
Normal file
176
src/components/structures/RoomDirectory.js
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
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 React = require('react');
|
||||
|
||||
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||
var ContentRepo = require("matrix-js-sdk").ContentRepo;
|
||||
var Modal = require('matrix-react-sdk/lib/Modal');
|
||||
var sdk = require('matrix-react-sdk')
|
||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||
var GeminiScrollbar = require('react-gemini-scrollbar');
|
||||
|
||||
var linkify = require('linkifyjs');
|
||||
var linkifyString = require('linkifyjs/string');
|
||||
var linkifyMatrix = require('matrix-react-sdk/lib/linkify-matrix');
|
||||
var sanitizeHtml = require('sanitize-html');
|
||||
|
||||
linkifyMatrix(linkify);
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'RoomDirectory',
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
publicRooms: [],
|
||||
roomAlias: '',
|
||||
loading: true,
|
||||
}
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
var self = this;
|
||||
MatrixClientPeg.get().publicRooms(function (err, data) {
|
||||
if (err) {
|
||||
self.setState({ loading: false });
|
||||
console.error("Failed to get publicRooms: %s", JSON.stringify(err));
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to get public room list",
|
||||
description: err.message
|
||||
});
|
||||
}
|
||||
else {
|
||||
self.setState({
|
||||
publicRooms: data.chunk,
|
||||
loading: false,
|
||||
});
|
||||
self.forceUpdate();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
showRoom: function(roomId) {
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: roomId
|
||||
});
|
||||
},
|
||||
|
||||
getRows: function(filter) {
|
||||
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||
|
||||
if (!this.state.publicRooms) return [];
|
||||
|
||||
var rooms = this.state.publicRooms.filter(function(a) {
|
||||
// FIXME: if incrementally typing, keep narrowing down the search set
|
||||
// incrementally rather than starting over each time.
|
||||
return (a.aliases[0].toLowerCase().search(filter.toLowerCase()) >= 0 && a.num_joined_members > 0);
|
||||
}).sort(function(a,b) {
|
||||
return a.num_joined_members - b.num_joined_members;
|
||||
});
|
||||
var rows = [];
|
||||
var self = this;
|
||||
var guestRead, guestJoin, perms;
|
||||
for (var i = 0; i < rooms.length; i++) {
|
||||
var name = rooms[i].name || rooms[i].aliases[0];
|
||||
guestRead = null;
|
||||
guestJoin = null;
|
||||
|
||||
if (rooms[i].world_readable) {
|
||||
guestRead = (
|
||||
<div className="mx_RoomDirectory_perm">World readable</div>
|
||||
);
|
||||
}
|
||||
if (rooms[i].guest_can_join) {
|
||||
guestJoin = (
|
||||
<div className="mx_RoomDirectory_perm">Guests can join</div>
|
||||
);
|
||||
}
|
||||
|
||||
perms = null;
|
||||
if (guestRead || guestJoin) {
|
||||
perms = <div className="mx_RoomDirectory_perms">{guestRead} {guestJoin}</div>;
|
||||
}
|
||||
|
||||
var topic = rooms[i].topic || '';
|
||||
topic = linkifyString(sanitizeHtml(topic));
|
||||
|
||||
rows.unshift(
|
||||
<tr key={ rooms[i].room_id } onClick={self.showRoom.bind(null, rooms[i].room_id)}>
|
||||
<td className="mx_RoomDirectory_roomAvatar">
|
||||
<BaseAvatar width={24} height={24} resizeMethod='crop'
|
||||
name={ name } idName={ name }
|
||||
url={ ContentRepo.getHttpUriForMxc(
|
||||
MatrixClientPeg.get().getHomeserverUrl(),
|
||||
rooms[i].avatar_url, 24, 24, "crop") } />
|
||||
</td>
|
||||
<td className="mx_RoomDirectory_roomDescription">
|
||||
<div className="mx_RoomDirectory_name">{ name }</div>
|
||||
{ perms }
|
||||
<div className="mx_RoomDirectory_topic"
|
||||
onClick={ function(e) { e.stopPropagation() } }
|
||||
dangerouslySetInnerHTML={{ __html: topic }}/>
|
||||
<div className="mx_RoomDirectory_alias">{ rooms[i].aliases[0] }</div>
|
||||
</td>
|
||||
<td className="mx_RoomDirectory_roomMemberCount">
|
||||
{ rooms[i].num_joined_members }
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
return rows;
|
||||
},
|
||||
|
||||
onKeyUp: function(ev) {
|
||||
this.forceUpdate();
|
||||
this.setState({ roomAlias : this.refs.roomAlias.value })
|
||||
if (ev.key == "Enter") {
|
||||
this.showRoom(this.refs.roomAlias.value);
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (this.state.loading) {
|
||||
var Loader = sdk.getComponent("elements.Spinner");
|
||||
return (
|
||||
<div className="mx_RoomDirectory">
|
||||
<Loader />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
var RoomHeader = sdk.getComponent('rooms.RoomHeader');
|
||||
return (
|
||||
<div className="mx_RoomDirectory">
|
||||
<RoomHeader simpleHeader="Directory" />
|
||||
<div className="mx_RoomDirectory_list">
|
||||
<input ref="roomAlias" placeholder="Join a room (e.g. #foo:domain.com)" className="mx_RoomDirectory_input" size="64" onKeyUp={ this.onKeyUp }/>
|
||||
<GeminiScrollbar className="mx_RoomDirectory_tableWrapper">
|
||||
<table ref="directory_table" className="mx_RoomDirectory_table">
|
||||
<tbody>
|
||||
{ this.getRows(this.state.roomAlias) }
|
||||
</tbody>
|
||||
</table>
|
||||
</GeminiScrollbar>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
364
src/components/structures/RoomSubList.js
Normal file
364
src/components/structures/RoomSubList.js
Normal file
@ -0,0 +1,364 @@
|
||||
/*
|
||||
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 React = require('react');
|
||||
var DropTarget = require('react-dnd').DropTarget;
|
||||
var sdk = require('matrix-react-sdk')
|
||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||
var Unread = require('matrix-react-sdk/lib/Unread');
|
||||
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||
|
||||
// turn this on for drop & drag console debugging galore
|
||||
var debug = false;
|
||||
|
||||
var roomListTarget = {
|
||||
canDrop: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
drop: function(props, monitor, component) {
|
||||
if (debug) console.log("dropped on sublist")
|
||||
},
|
||||
|
||||
hover: function(props, monitor, component) {
|
||||
var item = monitor.getItem();
|
||||
|
||||
if (component.state.sortedList.length == 0 && props.editable) {
|
||||
if (debug) console.log("hovering on sublist " + props.label + ", isOver=" + monitor.isOver());
|
||||
|
||||
if (item.targetList !== component) {
|
||||
item.targetList.removeRoomTile(item.room);
|
||||
item.targetList = component;
|
||||
}
|
||||
|
||||
component.moveRoomTile(item.room, 0);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var RoomSubList = React.createClass({
|
||||
displayName: 'RoomSubList',
|
||||
|
||||
debug: debug,
|
||||
|
||||
propTypes: {
|
||||
list: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
|
||||
label: React.PropTypes.string.isRequired,
|
||||
tagName: React.PropTypes.string,
|
||||
editable: React.PropTypes.bool,
|
||||
order: React.PropTypes.string.isRequired,
|
||||
selectedRoom: React.PropTypes.string.isRequired,
|
||||
startAsHidden: React.PropTypes.bool,
|
||||
showSpinner: React.PropTypes.bool, // true to show a spinner if 0 elements when expanded
|
||||
|
||||
// TODO: Fix the name of this. This is too easily confused with the
|
||||
// "hidden" state which is the expanded (or not) view of the list of rooms.
|
||||
// What this prop *really* does is control whether the room name is displayed
|
||||
// so it should be named as such.
|
||||
collapsed: React.PropTypes.bool.isRequired,
|
||||
onHeaderClick: React.PropTypes.func,
|
||||
alwaysShowHeader: React.PropTypes.bool,
|
||||
incomingCall: React.PropTypes.object,
|
||||
onShowMoreRooms: React.PropTypes.func
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
hidden: this.props.startAsHidden || false,
|
||||
truncateAt: 20,
|
||||
sortedList: [],
|
||||
};
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
onHeaderClick: function() {}, // NOP
|
||||
onShowMoreRooms: function() {} // NOP
|
||||
};
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this.sortList(this.props.list, this.props.order);
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(newProps) {
|
||||
// order the room list appropriately before we re-render
|
||||
//if (debug) console.log("received new props, list = " + newProps.list);
|
||||
this.sortList(newProps.list, newProps.order);
|
||||
},
|
||||
|
||||
onClick: function(ev) {
|
||||
var isHidden = !this.state.hidden;
|
||||
this.setState({ hidden : isHidden });
|
||||
|
||||
if (isHidden) {
|
||||
// as good a way as any to reset the truncate state
|
||||
this.setState({ truncateAt : 20 });
|
||||
this.props.onShowMoreRooms();
|
||||
}
|
||||
|
||||
this.props.onHeaderClick(isHidden);
|
||||
},
|
||||
|
||||
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))
|
||||
{
|
||||
return ev.getTs();
|
||||
}
|
||||
}
|
||||
|
||||
// we might only have events that don't trigger the unread indicator,
|
||||
// in which case use the oldest event even if normally it wouldn't count.
|
||||
// This is better than just assuming the last event was forever ago.
|
||||
if (room.timeline.length) {
|
||||
return room.timeline[0].getTs();
|
||||
} else {
|
||||
return Number.MAX_SAFE_INTEGER;
|
||||
}
|
||||
},
|
||||
|
||||
// TODO: factor the comparators back out into a generic comparator
|
||||
// so that view_prev_room and view_next_room can do the right thing
|
||||
|
||||
recentsComparator: function(roomA, roomB) {
|
||||
return this.tsOfNewestEvent(roomB) - this.tsOfNewestEvent(roomA);
|
||||
},
|
||||
|
||||
manualComparator: function(roomA, roomB) {
|
||||
if (!roomA.tags[this.props.tagName] || !roomB.tags[this.props.tagName]) return 0;
|
||||
var a = roomA.tags[this.props.tagName].order;
|
||||
var b = roomB.tags[this.props.tagName].order;
|
||||
return a == b ? this.recentsComparator(roomA, roomB) : ( a > b ? 1 : -1);
|
||||
},
|
||||
|
||||
sortList: function(list, order) {
|
||||
if (list === undefined) list = this.state.sortedList;
|
||||
if (order === undefined) order = this.props.order;
|
||||
var comparator;
|
||||
list = list || [];
|
||||
if (order === "manual") comparator = this.manualComparator;
|
||||
if (order === "recent") comparator = this.recentsComparator;
|
||||
|
||||
//if (debug) console.log("sorting list for sublist " + this.props.label + " with length " + list.length + ", this.props.list = " + this.props.list);
|
||||
this.setState({ sortedList: list.sort(comparator) });
|
||||
},
|
||||
|
||||
moveRoomTile: function(room, atIndex) {
|
||||
if (debug) console.log("moveRoomTile: id " + room.roomId + ", atIndex " + atIndex);
|
||||
//console.log("moveRoomTile before: " + JSON.stringify(this.state.rooms));
|
||||
var found = this.findRoomTile(room);
|
||||
var rooms = this.state.sortedList;
|
||||
if (found.room) {
|
||||
if (debug) console.log("removing at index " + found.index + " and adding at index " + atIndex);
|
||||
rooms.splice(found.index, 1);
|
||||
rooms.splice(atIndex, 0, found.room);
|
||||
}
|
||||
else {
|
||||
if (debug) console.log("Adding at index " + atIndex);
|
||||
rooms.splice(atIndex, 0, room);
|
||||
}
|
||||
this.setState({ sortedList: rooms });
|
||||
// console.log("moveRoomTile after: " + JSON.stringify(this.state.rooms));
|
||||
},
|
||||
|
||||
// XXX: this isn't invoked via a property method but indirectly via
|
||||
// the roomList property method. Unsure how evil this is.
|
||||
removeRoomTile: function(room) {
|
||||
if (debug) console.log("remove room " + room.roomId);
|
||||
var found = this.findRoomTile(room);
|
||||
var rooms = this.state.sortedList;
|
||||
if (found.room) {
|
||||
rooms.splice(found.index, 1);
|
||||
}
|
||||
else {
|
||||
console.warn("Can't remove room " + room.roomId + " - can't find it");
|
||||
}
|
||||
this.setState({ sortedList: rooms });
|
||||
},
|
||||
|
||||
findRoomTile: function(room) {
|
||||
var index = this.state.sortedList.indexOf(room);
|
||||
if (index >= 0) {
|
||||
// console.log("found: room: " + room.roomId + " with index " + index);
|
||||
}
|
||||
else {
|
||||
if (debug) console.log("didn't find room");
|
||||
room = null;
|
||||
}
|
||||
return ({
|
||||
room: room,
|
||||
index: index,
|
||||
});
|
||||
},
|
||||
|
||||
calcManualOrderTagData: function(room) {
|
||||
var index = this.state.sortedList.indexOf(room);
|
||||
|
||||
// we sort rooms by the lexicographic ordering of the 'order' metadata on their tags.
|
||||
// for convenience, we calculate this for now a floating point number between 0.0 and 1.0.
|
||||
|
||||
var orderA = 0.0; // by default we're next to the beginning of the list
|
||||
if (index > 0) {
|
||||
var prevTag = this.state.sortedList[index - 1].tags[this.props.tagName];
|
||||
if (!prevTag) {
|
||||
console.error("Previous room in sublist is not tagged to be in this list. This should never happen.")
|
||||
}
|
||||
else if (prevTag.order === undefined) {
|
||||
console.error("Previous room in sublist has no ordering metadata. This should never happen.");
|
||||
}
|
||||
else {
|
||||
orderA = prevTag.order;
|
||||
}
|
||||
}
|
||||
|
||||
var orderB = 1.0; // by default we're next to the end of the list too
|
||||
if (index < this.state.sortedList.length - 1) {
|
||||
var nextTag = this.state.sortedList[index + 1].tags[this.props.tagName];
|
||||
if (!nextTag) {
|
||||
console.error("Next room in sublist is not tagged to be in this list. This should never happen.")
|
||||
}
|
||||
else if (nextTag.order === undefined) {
|
||||
console.error("Next room in sublist has no ordering metadata. This should never happen.");
|
||||
}
|
||||
else {
|
||||
orderB = nextTag.order;
|
||||
}
|
||||
}
|
||||
|
||||
var order = (orderA + orderB) / 2.0;
|
||||
if (order === orderA || order === orderB) {
|
||||
console.error("Cannot describe new list position. This should be incredibly unlikely.");
|
||||
// TODO: renumber the list
|
||||
}
|
||||
|
||||
return order;
|
||||
},
|
||||
|
||||
makeRoomTiles: function() {
|
||||
var self = this;
|
||||
var RoomTile = sdk.getComponent("rooms.RoomTile");
|
||||
return this.state.sortedList.map(function(room) {
|
||||
var selected = room.roomId == self.props.selectedRoom;
|
||||
// XXX: is it evil to pass in self as a prop to RoomTile?
|
||||
return (
|
||||
<RoomTile
|
||||
room={ room }
|
||||
roomSubList={ self }
|
||||
key={ room.roomId }
|
||||
collapsed={ self.props.collapsed || false}
|
||||
selected={ selected }
|
||||
unread={ Unread.doesRoomHaveUnreadMessages(room) }
|
||||
highlight={ room.getUnreadNotificationCount('highlight') > 0 || self.props.label === 'Invites' }
|
||||
isInvite={ self.props.label === 'Invites' }
|
||||
incomingCall={ self.props.incomingCall && (self.props.incomingCall.roomId === room.roomId) ? self.props.incomingCall : null } />
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
_getHeaderJsx: function() {
|
||||
var TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||
return (
|
||||
<h2 onClick={ this.onClick } className="mx_RoomSubList_label">
|
||||
{ this.props.collapsed ? '' : this.props.label }
|
||||
<TintableSvg className="mx_RoomSubList_chevron"
|
||||
src={ this.state.hidden ? "img/list-close.svg" : "img/list-open.svg" }
|
||||
width="10" height="10" />
|
||||
</h2>
|
||||
);
|
||||
},
|
||||
|
||||
_createOverflowTile: function(overflowCount, totalCount) {
|
||||
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||
// XXX: this is duplicated from RoomTile - factor it out
|
||||
return (
|
||||
<div className="mx_RoomTile mx_RoomTile_ellipsis" onClick={this._showFullMemberList}>
|
||||
<div className="mx_RoomTile_avatar">
|
||||
<BaseAvatar url="img/ellipsis.svg" name="..." width={24} height={24} />
|
||||
</div>
|
||||
<div className="mx_RoomTile_name">and { overflowCount } others...</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
_showFullMemberList: function() {
|
||||
this.setState({
|
||||
truncateAt: -1
|
||||
});
|
||||
this.props.onShowMoreRooms();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var connectDropTarget = this.props.connectDropTarget;
|
||||
var RoomDropTarget = sdk.getComponent('rooms.RoomDropTarget');
|
||||
var TruncatedList = sdk.getComponent('elements.TruncatedList');
|
||||
|
||||
var label = this.props.collapsed ? null : this.props.label;
|
||||
|
||||
//console.log("render: " + JSON.stringify(this.state.sortedList));
|
||||
|
||||
var target;
|
||||
if (this.state.sortedList.length == 0 && this.props.editable) {
|
||||
target = <RoomDropTarget label={ 'Drop here to ' + this.props.verb }/>;
|
||||
}
|
||||
|
||||
if (this.state.sortedList.length > 0 || this.props.editable) {
|
||||
var subList;
|
||||
var classes = "mx_RoomSubList";
|
||||
|
||||
if (!this.state.hidden) {
|
||||
subList = <TruncatedList className={ classes } truncateAt={this.state.truncateAt}
|
||||
createOverflowElement={this._createOverflowTile} >
|
||||
{ target }
|
||||
{ this.makeRoomTiles() }
|
||||
</TruncatedList>;
|
||||
}
|
||||
else {
|
||||
subList = <TruncatedList className={ classes }>
|
||||
</TruncatedList>;
|
||||
}
|
||||
|
||||
return connectDropTarget(
|
||||
<div>
|
||||
{ this._getHeaderJsx() }
|
||||
{ subList }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
else {
|
||||
var Loader = sdk.getComponent("elements.Spinner");
|
||||
return (
|
||||
<div className="mx_RoomSubList">
|
||||
{ this.props.alwaysShowHeader ? this._getHeaderJsx() : undefined }
|
||||
{ (this.props.showSpinner && !this.state.hidden) ? <Loader /> : undefined }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Export the wrapped version, inlining the 'collect' functions
|
||||
// to more closely resemble the ES7
|
||||
module.exports =
|
||||
DropTarget('RoomTile', roomListTarget, function(connect) {
|
||||
return {
|
||||
connectDropTarget: connect.dropTarget(),
|
||||
}
|
||||
})(RoomSubList);
|
54
src/components/structures/ViewSource.js
Normal file
54
src/components/structures/ViewSource.js
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
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 React = require('react');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'ViewSource',
|
||||
|
||||
propTypes: {
|
||||
onFinished: React.PropTypes.func.isRequired
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
document.addEventListener("keydown", this.onKeyDown);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
document.removeEventListener("keydown", this.onKeyDown);
|
||||
},
|
||||
|
||||
onKeyDown: function(ev) {
|
||||
if (ev.keyCode == 27) { // escape
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.props.onFinished();
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="mx_ViewSource">
|
||||
<pre>
|
||||
{JSON.stringify(this.props.mxEvent.event, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
154
src/components/views/elements/ImageView.js
Normal file
154
src/components/views/elements/ImageView.js
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
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 React = require('react');
|
||||
|
||||
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||
|
||||
var DateUtils = require('matrix-react-sdk/lib/DateUtils');
|
||||
var filesize = require('filesize');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'ImageView',
|
||||
|
||||
propTypes: {
|
||||
onFinished: React.PropTypes.func.isRequired
|
||||
},
|
||||
|
||||
// XXX: keyboard shortcuts for managing dialogs should be done by the modal
|
||||
// dialog base class somehow, surely...
|
||||
componentDidMount: function() {
|
||||
document.addEventListener("keydown", this.onKeyDown);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
document.removeEventListener("keydown", this.onKeyDown);
|
||||
},
|
||||
|
||||
onKeyDown: function(ev) {
|
||||
if (ev.keyCode == 27) { // escape
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.props.onFinished();
|
||||
}
|
||||
},
|
||||
|
||||
onRedactClick: function() {
|
||||
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) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
// display error message stating you couldn't delete this.
|
||||
var code = e.errcode || e.statusCode;
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Error",
|
||||
description: "You cannot delete this image. (" + code + ")"
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
|
||||
/*
|
||||
// In theory max-width: 80%, max-height: 80% on the CSS should work
|
||||
// but in practice, it doesn't, so do it manually:
|
||||
|
||||
var width = this.props.width || 500;
|
||||
var height = this.props.height || 500;
|
||||
|
||||
var maxWidth = document.documentElement.clientWidth * 0.8;
|
||||
var maxHeight = document.documentElement.clientHeight * 0.8;
|
||||
|
||||
var widthFrac = width / maxWidth;
|
||||
var heightFrac = height / maxHeight;
|
||||
|
||||
var displayWidth;
|
||||
var displayHeight;
|
||||
if (widthFrac > heightFrac) {
|
||||
displayWidth = Math.min(width, maxWidth);
|
||||
displayHeight = (displayWidth / width) * height;
|
||||
} else {
|
||||
displayHeight = Math.min(height, maxHeight);
|
||||
displayWidth = (displayHeight / height) * width;
|
||||
}
|
||||
|
||||
var style = {
|
||||
width: displayWidth,
|
||||
height: displayHeight
|
||||
};
|
||||
*/
|
||||
var style, res;
|
||||
|
||||
if (this.props.width && this.props.height) {
|
||||
style = {
|
||||
width: this.props.width,
|
||||
height: this.props.height,
|
||||
};
|
||||
res = ", " + style.width + "x" + style.height + "px";
|
||||
}
|
||||
|
||||
var size;
|
||||
if (this.props.mxEvent.getContent().info && this.props.mxEvent.getContent().info.size) {
|
||||
size = filesize(this.props.mxEvent.getContent().info.size);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_ImageView">
|
||||
<div className="mx_ImageView_lhs">
|
||||
</div>
|
||||
<div className="mx_ImageView_content">
|
||||
<img src={this.props.src} style={style}/>
|
||||
<div className="mx_ImageView_labelWrapper">
|
||||
<div className="mx_ImageView_label">
|
||||
<img className="mx_ImageView_cancel" src="img/cancel-white.svg" width="18" height="18" alt="Close" onClick={ this.props.onFinished }/>
|
||||
<div className="mx_ImageView_shim">
|
||||
</div>
|
||||
<div className="mx_ImageView_name">
|
||||
{ this.props.mxEvent.getContent().body }
|
||||
</div>
|
||||
<div className="mx_ImageView_metadata">
|
||||
Uploaded on { DateUtils.formatDate(new Date(this.props.mxEvent.getTs())) } by { this.props.mxEvent.getSender() }
|
||||
</div>
|
||||
<a className="mx_ImageView_link" href={ this.props.src } target="_blank">
|
||||
<div className="mx_ImageView_download">
|
||||
Download this file<br/>
|
||||
<span className="mx_ImageView_size">{ size } { res }</span>
|
||||
</div>
|
||||
</a>
|
||||
<div className="mx_ImageView_button">
|
||||
<a className="mx_ImageView_link" href={ this.props.src } target="_blank">
|
||||
View full screen
|
||||
</a>
|
||||
</div>
|
||||
<div className="mx_ImageView_button" onClick={this.onRedactClick}>
|
||||
Redact
|
||||
</div>
|
||||
<div className="mx_ImageView_shim">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx_ImageView_rhs">
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -26,7 +26,7 @@ module.exports = React.createClass({
|
||||
var h = this.props.h || 32;
|
||||
var imgClass = this.props.imgClassName || "";
|
||||
return (
|
||||
<div>
|
||||
<div className="mx_Spinner">
|
||||
<img src="img/spinner.gif" width={w} height={h} className={imgClass}/>
|
||||
</div>
|
||||
);
|
44
src/components/views/globals/GuestWarningBar.js
Normal file
44
src/components/views/globals/GuestWarningBar.js
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
var React = require('react');
|
||||
var dis = require('matrix-react-sdk/lib/dispatcher')
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'GuestWarningBar',
|
||||
|
||||
onRegisterClicked: function() {
|
||||
dis.dispatch({'action': 'logout'});
|
||||
dis.dispatch({'action': 'start_registration'});
|
||||
},
|
||||
|
||||
onLoginClicked: function() {
|
||||
dis.dispatch({'action': 'logout'});
|
||||
dis.dispatch({'action': 'start_login'});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="mx_GuestWarningBar">
|
||||
<img className="mx_GuestWarningBar_warning" src="img/warning.svg" width="24" height="23" alt="/!\"/>
|
||||
<div>
|
||||
You are using Vector as a guest. <a onClick={this.onRegisterClicked}>Register</a> or <a onClick={this.onLoginClicked}>log in</a> to access more rooms and features.
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -17,23 +17,28 @@ limitations under the License.
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
|
||||
var Notifier = require("matrix-react-sdk/lib/Notifier");
|
||||
var sdk = require('matrix-react-sdk')
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'MatrixToolbar',
|
||||
|
||||
hideToolbar: function() {
|
||||
var Notifier = sdk.getComponent('organisms.Notifier');
|
||||
Notifier.setToolbarHidden(true);
|
||||
},
|
||||
|
||||
onClick: function() {
|
||||
Notifier.setEnabled(true);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var EnableNotificationsButton = sdk.getComponent("atoms.EnableNotificationsButton");
|
||||
return (
|
||||
<div className="mx_MatrixToolbar">
|
||||
You are not receiving desktop notifications. <EnableNotificationsButton />
|
||||
<div className="mx_MatrixToolbar_close"><img src="img/close-white.png" width="16" height="16" onClick={ this.hideToolbar } /></div>
|
||||
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="/!\"/>
|
||||
<div>
|
||||
You are not receiving desktop notifications. <a className="mx_MatrixToolbar_link" onClick={ this.onClick }>Enable them now</a>
|
||||
</div>
|
||||
<div className="mx_MatrixToolbar_close"><img src="img/cancel.svg" width="18" height="18" onClick={ this.hideToolbar } /></div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -17,17 +17,20 @@ limitations under the License.
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
|
||||
//var RoomDropTargetController = require('matrix-react-sdk/lib/controllers/molecules/RoomDropTargetController')
|
||||
var sdk = require('matrix-react-sdk')
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'RoomDropTarget',
|
||||
// mixins: [RoomDropTargetController],
|
||||
displayName: 'NewVersionBar',
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="mx_RoomDropTarget">
|
||||
{this.props.text}
|
||||
<div className="mx_MatrixToolbar">
|
||||
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="/!\"/>
|
||||
<div>
|
||||
A new version of Vector is available. Refresh your browser.
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
53
src/components/views/login/VectorCustomServerDialog.js
Normal file
53
src/components/views/login/VectorCustomServerDialog.js
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
var React = require("react");
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'VectorCustomServerDialog',
|
||||
statics: {
|
||||
replaces: 'CustomServerDialog',
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="mx_ErrorDialog">
|
||||
<div className="mx_Dialog_title">
|
||||
Custom Server Options
|
||||
</div>
|
||||
<div className="mx_Dialog_content">
|
||||
<span>
|
||||
You can use the custom server options to log into other Matrix
|
||||
servers by specifying a different Home server URL.
|
||||
<br/>
|
||||
This allows you to use Vector with an existing Matrix account on
|
||||
a different Home server.
|
||||
<br/>
|
||||
<br/>
|
||||
You can also set a custom Identity server but this will affect
|
||||
people's ability to find you if you use a server in a group other
|
||||
than the main Matrix.org group.
|
||||
</span>
|
||||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button onClick={this.props.onFinished} autoFocus={true}>
|
||||
Dismiss
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -18,26 +18,20 @@ limitations under the License.
|
||||
|
||||
var React = require('react');
|
||||
|
||||
var TextForEvent = require('matrix-react-sdk/lib/TextForEvent');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'EventAsTextTile',
|
||||
|
||||
displayName: 'VectorLoginFooter',
|
||||
statics: {
|
||||
needsSenderProfile: function() {
|
||||
return false;
|
||||
}
|
||||
replaces: 'LoginFooter',
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var text = TextForEvent.textForEvent(this.props.mxEvent);
|
||||
if (text == null || text.length == 0) return null;
|
||||
|
||||
return (
|
||||
<div className="mx_EventAsTextTile">
|
||||
{TextForEvent.textForEvent(this.props.mxEvent)}
|
||||
<div className="mx_Login_links">
|
||||
<a href="https://medium.com/@Vector">blog</a> ·
|
||||
<a href="https://twitter.com/@VectorCo">twitter</a> ·
|
||||
<a href="https://github.com/vector-im/vector-web">github</a> ·
|
||||
<a href="https://matrix.org">powered by Matrix</a>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
}
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -19,16 +19,16 @@ limitations under the License.
|
||||
var React = require('react');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'ViewSource',
|
||||
displayName: 'VectorLoginHeader',
|
||||
statics: {
|
||||
replaces: 'LoginHeader',
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="mx_ViewSource">
|
||||
<pre>
|
||||
{JSON.stringify(this.props.mxEvent.event, null, 2)}
|
||||
</pre>
|
||||
<div className="mx_Login_logo">
|
||||
<img src="img/logo.png" width="249" height="78" alt="vector"/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -17,16 +17,18 @@ limitations under the License.
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var DateUtils = require('matrix-react-sdk/lib/DateUtils');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'UnknownMessageTile',
|
||||
displayName: 'MessageTimestamp',
|
||||
|
||||
render: function() {
|
||||
var content = this.props.mxEvent.getContent();
|
||||
var date = new Date(this.props.ts);
|
||||
return (
|
||||
<span className="mx_UnknownMessageTile">
|
||||
{content.body}
|
||||
<span className="mx_MessageTimestamp">
|
||||
{ DateUtils.formatDate(date) }
|
||||
</span>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -18,19 +18,20 @@ limitations under the License.
|
||||
|
||||
var React = require('react');
|
||||
|
||||
var MEmoteTileController = require('matrix-react-sdk/lib/controllers/molecules/MEmoteTile')
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'MEmoteTile',
|
||||
mixins: [MEmoteTileController],
|
||||
displayName: 'SenderProfile',
|
||||
|
||||
render: function() {
|
||||
var mxEvent = this.props.mxEvent;
|
||||
var content = mxEvent.getContent();
|
||||
var name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
|
||||
|
||||
var msgtype = mxEvent.getContent().msgtype;
|
||||
if (msgtype && msgtype == 'm.emote') {
|
||||
name = ''; // emote message must include the name so don't duplicate it
|
||||
}
|
||||
return (
|
||||
<span ref="content" className="mx_MEmoteTile mx_MessageTile_content">
|
||||
* {name} {content.body}
|
||||
<span className="mx_SenderProfile">
|
||||
{name} { this.props.aux }
|
||||
</span>
|
||||
);
|
||||
},
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -41,14 +41,14 @@ module.exports = React.createClass({
|
||||
label = <div className="mx_RoomTile_name">{ this.props.label }</div>;
|
||||
}
|
||||
else if (this.state.hover) {
|
||||
var RoomTooltip = sdk.getComponent("molecules.RoomTooltip");
|
||||
var RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
|
||||
label = <RoomTooltip bottom={ true } label={ this.props.label }/>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_RoomTile" onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} onClick={this.props.onClick}>
|
||||
<div className="mx_RoomTile_avatar">
|
||||
<img src={ this.props.img } width="36" height="36"/>
|
||||
<img src={ this.props.img } width="26" height="26"/>
|
||||
</div>
|
||||
{ label }
|
||||
</div>
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -22,30 +22,18 @@ var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||
var sdk = require('matrix-react-sdk')
|
||||
var Modal = require('matrix-react-sdk/lib/Modal');
|
||||
var Resend = require("matrix-react-sdk/lib/Resend");
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'MessageContextMenu',
|
||||
|
||||
onResendClick: function() {
|
||||
MatrixClientPeg.get().resendEvent(
|
||||
this.props.mxEvent, MatrixClientPeg.get().getRoom(
|
||||
this.props.mxEvent.getRoomId()
|
||||
)
|
||||
).done(function() {
|
||||
dis.dispatch({
|
||||
action: 'message_sent'
|
||||
});
|
||||
}, function() {
|
||||
dis.dispatch({
|
||||
action: 'message_send_failed'
|
||||
});
|
||||
});
|
||||
dis.dispatch({action: 'message_resend_started'});
|
||||
Resend.resend(this.props.mxEvent);
|
||||
if (this.props.onFinished) this.props.onFinished();
|
||||
},
|
||||
|
||||
onViewSourceClick: function() {
|
||||
var ViewSource = sdk.getComponent('organisms.ViewSource');
|
||||
var ViewSource = sdk.getComponent('structures.ViewSource');
|
||||
Modal.createDialog(ViewSource, {
|
||||
mxEvent: this.props.mxEvent
|
||||
});
|
||||
@ -58,7 +46,7 @@ module.exports = React.createClass({
|
||||
).done(function() {
|
||||
// message should disappear by itself
|
||||
}, function(e) {
|
||||
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
// display error message stating you couldn't delete this.
|
||||
var code = e.errcode || e.statusCode;
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
@ -69,25 +57,42 @@ module.exports = React.createClass({
|
||||
if (this.props.onFinished) this.props.onFinished();
|
||||
},
|
||||
|
||||
onCancelSendClick: function() {
|
||||
Resend.removeFromQueue(this.props.mxEvent);
|
||||
if (this.props.onFinished) this.props.onFinished();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var eventStatus = this.props.mxEvent.status;
|
||||
var resendButton;
|
||||
var viewSourceButton;
|
||||
var redactButton;
|
||||
var cancelButton;
|
||||
|
||||
if (this.props.mxEvent.status == 'not_sent') {
|
||||
if (eventStatus === 'not_sent') {
|
||||
resendButton = (
|
||||
<div className="mx_ContextualMenu_field" onClick={this.onResendClick}>
|
||||
Resend
|
||||
</div>
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
if (!eventStatus) { // sent
|
||||
redactButton = (
|
||||
<div className="mx_ContextualMenu_field" onClick={this.onRedactClick}>
|
||||
Delete
|
||||
Redact
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (eventStatus === "queued" || eventStatus === "not_sent") {
|
||||
cancelButton = (
|
||||
<div className="mx_ContextualMenu_field" onClick={this.onCancelSendClick}>
|
||||
Cancel Sending
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
viewSourceButton = (
|
||||
<div className="mx_ContextualMenu_field" onClick={this.onViewSourceClick}>
|
||||
View Source
|
||||
@ -98,6 +103,7 @@ module.exports = React.createClass({
|
||||
<div>
|
||||
{resendButton}
|
||||
{redactButton}
|
||||
{cancelButton}
|
||||
{viewSourceButton}
|
||||
</div>
|
||||
);
|
205
src/components/views/rooms/RoomDNDView.js
Normal file
205
src/components/views/rooms/RoomDNDView.js
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
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 React = require('react');
|
||||
var DragSource = require('react-dnd').DragSource;
|
||||
var DropTarget = require('react-dnd').DropTarget;
|
||||
|
||||
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');
|
||||
|
||||
/**
|
||||
* Specifies the drag source contract.
|
||||
* Only `beginDrag` function is required.
|
||||
*/
|
||||
var roomTileSource = {
|
||||
canDrag: function(props, monitor) {
|
||||
return props.roomSubList.props.editable;
|
||||
},
|
||||
|
||||
beginDrag: function (props) {
|
||||
// Return the data describing the dragged item
|
||||
var item = {
|
||||
room: props.room,
|
||||
originalList: props.roomSubList,
|
||||
originalIndex: props.roomSubList.findRoomTile(props.room).index,
|
||||
targetList: props.roomSubList, // at first target is same as original
|
||||
// lastTargetRoom: null,
|
||||
// lastYOffset: null,
|
||||
// lastYDelta: null,
|
||||
};
|
||||
|
||||
if (props.roomSubList.debug) console.log("roomTile beginDrag for " + item.room.roomId);
|
||||
|
||||
// doing this 'correctly' with state causes react-dnd to break seemingly due to the state transitions
|
||||
props.room._dragging = true;
|
||||
|
||||
return item;
|
||||
},
|
||||
|
||||
endDrag: function (props, monitor, component) {
|
||||
var item = monitor.getItem();
|
||||
|
||||
if (props.roomSubList.debug) console.log("roomTile endDrag for " + item.room.roomId + " with didDrop=" + monitor.didDrop());
|
||||
|
||||
props.room._dragging = false;
|
||||
if (monitor.didDrop()) {
|
||||
if (props.roomSubList.debug) console.log("force updating component " + item.targetList.props.label);
|
||||
item.targetList.forceUpdate(); // as we're not using state
|
||||
}
|
||||
|
||||
if (monitor.didDrop() && item.targetList.props.editable) {
|
||||
// if we moved lists, remove the old tag
|
||||
if (item.targetList !== item.originalList && item.originalList.props.tagName) {
|
||||
// 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() {
|
||||
//component.state.set({ spinner: component.state.spinner-- });
|
||||
}).fail(function(err) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to remove tag " + item.originalList.props.tagName + " from room",
|
||||
description: err.toString()
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var newOrder= {};
|
||||
if (item.targetList.props.order === 'manual') {
|
||||
newOrder['order'] = item.targetList.calcManualOrderTagData(item.room);
|
||||
}
|
||||
|
||||
// if we moved lists or the ordering changed, add the new tag
|
||||
if (item.targetList.props.tagName && (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() {
|
||||
//component.state.set({ spinner: component.state.spinner-- });
|
||||
}).fail(function(err) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to add tag " + item.targetList.props.tagName + " to room",
|
||||
description: err.toString()
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
// cancel the drop and reset our original position
|
||||
if (props.roomSubList.debug) console.log("cancelling drop & drag");
|
||||
props.roomSubList.moveRoomTile(item.room, item.originalIndex);
|
||||
if (item.targetList && item.targetList !== item.originalList) {
|
||||
item.targetList.removeRoomTile(item.room);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var roomTileTarget = {
|
||||
canDrop: function() {
|
||||
return false;
|
||||
},
|
||||
|
||||
hover: function(props, monitor) {
|
||||
var item = monitor.getItem();
|
||||
//var off = monitor.getClientOffset();
|
||||
// console.log("hovering on room " + props.room.roomId + ", isOver=" + monitor.isOver());
|
||||
|
||||
//console.log("item.targetList=" + item.targetList + ", roomSubList=" + props.roomSubList);
|
||||
|
||||
var switchedTarget = false;
|
||||
if (item.targetList !== props.roomSubList) {
|
||||
// we've switched target, so remove the tile from the previous target.
|
||||
// n.b. the previous target might actually be the source list.
|
||||
if (props.roomSubList.debug) console.log("switched target sublist");
|
||||
switchedTarget = true;
|
||||
item.targetList.removeRoomTile(item.room);
|
||||
item.targetList = props.roomSubList;
|
||||
}
|
||||
|
||||
if (!item.targetList.props.editable) return;
|
||||
|
||||
if (item.targetList.props.order === 'manual') {
|
||||
if (item.room.roomId !== props.room.roomId && props.room !== item.lastTargetRoom) {
|
||||
// find the offset of the target tile in the list.
|
||||
var roomTile = props.roomSubList.findRoomTile(props.room);
|
||||
// shuffle the list to add our tile to that position.
|
||||
props.roomSubList.moveRoomTile(item.room, roomTile.index);
|
||||
}
|
||||
|
||||
// stop us from flickering between our droptarget and the previous room.
|
||||
// whenever the cursor changes direction we have to reset the flicker-damping.
|
||||
/*
|
||||
var yDelta = off.y - item.lastYOffset;
|
||||
|
||||
if ((yDelta > 0 && item.lastYDelta < 0) ||
|
||||
(yDelta < 0 && item.lastYDelta > 0))
|
||||
{
|
||||
// the cursor changed direction - forget our previous room
|
||||
item.lastTargetRoom = null;
|
||||
}
|
||||
else {
|
||||
// track the last room we were hovering over so we can stop
|
||||
// bouncing back and forth if the droptarget is narrower than
|
||||
// the other list items. The other way to do this would be
|
||||
// to reduce the size of the hittarget on the list items, but
|
||||
// can't see an easy way to do that.
|
||||
item.lastTargetRoom = props.room;
|
||||
}
|
||||
|
||||
if (yDelta) item.lastYDelta = yDelta;
|
||||
item.lastYOffset = off.y;
|
||||
*/
|
||||
}
|
||||
else if (switchedTarget) {
|
||||
if (!props.roomSubList.findRoomTile(item.room).room) {
|
||||
// add to the list in the right place
|
||||
props.roomSubList.moveRoomTile(item.room, 0);
|
||||
}
|
||||
// we have to sort the list whatever to recalculate it
|
||||
props.roomSubList.sortList();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Export the wrapped version, inlining the 'collect' functions
|
||||
// to more closely resemble the ES7
|
||||
module.exports =
|
||||
DropTarget('RoomTile', roomTileTarget, function(connect, monitor) {
|
||||
return {
|
||||
// Call this function inside render()
|
||||
// to let React DnD handle the drag events:
|
||||
connectDropTarget: connect.dropTarget(),
|
||||
isOver: monitor.isOver(),
|
||||
}
|
||||
})(
|
||||
DragSource('RoomTile', roomTileSource, function(connect, monitor) {
|
||||
return {
|
||||
// Call this function inside render()
|
||||
// to let React DnD handle the drag events:
|
||||
connectDragSource: connect.dragSource(),
|
||||
// You can ask the monitor about the current drag state:
|
||||
isDragging: monitor.isDragging()
|
||||
};
|
||||
})(RoomTile));
|
||||
|
||||
module.exports.replaces = 'RoomTile';
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -18,20 +18,24 @@ limitations under the License.
|
||||
|
||||
var React = require('react');
|
||||
|
||||
var EnableNotificationsButtonController = require('matrix-react-sdk/lib/controllers/atoms/EnableNotificationsButton')
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'EnableNotificationsButton',
|
||||
mixins: [EnableNotificationsButtonController],
|
||||
displayName: 'RoomDropTarget',
|
||||
|
||||
render: function() {
|
||||
if (this.enabled()) {
|
||||
if (this.props.placeholder) {
|
||||
return (
|
||||
<button className="mx_EnableNotificationsButton" onClick={this.onClick}>Disable Notifications</button>
|
||||
<div className="mx_RoomDropTarget mx_RoomDropTarget_placeholder">
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return (
|
||||
<button className="mx_EnableNotificationsButton" onClick={this.onClick}>Enable Notifications</button>
|
||||
<div className="mx_RoomDropTarget">
|
||||
<div className="mx_RoomDropTarget_avatar"></div>
|
||||
<div className="mx_RoomDropTarget_label">
|
||||
{ this.props.label }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -17,6 +17,7 @@ limitations under the License.
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var ReactDOM = require('react-dom');
|
||||
|
||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||
|
||||
@ -24,21 +25,21 @@ module.exports = React.createClass({
|
||||
displayName: 'RoomTooltip',
|
||||
|
||||
componentDidMount: function() {
|
||||
var tooltip = ReactDOM.findDOMNode(this);
|
||||
if (!this.props.bottom) {
|
||||
// tell the roomlist about us so it can position us
|
||||
dis.dispatch({
|
||||
action: 'view_tooltip',
|
||||
tooltip: this.getDOMNode(),
|
||||
tooltip: tooltip,
|
||||
});
|
||||
}
|
||||
else {
|
||||
var tooltip = this.getDOMNode();
|
||||
tooltip.style.top = tooltip.parentElement.getBoundingClientRect().top + "px";
|
||||
tooltip.style.display = "block";
|
||||
}
|
||||
},
|
||||
|
||||
componentDidUnmount: function() {
|
||||
componentWillUnmount: function() {
|
||||
if (!this.props.bottom) {
|
||||
dis.dispatch({
|
||||
action: 'view_tooltip',
|
69
src/components/views/rooms/SearchBar.js
Normal file
69
src/components/views/rooms/SearchBar.js
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
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 React = require('react');
|
||||
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||
var sdk = require('matrix-react-sdk');
|
||||
var classNames = require('classnames');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'SearchBar',
|
||||
|
||||
getInitialState: function() {
|
||||
return ({
|
||||
scope: 'Room'
|
||||
});
|
||||
},
|
||||
|
||||
onThisRoomClick: function() {
|
||||
this.setState({ scope: 'Room' });
|
||||
},
|
||||
|
||||
onAllRoomsClick: function() {
|
||||
this.setState({ scope: 'All' });
|
||||
},
|
||||
|
||||
onSearchChange: function(e) {
|
||||
if (e.keyCode === 13) { // on enter...
|
||||
this.onSearch();
|
||||
}
|
||||
if (e.keyCode === 27) { // escape...
|
||||
this.props.onCancelClick();
|
||||
}
|
||||
},
|
||||
|
||||
onSearch: function() {
|
||||
this.props.onSearch(this.refs.search_term.value, this.state.scope);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var searchButtonClasses = classNames({ mx_SearchBar_searchButton : true, mx_SearchBar_searching: this.props.searchInProgress });
|
||||
var thisRoomClasses = classNames({ mx_SearchBar_button : true, mx_SearchBar_unselected : this.state.scope !== 'Room' });
|
||||
var allRoomsClasses = classNames({ mx_SearchBar_button : true, mx_SearchBar_unselected : this.state.scope !== 'All' });
|
||||
|
||||
return (
|
||||
<div className="mx_SearchBar">
|
||||
<input ref="search_term" className="mx_SearchBar_input" type="text" autoFocus={true} placeholder="Search..." onKeyDown={this.onSearchChange}/>
|
||||
<div className={ searchButtonClasses } onClick={this.onSearch}><img src="img/search-button.svg" width="37" height="37" alt="Search"/></div>
|
||||
<div className={ thisRoomClasses } onClick={this.onThisRoomClick}>This Room</div>
|
||||
<div className={ allRoomsClasses } onClick={this.onAllRoomsClick}>All Rooms</div>
|
||||
<img className="mx_SearchBar_cancel" src="img/cancel.svg" width="18" height="18" onClick={this.props.onCancelClick} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
1115
src/components/views/settings/Notifications.js
Normal file
1115
src/components/views/settings/Notifications.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,97 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
var dis = require("matrix-react-sdk/lib/dispatcher");
|
||||
var CallHandler = require("matrix-react-sdk/lib/CallHandler");
|
||||
var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
|
||||
|
||||
var VectorConferenceHandler = require('../../../modules/VectorConferenceHandler');
|
||||
|
||||
/*
|
||||
* State vars:
|
||||
* this.state.call = MatrixCall|null
|
||||
*
|
||||
* Props:
|
||||
* this.props.room = Room (JS SDK)
|
||||
*
|
||||
* Internal state:
|
||||
* this._trackedRoom = (either from props.room or programatically set)
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
|
||||
componentDidMount: function() {
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
this._trackedRoom = null;
|
||||
if (this.props.room) {
|
||||
this._trackedRoom = this.props.room;
|
||||
this.showCall(this._trackedRoom.roomId);
|
||||
}
|
||||
else {
|
||||
var call = CallHandler.getAnyActiveCall();
|
||||
if (call) {
|
||||
console.log(
|
||||
"Global CallView is now tracking active call in room %s",
|
||||
call.roomId
|
||||
);
|
||||
this._trackedRoom = MatrixClientPeg.get().getRoom(call.roomId);
|
||||
this.showCall(call.roomId);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
dis.unregister(this.dispatcherRef);
|
||||
},
|
||||
|
||||
onAction: function(payload) {
|
||||
// don't filter out payloads for room IDs other than props.room because
|
||||
// we may be interested in the conf 1:1 room
|
||||
if (payload.action !== 'call_state' || !payload.room_id) {
|
||||
return;
|
||||
}
|
||||
this.showCall(payload.room_id);
|
||||
},
|
||||
|
||||
showCall: function(roomId) {
|
||||
var call = (
|
||||
CallHandler.getCallForRoom(roomId) ||
|
||||
VectorConferenceHandler.getConferenceCallForRoom(roomId)
|
||||
);
|
||||
if (call) {
|
||||
call.setLocalVideoElement(this.getVideoView().getLocalVideoElement());
|
||||
call.setRemoteVideoElement(this.getVideoView().getRemoteVideoElement());
|
||||
// give a separate element for audio stream playback - both for voice calls
|
||||
// and for the voice stream of screen captures
|
||||
call.setRemoteAudioElement(this.getVideoView().getRemoteAudioElement());
|
||||
}
|
||||
if (call && call.type === "video" && call.state !== 'ended') {
|
||||
// if this call is a conf call, don't display local video as the
|
||||
// conference will have us in it
|
||||
this.getVideoView().getLocalVideoElement().style.display = (
|
||||
call.confUserId ? "none" : "initial"
|
||||
);
|
||||
this.getVideoView().getRemoteVideoElement().style.display = "initial";
|
||||
}
|
||||
else {
|
||||
this.getVideoView().getLocalVideoElement().style.display = "none";
|
||||
this.getVideoView().getRemoteVideoElement().style.display = "none";
|
||||
dis.dispatch({action: 'video_fullscreen', fullscreen: false});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1,194 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var React = require("react");
|
||||
var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
|
||||
var RoomListSorter = require("matrix-react-sdk/lib/RoomListSorter");
|
||||
var dis = require("matrix-react-sdk/lib/dispatcher");
|
||||
|
||||
var sdk = require('matrix-react-sdk');
|
||||
var VectorConferenceHandler = require("../../modules/VectorConferenceHandler");
|
||||
var CallHandler = require("matrix-react-sdk/lib/CallHandler");
|
||||
|
||||
var HIDE_CONFERENCE_CHANS = true;
|
||||
|
||||
module.exports = {
|
||||
componentWillMount: function() {
|
||||
var cli = MatrixClientPeg.get();
|
||||
cli.on("Room", this.onRoom);
|
||||
cli.on("Room.timeline", this.onRoomTimeline);
|
||||
cli.on("Room.name", this.onRoomName);
|
||||
cli.on("RoomState.events", this.onRoomStateEvents);
|
||||
cli.on("RoomMember.name", this.onRoomMemberName);
|
||||
|
||||
var rooms = this.getRoomList();
|
||||
this.setState({
|
||||
roomList: rooms,
|
||||
activityMap: {}
|
||||
});
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
},
|
||||
|
||||
onAction: function(payload) {
|
||||
switch (payload.action) {
|
||||
// listen for call state changes to prod the render method, which
|
||||
// may hide the global CallView if the call it is tracking is dead
|
||||
case 'call_state':
|
||||
this._recheckCallElement(this.props.selectedRoom);
|
||||
break;
|
||||
case 'view_tooltip':
|
||||
this.tooltip = payload.tooltip;
|
||||
this._repositionTooltip();
|
||||
if (this.tooltip) this.tooltip.style.display = 'block';
|
||||
break
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
dis.unregister(this.dispatcherRef);
|
||||
if (MatrixClientPeg.get()) {
|
||||
MatrixClientPeg.get().removeListener("Room", this.onRoom);
|
||||
MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
|
||||
MatrixClientPeg.get().removeListener("Room.name", this.onRoomName);
|
||||
MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents);
|
||||
}
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(newProps) {
|
||||
this.state.activityMap[newProps.selectedRoom] = undefined;
|
||||
this._recheckCallElement(newProps.selectedRoom);
|
||||
this.setState({
|
||||
activityMap: this.state.activityMap
|
||||
});
|
||||
},
|
||||
|
||||
onRoom: function(room) {
|
||||
this.refreshRoomList();
|
||||
},
|
||||
|
||||
onRoomTimeline: function(ev, room, toStartOfTimeline) {
|
||||
if (toStartOfTimeline) return;
|
||||
|
||||
var newState = {
|
||||
roomList: this.getRoomList()
|
||||
};
|
||||
if (
|
||||
room.roomId != this.props.selectedRoom &&
|
||||
ev.getSender() != MatrixClientPeg.get().credentials.userId)
|
||||
{
|
||||
var hl = 1;
|
||||
|
||||
var actions = MatrixClientPeg.get().getPushActionsForEvent(ev);
|
||||
if (actions && actions.tweaks && actions.tweaks.highlight) {
|
||||
hl = 2;
|
||||
}
|
||||
// obviously this won't deep copy but this shouldn't be necessary
|
||||
var amap = this.state.activityMap;
|
||||
amap[room.roomId] = Math.max(amap[room.roomId] || 0, hl);
|
||||
|
||||
newState.activityMap = amap;
|
||||
}
|
||||
this.setState(newState);
|
||||
},
|
||||
|
||||
onRoomName: function(room) {
|
||||
this.refreshRoomList();
|
||||
},
|
||||
|
||||
onRoomStateEvents: function(ev, state) {
|
||||
setTimeout(this.refreshRoomList, 0);
|
||||
},
|
||||
|
||||
onRoomMemberName: function(ev, member) {
|
||||
setTimeout(this.refreshRoomList, 0);
|
||||
},
|
||||
|
||||
|
||||
refreshRoomList: function() {
|
||||
var rooms = this.getRoomList();
|
||||
this.setState({
|
||||
roomList: rooms
|
||||
});
|
||||
},
|
||||
|
||||
getRoomList: function() {
|
||||
return RoomListSorter.mostRecentActivityFirst(
|
||||
MatrixClientPeg.get().getRooms().filter(function(room) {
|
||||
var me = room.getMember(MatrixClientPeg.get().credentials.userId);
|
||||
var shouldShowRoom = (
|
||||
me && (me.membership == "join" || me.membership == "invite")
|
||||
);
|
||||
// hiding conf rooms only ever toggles shouldShowRoom to false
|
||||
if (shouldShowRoom && HIDE_CONFERENCE_CHANS) {
|
||||
// we want to hide the 1:1 conf<->user room and not the group chat
|
||||
var joinedMembers = room.getJoinedMembers();
|
||||
if (joinedMembers.length === 2) {
|
||||
var otherMember = joinedMembers.filter(function(m) {
|
||||
return m.userId !== me.userId
|
||||
})[0];
|
||||
if (VectorConferenceHandler.isConferenceUser(otherMember)) {
|
||||
// console.log("Hiding conference 1:1 room %s", room.roomId);
|
||||
shouldShowRoom = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return shouldShowRoom;
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
_recheckCallElement: function(selectedRoomId) {
|
||||
// if we aren't viewing a room with an ongoing call, but there is an
|
||||
// active call, show the call element - we need to do this to make
|
||||
// audio/video not crap out
|
||||
var activeCall = CallHandler.getAnyActiveCall();
|
||||
var callForRoom = CallHandler.getCallForRoom(selectedRoomId);
|
||||
var showCall = (activeCall && !callForRoom);
|
||||
this.setState({
|
||||
show_call_element: showCall
|
||||
});
|
||||
},
|
||||
|
||||
_repositionTooltip: function(e) {
|
||||
if (this.tooltip && this.tooltip.parentElement) {
|
||||
var scroll = this.getDOMNode();
|
||||
this.tooltip.style.top = (scroll.parentElement.offsetTop + this.tooltip.parentElement.offsetTop - scroll.scrollTop) + "px";
|
||||
}
|
||||
},
|
||||
|
||||
makeRoomTiles: function() {
|
||||
var self = this;
|
||||
var RoomTile = sdk.getComponent("molecules.RoomTile");
|
||||
return this.state.roomList.map(function(room) {
|
||||
var selected = room.roomId == self.props.selectedRoom;
|
||||
return (
|
||||
<RoomTile
|
||||
room={room}
|
||||
key={room.roomId}
|
||||
collapsed={self.props.collapsed}
|
||||
selected={selected}
|
||||
unread={self.state.activityMap[room.roomId] === 1}
|
||||
highlight={self.state.activityMap[room.roomId] === 2}
|
||||
/>
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
@ -1,503 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
|
||||
var React = require("react");
|
||||
var q = require("q");
|
||||
var ContentMessages = require("matrix-react-sdk/lib//ContentMessages");
|
||||
var WhoIsTyping = require("matrix-react-sdk/lib/WhoIsTyping");
|
||||
var Modal = require("matrix-react-sdk/lib/Modal");
|
||||
var sdk = require('matrix-react-sdk/lib/index');
|
||||
var CallHandler = require('matrix-react-sdk/lib/CallHandler');
|
||||
var VectorConferenceHandler = require('../../modules/VectorConferenceHandler');
|
||||
|
||||
var dis = require("matrix-react-sdk/lib/dispatcher");
|
||||
|
||||
var PAGINATE_SIZE = 20;
|
||||
var INITIAL_SIZE = 20;
|
||||
|
||||
module.exports = {
|
||||
getInitialState: function() {
|
||||
return {
|
||||
room: this.props.roomId ? MatrixClientPeg.get().getRoom(this.props.roomId) : null,
|
||||
messageCap: INITIAL_SIZE,
|
||||
editingRoomSettings: false,
|
||||
uploadingRoomSettings: false,
|
||||
numUnreadMessages: 0,
|
||||
draggingFile: false,
|
||||
}
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
MatrixClientPeg.get().on("Room.timeline", this.onRoomTimeline);
|
||||
MatrixClientPeg.get().on("Room.name", this.onRoomName);
|
||||
MatrixClientPeg.get().on("RoomMember.typing", this.onRoomMemberTyping);
|
||||
MatrixClientPeg.get().on("RoomState.members", this.onRoomStateMember);
|
||||
this.atBottom = true;
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
if (this.refs.messageWrapper) {
|
||||
var messageWrapper = this.refs.messageWrapper.getDOMNode();
|
||||
messageWrapper.removeEventListener('drop', this.onDrop);
|
||||
messageWrapper.removeEventListener('dragover', this.onDragOver);
|
||||
messageWrapper.removeEventListener('dragleave', this.onDragLeaveOrEnd);
|
||||
messageWrapper.removeEventListener('dragend', this.onDragLeaveOrEnd);
|
||||
}
|
||||
dis.unregister(this.dispatcherRef);
|
||||
if (MatrixClientPeg.get()) {
|
||||
MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
|
||||
MatrixClientPeg.get().removeListener("Room.name", this.onRoomName);
|
||||
MatrixClientPeg.get().removeListener("RoomMember.typing", this.onRoomMemberTyping);
|
||||
MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember);
|
||||
}
|
||||
},
|
||||
|
||||
onAction: function(payload) {
|
||||
switch (payload.action) {
|
||||
case 'message_send_failed':
|
||||
case 'message_sent':
|
||||
case 'message_resend_started':
|
||||
this.setState({
|
||||
room: MatrixClientPeg.get().getRoom(this.props.roomId)
|
||||
});
|
||||
this.forceUpdate();
|
||||
break;
|
||||
case 'notifier_enabled':
|
||||
this.forceUpdate();
|
||||
break;
|
||||
case 'call_state':
|
||||
if (CallHandler.getCallForRoom(this.props.roomId)) {
|
||||
// Call state has changed so we may be loading video elements
|
||||
// which will obscure the message log.
|
||||
// scroll to bottom
|
||||
var messageWrapper = this.refs.messageWrapper;
|
||||
if (messageWrapper) {
|
||||
messageWrapper = messageWrapper.getDOMNode();
|
||||
messageWrapper.scrollTop = messageWrapper.scrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// possibly remove the conf call notification if we're now in
|
||||
// the conf
|
||||
this._updateConfCallNotification();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
// MatrixRoom still showing the messages from the old room?
|
||||
// Set the key to the room_id. Sadly you can no longer get at
|
||||
// the key from inside the component, or we'd check this in code.
|
||||
/*componentWillReceiveProps: function(props) {
|
||||
},*/
|
||||
|
||||
onRoomTimeline: function(ev, room, toStartOfTimeline) {
|
||||
if (!this.isMounted()) return;
|
||||
|
||||
// ignore anything that comes in whilst pagingating: we get one
|
||||
// event for each new matrix event so this would cause a huge
|
||||
// number of UI updates. Just update the UI when the paginate
|
||||
// call returns.
|
||||
if (this.state.paginating) return;
|
||||
|
||||
// no point handling anything while we're waiting for the join to finish:
|
||||
// we'll only be showing a spinner.
|
||||
if (this.state.joining) return;
|
||||
if (room.roomId != this.props.roomId) return;
|
||||
|
||||
if (this.refs.messageWrapper) {
|
||||
var messageWrapper = this.refs.messageWrapper.getDOMNode();
|
||||
this.atBottom = (
|
||||
messageWrapper.scrollHeight - messageWrapper.scrollTop <=
|
||||
(messageWrapper.clientHeight + 150)
|
||||
);
|
||||
}
|
||||
|
||||
var currentUnread = this.state.numUnreadMessages;
|
||||
if (!toStartOfTimeline &&
|
||||
(ev.getSender() !== MatrixClientPeg.get().credentials.userId)) {
|
||||
// update unread count when scrolled up
|
||||
if (this.atBottom) {
|
||||
currentUnread = 0;
|
||||
}
|
||||
else {
|
||||
currentUnread += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.setState({
|
||||
room: MatrixClientPeg.get().getRoom(this.props.roomId),
|
||||
numUnreadMessages: currentUnread
|
||||
});
|
||||
|
||||
if (toStartOfTimeline && !this.state.paginating) {
|
||||
this.fillSpace();
|
||||
}
|
||||
},
|
||||
|
||||
onRoomName: function(room) {
|
||||
if (room.roomId == this.props.roomId) {
|
||||
this.setState({
|
||||
room: room
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
onRoomMemberTyping: function(ev, member) {
|
||||
this.forceUpdate();
|
||||
},
|
||||
|
||||
onRoomStateMember: function(ev, state, member) {
|
||||
if (member.roomId !== this.props.roomId ||
|
||||
member.userId !== VectorConferenceHandler.getConferenceUserIdForRoom(member.roomId)) {
|
||||
return;
|
||||
}
|
||||
this._updateConfCallNotification();
|
||||
},
|
||||
|
||||
_updateConfCallNotification: function() {
|
||||
var room = MatrixClientPeg.get().getRoom(this.props.roomId);
|
||||
if (!room) return;
|
||||
var confMember = room.getMember(
|
||||
VectorConferenceHandler.getConferenceUserIdForRoom(this.props.roomId)
|
||||
);
|
||||
|
||||
if (!confMember) {
|
||||
return;
|
||||
}
|
||||
var confCall = VectorConferenceHandler.getConferenceCallForRoom(confMember.roomId);
|
||||
|
||||
// A conf call notification should be displayed if there is an ongoing
|
||||
// conf call but this cilent isn't a part of it.
|
||||
this.setState({
|
||||
displayConfCallNotification: (
|
||||
(!confCall || confCall.call_state === "ended") &&
|
||||
confMember.membership === "join"
|
||||
)
|
||||
});
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
if (this.refs.messageWrapper) {
|
||||
var messageWrapper = this.refs.messageWrapper.getDOMNode();
|
||||
|
||||
messageWrapper.addEventListener('drop', this.onDrop);
|
||||
messageWrapper.addEventListener('dragover', this.onDragOver);
|
||||
messageWrapper.addEventListener('dragleave', this.onDragLeaveOrEnd);
|
||||
messageWrapper.addEventListener('dragend', this.onDragLeaveOrEnd);
|
||||
|
||||
messageWrapper.scrollTop = messageWrapper.scrollHeight;
|
||||
|
||||
this.fillSpace();
|
||||
}
|
||||
|
||||
this._updateConfCallNotification();
|
||||
},
|
||||
|
||||
componentDidUpdate: function() {
|
||||
if (!this.refs.messageWrapper) return;
|
||||
|
||||
var messageWrapper = this.refs.messageWrapper.getDOMNode();
|
||||
|
||||
if (this.state.paginating && !this.waiting_for_paginate) {
|
||||
var heightGained = messageWrapper.scrollHeight - this.oldScrollHeight;
|
||||
messageWrapper.scrollTop += heightGained;
|
||||
this.oldScrollHeight = undefined;
|
||||
if (!this.fillSpace()) {
|
||||
this.setState({paginating: false});
|
||||
}
|
||||
} else if (this.atBottom) {
|
||||
messageWrapper.scrollTop = messageWrapper.scrollHeight;
|
||||
if (this.state.numUnreadMessages !== 0) {
|
||||
this.setState({numUnreadMessages: 0});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
fillSpace: function() {
|
||||
if (!this.refs.messageWrapper) return;
|
||||
var messageWrapper = this.refs.messageWrapper.getDOMNode();
|
||||
if (messageWrapper.scrollTop < messageWrapper.clientHeight && this.state.room.oldState.paginationToken) {
|
||||
this.setState({paginating: true});
|
||||
|
||||
this.oldScrollHeight = messageWrapper.scrollHeight;
|
||||
|
||||
if (this.state.messageCap < this.state.room.timeline.length) {
|
||||
this.waiting_for_paginate = false;
|
||||
var cap = Math.min(this.state.messageCap + PAGINATE_SIZE, this.state.room.timeline.length);
|
||||
this.setState({messageCap: cap, paginating: true});
|
||||
} else {
|
||||
this.waiting_for_paginate = true;
|
||||
var cap = this.state.messageCap + PAGINATE_SIZE;
|
||||
this.setState({messageCap: cap, paginating: true});
|
||||
var self = this;
|
||||
MatrixClientPeg.get().scrollback(this.state.room, PAGINATE_SIZE).finally(function() {
|
||||
self.waiting_for_paginate = false;
|
||||
if (self.isMounted()) {
|
||||
self.setState({
|
||||
room: MatrixClientPeg.get().getRoom(self.props.roomId)
|
||||
});
|
||||
}
|
||||
// wait and set paginating to false when the component updates
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
onJoinButtonClicked: function(ev) {
|
||||
var self = this;
|
||||
MatrixClientPeg.get().joinRoom(this.props.roomId).then(function() {
|
||||
self.setState({
|
||||
joining: false,
|
||||
room: MatrixClientPeg.get().getRoom(self.props.roomId)
|
||||
});
|
||||
}, function(error) {
|
||||
self.setState({
|
||||
joining: false,
|
||||
joinError: error
|
||||
});
|
||||
});
|
||||
this.setState({
|
||||
joining: true
|
||||
});
|
||||
},
|
||||
|
||||
onMessageListScroll: function(ev) {
|
||||
if (this.refs.messageWrapper) {
|
||||
var messageWrapper = this.refs.messageWrapper.getDOMNode();
|
||||
var wasAtBottom = this.atBottom;
|
||||
this.atBottom = messageWrapper.scrollHeight - messageWrapper.scrollTop <= messageWrapper.clientHeight;
|
||||
if (this.atBottom && !wasAtBottom) {
|
||||
this.forceUpdate(); // remove unread msg count
|
||||
}
|
||||
}
|
||||
if (!this.state.paginating) this.fillSpace();
|
||||
},
|
||||
|
||||
onDragOver: function(ev) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
ev.dataTransfer.dropEffect = 'none';
|
||||
|
||||
var items = ev.dataTransfer.items;
|
||||
if (items.length == 1) {
|
||||
if (items[0].kind == 'file') {
|
||||
this.setState({ draggingFile : true });
|
||||
ev.dataTransfer.dropEffect = 'copy';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onDrop: function(ev) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.setState({ draggingFile : false });
|
||||
var files = ev.dataTransfer.files;
|
||||
if (files.length == 1) {
|
||||
this.uploadFile(files[0]);
|
||||
}
|
||||
},
|
||||
|
||||
onDragLeaveOrEnd: function(ev) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.setState({ draggingFile : false });
|
||||
},
|
||||
|
||||
uploadFile: function(file) {
|
||||
this.setState({
|
||||
upload: {
|
||||
fileName: file.name,
|
||||
uploadedBytes: 0,
|
||||
totalBytes: file.size
|
||||
}
|
||||
});
|
||||
var self = this;
|
||||
ContentMessages.sendContentToRoom(
|
||||
file, this.props.roomId, MatrixClientPeg.get()
|
||||
).progress(function(ev) {
|
||||
//console.log("Upload: "+ev.loaded+" / "+ev.total);
|
||||
self.setState({
|
||||
upload: {
|
||||
fileName: file.name,
|
||||
uploadedBytes: ev.loaded,
|
||||
totalBytes: ev.total
|
||||
}
|
||||
});
|
||||
}).finally(function() {
|
||||
self.setState({
|
||||
upload: undefined
|
||||
});
|
||||
}).done(undefined, function() {
|
||||
// display error message
|
||||
});
|
||||
},
|
||||
|
||||
getWhoIsTypingString: function() {
|
||||
return WhoIsTyping.whoIsTypingString(this.state.room);
|
||||
},
|
||||
|
||||
getEventTiles: function() {
|
||||
var DateSeparator = sdk.getComponent('molecules.DateSeparator');
|
||||
|
||||
var ret = [];
|
||||
var count = 0;
|
||||
|
||||
var EventTile = sdk.getComponent('molecules.EventTile');
|
||||
|
||||
for (var i = this.state.room.timeline.length-1; i >= 0 && count < this.state.messageCap; --i) {
|
||||
var mxEv = this.state.room.timeline[i];
|
||||
|
||||
if (!EventTile.supportsEventType(mxEv.getType())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var continuation = false;
|
||||
var last = false;
|
||||
var dateSeparator = null;
|
||||
if (i == this.state.room.timeline.length - 1) {
|
||||
last = true;
|
||||
}
|
||||
if (i > 0 && count < this.state.messageCap - 1) {
|
||||
if (this.state.room.timeline[i].sender &&
|
||||
this.state.room.timeline[i - 1].sender &&
|
||||
(this.state.room.timeline[i].sender.userId ===
|
||||
this.state.room.timeline[i - 1].sender.userId) &&
|
||||
(this.state.room.timeline[i].getType() ==
|
||||
this.state.room.timeline[i - 1].getType())
|
||||
)
|
||||
{
|
||||
continuation = true;
|
||||
}
|
||||
|
||||
var ts0 = this.state.room.timeline[i - 1].getTs();
|
||||
var ts1 = this.state.room.timeline[i].getTs();
|
||||
if (new Date(ts0).toDateString() !== new Date(ts1).toDateString()) {
|
||||
dateSeparator = <DateSeparator key={ts1} ts={ts1}/>;
|
||||
continuation = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (i === 1) { // n.b. 1, not 0, as the 0th event is an m.room.create and so doesn't show on the timeline
|
||||
var ts1 = this.state.room.timeline[i].getTs();
|
||||
dateSeparator = <li key={ts1}><DateSeparator ts={ts1}/></li>;
|
||||
continuation = false;
|
||||
}
|
||||
|
||||
ret.unshift(
|
||||
<li key={mxEv.getId()}><EventTile mxEvent={mxEv} continuation={continuation} last={last}/></li>
|
||||
);
|
||||
if (dateSeparator) {
|
||||
ret.unshift(dateSeparator);
|
||||
}
|
||||
++count;
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
|
||||
uploadNewState: function(new_name, new_topic, new_join_rule, new_history_visibility, new_power_levels) {
|
||||
var old_name = this.state.room.name;
|
||||
|
||||
var old_topic = this.state.room.currentState.getStateEvents('m.room.topic', '');
|
||||
if (old_topic) {
|
||||
old_topic = old_topic.getContent().topic;
|
||||
} else {
|
||||
old_topic = "";
|
||||
}
|
||||
|
||||
var old_join_rule = this.state.room.currentState.getStateEvents('m.room.join_rules', '');
|
||||
if (old_join_rule) {
|
||||
old_join_rule = old_join_rule.getContent().join_rule;
|
||||
} else {
|
||||
old_join_rule = "invite";
|
||||
}
|
||||
|
||||
var old_history_visibility = this.state.room.currentState.getStateEvents('m.room.history_visibility', '');
|
||||
if (old_history_visibility) {
|
||||
old_history_visibility = old_history_visibility.getContent().history_visibility;
|
||||
} else {
|
||||
old_history_visibility = "shared";
|
||||
}
|
||||
|
||||
var deferreds = [];
|
||||
|
||||
if (old_name != new_name && new_name != undefined && new_name) {
|
||||
deferreds.push(
|
||||
MatrixClientPeg.get().setRoomName(this.state.room.roomId, new_name)
|
||||
);
|
||||
}
|
||||
|
||||
if (old_topic != new_topic && new_topic != undefined) {
|
||||
deferreds.push(
|
||||
MatrixClientPeg.get().setRoomTopic(this.state.room.roomId, new_topic)
|
||||
);
|
||||
}
|
||||
|
||||
if (old_join_rule != new_join_rule && new_join_rule != undefined) {
|
||||
deferreds.push(
|
||||
MatrixClientPeg.get().sendStateEvent(
|
||||
this.state.room.roomId, "m.room.join_rules", {
|
||||
join_rule: new_join_rule,
|
||||
}, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (old_history_visibility != new_history_visibility && new_history_visibility != undefined) {
|
||||
deferreds.push(
|
||||
MatrixClientPeg.get().sendStateEvent(
|
||||
this.state.room.roomId, "m.room.history_visibility", {
|
||||
history_visibility: new_history_visibility,
|
||||
}, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (new_power_levels) {
|
||||
deferreds.push(
|
||||
MatrixClientPeg.get().sendStateEvent(
|
||||
this.state.room.roomId, "m.room.power_levels", new_power_levels, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (deferreds.length) {
|
||||
var self = this;
|
||||
q.all(deferreds).fail(function(err) {
|
||||
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to set state",
|
||||
description: err.toString()
|
||||
});
|
||||
}).finally(function() {
|
||||
self.setState({
|
||||
uploadingRoomSettings: false,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
editingRoomSettings: false,
|
||||
uploadingRoomSettings: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var extend = require('matrix-react-sdk/lib/extend');
|
||||
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||
var BaseRegisterController = require('matrix-react-sdk/lib/controllers/templates/Register.js');
|
||||
|
||||
var RegisterController = {};
|
||||
extend(RegisterController, BaseRegisterController);
|
||||
|
||||
RegisterController.onRegistered = function(user_id, access_token) {
|
||||
MatrixClientPeg.replaceUsingAccessToken(
|
||||
this.state.hs_url, this.state.is_url, user_id, access_token
|
||||
);
|
||||
|
||||
this.setState({
|
||||
step: 'profile',
|
||||
busy: true
|
||||
});
|
||||
|
||||
var self = this;
|
||||
var cli = MatrixClientPeg.get();
|
||||
cli.getProfileInfo(cli.credentials.userId).done(function(result) {
|
||||
self.setState({
|
||||
avatarUrl: result.avatar_url,
|
||||
busy: false
|
||||
});
|
||||
},
|
||||
function(err) {
|
||||
console.err(err);
|
||||
self.setState({
|
||||
busy: false
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
RegisterController.onAccountReady = function() {
|
||||
if (this.props.onLoggedIn) {
|
||||
this.props.onLoggedIn();
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = RegisterController;
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -22,8 +22,13 @@ html {
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Lato', Helvetica, Arial, Sans-Serif;
|
||||
font-size: 16px;
|
||||
/* Open Sans lacks combining diacritics, so these will fall through
|
||||
to the next font. Helevetica's diacritics however do not combine
|
||||
nicely with Open Sans (on OSX, at least) and result in a huge
|
||||
horizontal mess. Arial empirically gets it right, hence prioritising
|
||||
Arial here. */
|
||||
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
|
||||
font-size: 15px;
|
||||
color: #454545;
|
||||
border: 0px;
|
||||
margin: 0px;
|
||||
@ -34,9 +39,9 @@ div.error {
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #80cef4;
|
||||
color: #454545;
|
||||
font-weight: 400;
|
||||
font-size: 20px;
|
||||
font-size: 18px;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
@ -44,7 +49,21 @@ h2 {
|
||||
a:hover,
|
||||
a:link,
|
||||
a:visited {
|
||||
color: #80CEF4;
|
||||
color: #76cfa6;
|
||||
}
|
||||
|
||||
input[type=text]:focus, textarea:focus {
|
||||
border: 1px solid #76CFA6;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* XXX: critical hack to GeminiScrollbar to allow them to work in FF 42 and Chrome 48.
|
||||
Stop the scrollbar view from pushing out the container's overall sizing, which causes
|
||||
flexbox to adapt to the new size and cause the view to keep growing.
|
||||
*/
|
||||
.gm-scrollbar-container .gm-scroll-view {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_background {
|
||||
@ -58,7 +77,7 @@ a:visited {
|
||||
}
|
||||
|
||||
.mx_ContextualMenu {
|
||||
border: 1px solid #a9dbf4;
|
||||
border: 1px solid #a4a4a4;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
color: #747474;
|
||||
@ -91,19 +110,9 @@ a:visited {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.mx_Dialog_background {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000;
|
||||
opacity: 0.2;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.mx_Dialog_wrapper {
|
||||
position: fixed;
|
||||
z-index: 4000;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
@ -124,18 +133,36 @@ a:visited {
|
||||
background-color: #fff;
|
||||
color: #747474;
|
||||
text-align: center;
|
||||
z-index: 2010;
|
||||
z-index: 4010;
|
||||
font-weight: 300;
|
||||
font-size: 16px;
|
||||
font-size: 15px;
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
max-width: 75%;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.mx_ImageView {
|
||||
margin: 6px;
|
||||
/* hack: flexbox bug? */
|
||||
margin-bottom: 4px;
|
||||
.mx_Dialog_background {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.mx_Dialog_lightbox .mx_Dialog_background {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.mx_Dialog_lightbox .mx_Dialog {
|
||||
border-radius: 0px;
|
||||
background-color: transparent;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mx_Dialog_content {
|
||||
@ -146,26 +173,38 @@ a:visited {
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
|
||||
.mx_Dialog button {
|
||||
.mx_Dialog button, .mx_Dialog input[type="submit"] {
|
||||
border: 0px;
|
||||
height: 36px;
|
||||
border-radius: 36px;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
font-size: 15px;
|
||||
color: #fff;
|
||||
background-color: #80cef4;
|
||||
background-color: #76cfa6;
|
||||
margin-left: 8px;
|
||||
margin-right: 8px;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.mx_ErrorDialogTitle,
|
||||
.mx_QuestionDialogTitle {
|
||||
.mx_Dialog_title {
|
||||
min-height: 16px;
|
||||
padding: 12px;
|
||||
border-bottom: 1px solid #a9dbf4;
|
||||
border-bottom: 1px solid #a4a4a4;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
font-size: 18px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.mx_TextInputDialog_label {
|
||||
text-align: left;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.mx_TextInputDialog_input {
|
||||
font-size: 15px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #f0f0f0;
|
||||
padding: 9px;
|
||||
color: #454545;
|
||||
}
|
||||
|
@ -1,7 +1,3 @@
|
||||
.mx_RoomDropTarget,
|
||||
.mx_RoomList_favourites_label,
|
||||
.mx_RoomList_archive_label,
|
||||
.mx_RoomHeader_search,
|
||||
.mx_RoomSettings_encrypt,
|
||||
.mx_CreateRoom_encrypt,
|
||||
.mx_RightPanel_filebutton
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -15,7 +15,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_CreateRoom {
|
||||
width: 720px;
|
||||
width: 960px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
color: #4a4a4a;
|
||||
@ -26,7 +26,7 @@ limitations under the License.
|
||||
border-radius: 3px;
|
||||
border: 1px solid #c7c7c7;
|
||||
font-weight: 300;
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
padding: 9px;
|
||||
margin-top: 6px;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -14,6 +14,18 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_MatrixChat_splash {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mx_MatrixChat_splashButtons {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
}
|
||||
|
||||
.mx_MatrixChat_wrapper {
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
@ -35,7 +47,17 @@ limitations under the License.
|
||||
-webkit-order: 1;
|
||||
order: 1;
|
||||
|
||||
height: 21px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.mx_GuestWarningBar {
|
||||
-webkit-box-ordinal-group: 1;
|
||||
-moz-box-ordinal-group: 1;
|
||||
-ms-flex-order: 1;
|
||||
-webkit-order: 1;
|
||||
order: 1;
|
||||
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.mx_MatrixChat_toolbarShowing {
|
||||
@ -69,8 +91,10 @@ limitations under the License.
|
||||
-webkit-order: 1;
|
||||
order: 1;
|
||||
|
||||
-webkit-flex: 0 0 230px;
|
||||
flex: 0 0 230px;
|
||||
background-color: #eaf5f0;
|
||||
|
||||
-webkit-flex: 0 0 210px;
|
||||
flex: 0 0 210px;
|
||||
}
|
||||
|
||||
.mx_MatrixChat .mx_LeftPanel.collapsed {
|
||||
@ -85,17 +109,25 @@ limitations under the License.
|
||||
-webkit-order: 2;
|
||||
order: 2;
|
||||
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
background-color: #f3f8fa;
|
||||
padding-left: 25px;
|
||||
padding-right: 22px;
|
||||
background-color: #fff;
|
||||
|
||||
-webkit-flex: 1;
|
||||
flex: 1;
|
||||
|
||||
/* Experimental fix for https://github.com/vector-im/vector-web/issues/947
|
||||
and https://github.com/vector-im/vector-web/issues/946.
|
||||
Empirically this stops the MessagePanel's width exploding outwards when
|
||||
gemini is in 'prevented' mode
|
||||
*/
|
||||
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.
|
||||
* 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.
|
||||
@ -114,9 +146,8 @@ limitations under the License.
|
||||
-webkit-order: 3;
|
||||
order: 3;
|
||||
|
||||
background-color: #f3f8fa;
|
||||
-webkit-flex: 0 0 230px;
|
||||
flex: 0 0 230px;
|
||||
-webkit-flex: 0 0 235px;
|
||||
flex: 0 0 235px;
|
||||
}
|
||||
|
||||
.mx_MatrixChat .mx_RightPanel.collapsed {
|
@ -0,0 +1,92 @@
|
||||
.mx_RoomStatusBar {
|
||||
margin-top: 5px;
|
||||
margin-left: 65px;
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
/* position the indicator in the same place horizontally as .mx_EventTile_avatar. */
|
||||
.mx_RoomStatusBar_indicator {
|
||||
padding-left: 18px;
|
||||
padding-right: 12px;
|
||||
margin-left: -73px;
|
||||
float: left;
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_placeholderIndicator {
|
||||
color: #4a4a4a;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_scrollDownIndicator {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_unreadMessagesBar {
|
||||
color: #ff0064;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_connectionLostBar {
|
||||
margin-top: 19px;
|
||||
height: 58px;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_connectionLostBar img {
|
||||
padding-left: 10px;
|
||||
padding-right: 22px;
|
||||
vertical-align: middle;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_connectionLostBar_title {
|
||||
color: #ff0064;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_connectionLostBar_desc {
|
||||
color: #454545;
|
||||
font-size: 13px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_resend_link {
|
||||
color: #454545 ! important;
|
||||
text-decoration: underline ! important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_tabCompleteBar {
|
||||
color: #4a4a4a;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_typingBar {
|
||||
color: #4a4a4a;
|
||||
opacity: 0.5;
|
||||
overflow-y: hidden;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_tabCompleteWrapper {
|
||||
display: flex;
|
||||
display: -webkit-flex;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_tabCompleteWrapper .mx_TabCompleteBar {
|
||||
flex: 1 1 auto;
|
||||
-webkit-flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_tabCompleteEol {
|
||||
flex: 0 0 auto;
|
||||
-webkit-flex: 0 0 auto;
|
||||
color: #76CFA6;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_tabCompleteEol object {
|
||||
vertical-align: middle;
|
||||
margin-right: 8px;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -36,15 +36,15 @@ limitations under the License.
|
||||
-webkit-order: 1;
|
||||
order: 1;
|
||||
|
||||
-webkit-flex: 0 0 88px;
|
||||
flex: 0 0 88px;
|
||||
-webkit-flex: 0 0 83px;
|
||||
flex: 0 0 83px;
|
||||
}
|
||||
|
||||
.mx_RoomView_fileDropTarget {
|
||||
min-width: 0px;
|
||||
max-width: 720px;
|
||||
max-width: 960px;
|
||||
width: 100%;
|
||||
font-size: 20px;
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
|
||||
pointer-events: none;
|
||||
@ -61,10 +61,10 @@ limitations under the License.
|
||||
border-top-right-radius: 10px;
|
||||
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
border: 2px dashed #80cef4;
|
||||
border: 2px #e1dddd solid;
|
||||
border-bottom: none;
|
||||
position: absolute;
|
||||
top: 88px;
|
||||
top: 83px;
|
||||
bottom: 0px;
|
||||
z-index: 3000;
|
||||
}
|
||||
@ -84,23 +84,31 @@ limitations under the License.
|
||||
order: 2;
|
||||
|
||||
min-width: 0px;
|
||||
max-width: 720px;
|
||||
max-width: 960px;
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
|
||||
overflow: auto;
|
||||
border-bottom: 1px solid #a8dbf3;
|
||||
border-bottom: 1px solid #eee;
|
||||
|
||||
-webkit-flex: 0 0 auto;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.mx_RoomView_messagePanel {
|
||||
.mx_RoomView_topUnreadMessagesBar {
|
||||
-webkit-box-ordinal-group: 3;
|
||||
-moz-box-ordinal-group: 3;
|
||||
-ms-flex-order: 3;
|
||||
-webkit-order: 3;
|
||||
order: 3;
|
||||
}
|
||||
|
||||
.mx_RoomView_messagePanel {
|
||||
-webkit-box-ordinal-group: 4;
|
||||
-moz-box-ordinal-group: 4;
|
||||
-ms-flex-order: 4;
|
||||
-webkit-order: 4;
|
||||
order: 4;
|
||||
|
||||
-webkit-flex: 1 1 0;
|
||||
flex: 1 1 0;
|
||||
@ -111,8 +119,22 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_RoomView_messageListWrapper {
|
||||
max-width: 720px;
|
||||
max-width: 960px;
|
||||
margin: auto;
|
||||
|
||||
min-height: 100%;
|
||||
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
|
||||
flex-direction: column;
|
||||
-webkit-flex-direction: column;
|
||||
|
||||
justify-content: flex-end;
|
||||
-webkit-justify-content: flex-end;
|
||||
}
|
||||
|
||||
.mx_RoomView_MessageList {
|
||||
@ -129,8 +151,9 @@ limitations under the License.
|
||||
clear: both;
|
||||
margin-top: 32px;
|
||||
margin-bottom: 8px;
|
||||
margin-left: 63px;
|
||||
padding-bottom: 6px;
|
||||
border-bottom: 1px solid #a8dbf3;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.mx_RoomView_invitePrompt {
|
||||
@ -141,7 +164,7 @@ limitations under the License.
|
||||
order: 2;
|
||||
|
||||
min-width: 0px;
|
||||
max-width: 720px;
|
||||
max-width: 960px;
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
|
||||
@ -149,55 +172,22 @@ limitations under the License.
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
li.mx_RoomView_myReadMarker_container {
|
||||
height: 0px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
hr.mx_RoomView_myReadMarker {
|
||||
border-top: solid 1px #76cfa6;
|
||||
border-bottom: solid 1px #76cfa6;
|
||||
margin-top: 0px;
|
||||
position: relative;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
.mx_RoomView_statusArea {
|
||||
-webkit-box-ordinal-group: 4;
|
||||
-moz-box-ordinal-group: 4;
|
||||
-ms-flex-order: 4;
|
||||
-webkit-order: 4;
|
||||
order: 4;
|
||||
|
||||
width: 100%;
|
||||
-webkit-flex: 0 0 58px;
|
||||
flex: 0 0 58px;
|
||||
}
|
||||
|
||||
.mx_RoomView_statusAreaBox {
|
||||
max-width: 720px;
|
||||
margin: auto;
|
||||
border-top: 1px solid #a8dbf3;
|
||||
}
|
||||
|
||||
.mx_RoomView_unreadMessagesBar {
|
||||
margin-top: 13px;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
background-color: #ff0064;
|
||||
border-radius: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomView_unreadMessagesBar img {
|
||||
padding-left: 22px;
|
||||
padding-right: 22px;
|
||||
}
|
||||
|
||||
.mx_RoomView_typingBar {
|
||||
margin-top: 17px;
|
||||
margin-left: 56px;
|
||||
color: #818794;
|
||||
}
|
||||
|
||||
.mx_RoomView_typingBar img {
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
margin-left: -64px;
|
||||
margin-top: -7px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.mx_RoomView .mx_MessageComposer {
|
||||
-webkit-box-ordinal-group: 5;
|
||||
-moz-box-ordinal-group: 5;
|
||||
-ms-flex-order: 5;
|
||||
@ -205,44 +195,62 @@ limitations under the License.
|
||||
order: 5;
|
||||
|
||||
width: 100%;
|
||||
-webkit-flex: 0 0 63px;
|
||||
flex: 0 0 63px;
|
||||
margin-right: 2px;
|
||||
-webkit-flex: 0 0 auto;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.mx_RoomView_uploadProgressOuter {
|
||||
width: 100%;
|
||||
background-color: rgba(169, 219, 244, 0.5);
|
||||
height: 4px;
|
||||
.mx_RoomView_statusAreaBox {
|
||||
max-width: 960px;
|
||||
margin: auto;
|
||||
min-height: 36px;
|
||||
}
|
||||
|
||||
.mx_RoomView_uploadProgressInner {
|
||||
background-color: #80cef4;
|
||||
height: 4px;
|
||||
.mx_RoomView_statusAreaBox_line {
|
||||
border-top: 1px solid #eee;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.mx_RoomView_uploadFilename {
|
||||
margin-top: 15px;
|
||||
margin-left: 56px;
|
||||
.mx_RoomView_inCall .mx_RoomView_statusAreaBox_line {
|
||||
border-top: 1px hidden;
|
||||
}
|
||||
|
||||
.mx_RoomView_uploadIcon {
|
||||
float: left;
|
||||
margin-top: 6px;
|
||||
margin-left: 5px;
|
||||
.mx_RoomView_inCall .mx_MessageComposer_wrapper {
|
||||
border-top: 2px hidden;
|
||||
}
|
||||
|
||||
.mx_RoomView_uploadCancel {
|
||||
.mx_RoomView_inCall .mx_RoomView_statusAreaBox {
|
||||
background-color: #76CFA6;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_RoomView_voipChevron {
|
||||
position: absolute;
|
||||
bottom: -11px;
|
||||
right: 11px;
|
||||
}
|
||||
|
||||
.mx_RoomView_voipButton {
|
||||
float: right;
|
||||
margin-top: 6px;
|
||||
margin-right: 10px;
|
||||
margin-right: 13px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomView_uploadBytes {
|
||||
float: right;
|
||||
opacity: 0.5;
|
||||
margin-top: 15px;
|
||||
margin-right: 10px;
|
||||
.mx_RoomView_voipButton object {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mx_RoomView .mx_MessageComposer {
|
||||
-webkit-box-ordinal-group: 6;
|
||||
-moz-box-ordinal-group: 6;
|
||||
-ms-flex-order: 6;
|
||||
-webkit-order: 6;
|
||||
order: 6;
|
||||
|
||||
width: 100%;
|
||||
-webkit-flex: 0 0 auto;
|
||||
flex: 0 0 auto;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.mx_RoomView_ongoingConfCallNotification {
|
||||
@ -251,5 +259,5 @@ limitations under the License.
|
||||
background-color: #ff0064;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
padding: 6px;
|
||||
}
|
||||
padding: 6px 0;
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
.mx_UploadBar {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_UploadBar_uploadProgressOuter {
|
||||
height: 4px;
|
||||
margin-left: 63px;
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.mx_UploadBar_uploadProgressInner {
|
||||
background-color: #76cfa6;
|
||||
height: 4px;
|
||||
}
|
||||
|
||||
.mx_UploadBar_uploadFilename {
|
||||
margin-top: 5px;
|
||||
margin-left: 65px;
|
||||
opacity: 0.5;
|
||||
color: #4a4a4a;
|
||||
}
|
||||
|
||||
.mx_UploadBar_uploadIcon {
|
||||
float: left;
|
||||
margin-top: 1px;
|
||||
margin-left: 14px;
|
||||
}
|
||||
|
||||
.mx_UploadBar_uploadCancel {
|
||||
float: right;
|
||||
margin-top: 5px;
|
||||
margin-right: 10px;
|
||||
position: relative;
|
||||
opacity: 0.6;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.mx_UploadBar_uploadBytes {
|
||||
float: right;
|
||||
margin-top: 5px;
|
||||
margin-right: 30px;
|
||||
color: #76cfa6;
|
||||
}
|
@ -0,0 +1,184 @@
|
||||
/*
|
||||
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_UserSettings {
|
||||
max-width: 960px;
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
-webkit-flex-direction: column;
|
||||
}
|
||||
|
||||
.mx_UserSettings .mx_RoomHeader {
|
||||
-webkit-box-ordinal-group: 1;
|
||||
-moz-box-ordinal-group: 1;
|
||||
-ms-flex-order: 1;
|
||||
-webkit-order: 1;
|
||||
order: 1;
|
||||
|
||||
-webkit-flex: 0 0 83px;
|
||||
flex: 0 0 83px;
|
||||
}
|
||||
|
||||
.mx_UserSettings_body {
|
||||
-webkit-box-ordinal-group: 2;
|
||||
-moz-box-ordinal-group: 2;
|
||||
-ms-flex-order: 2;
|
||||
-webkit-order: 2;
|
||||
order: 2;
|
||||
|
||||
-webkit-flex: 1 1 0;
|
||||
flex: 1 1 0;
|
||||
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.mx_UserSettings_spinner {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-right: 12px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.mx_UserSettings_button {
|
||||
display: inline;
|
||||
vertical-align: middle;
|
||||
border: 0px;
|
||||
border-radius: 36px;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
background-color: #76cfa6;
|
||||
width: auto;
|
||||
margin: auto;
|
||||
padding: 7px;
|
||||
padding-left: 1.5em;
|
||||
padding-right: 1.5em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_UserSettings h2 {
|
||||
clear: both;
|
||||
margin-top: 32px;
|
||||
margin-bottom: 8px;
|
||||
margin-left: 63px;
|
||||
padding-bottom: 6px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.mx_UserSettings h3 {
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.mx_UserSettings_section {
|
||||
margin-left: 63px;
|
||||
margin-top: 28px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.mx_UserSettings_accountTable
|
||||
.mx_UserSettings_notifTable
|
||||
{
|
||||
display: table;
|
||||
}
|
||||
|
||||
.mx_UserSettings_profileTable
|
||||
{
|
||||
display: table;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.mx_UserSettings_profileTableRow
|
||||
{
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.mx_UserSettings_profileLabelCell
|
||||
{
|
||||
padding-bottom: 21px;
|
||||
display: table-cell;
|
||||
font-weight: bold;
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
.mx_UserSettings_profileInputCell {
|
||||
display: table-cell;
|
||||
padding-bottom: 21px;
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.mx_UserSettings_profileInputCell input,
|
||||
.mx_UserSettings_profileInputCell .mx_EditableText
|
||||
{
|
||||
display: inline-block;
|
||||
border: 0px;
|
||||
border-bottom: 1px solid rgba(151, 151, 151, 0.5);
|
||||
padding: 0px;
|
||||
width: 240px;
|
||||
color: rgba(74, 74, 74, 0.9);
|
||||
font-family: 'Open Sans', Helvetica, Arial, Sans-Serif;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.mx_UserSettings_addThreepid {
|
||||
display: table-cell;
|
||||
padding-left: 0.5em;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_UserSettings_changePasswordButton {
|
||||
float: right;
|
||||
margin-right: 32px;
|
||||
margin-left: 32px;
|
||||
}
|
||||
|
||||
.mx_UserSettings_logout {
|
||||
float: right;
|
||||
margin-right: 32px;
|
||||
margin-left: 32px;
|
||||
}
|
||||
|
||||
.mx_UserSettings_avatarPicker {
|
||||
margin-left: 32px;
|
||||
margin-right: 32px;
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_UserSettings_avatarPicker_img .mx_BaseAvatar_image {
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.mx_UserSettings_avatarPicker_edit {
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.mx_UserSettings_avatarPicker_edit > input {
|
||||
display: none;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -17,6 +17,18 @@ limitations under the License.
|
||||
.mx_Login {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
-webkit-justify-content: center;
|
||||
justify-content: center;
|
||||
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.mx_Login h2 {
|
||||
@ -28,8 +40,10 @@ limitations under the License.
|
||||
|
||||
.mx_Login_box {
|
||||
width: 300px;
|
||||
min-height: 450px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
margin: auto;
|
||||
padding-top: 100px;
|
||||
}
|
||||
|
||||
.mx_Login_logo {
|
||||
@ -41,7 +55,7 @@ limitations under the License.
|
||||
border-radius: 3px;
|
||||
border: 1px solid #c7c7c7;
|
||||
font-weight: 300;
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
padding: 9px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
@ -54,12 +68,12 @@ limitations under the License.
|
||||
height: 40px;
|
||||
border: 0px;
|
||||
background-color: #76cfa6;
|
||||
font-size: 16px;
|
||||
font-size: 15px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.mx_Login_label {
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
@ -71,7 +85,7 @@ limitations under the License.
|
||||
display: block;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
@ -83,7 +97,7 @@ limitations under the License.
|
||||
display: block;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
@ -91,6 +105,15 @@ limitations under the License.
|
||||
color: #4a4a4a;
|
||||
}
|
||||
|
||||
.mx_Login_forgot {
|
||||
font-size: 13px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.mx_Login_forgot:link {
|
||||
color: #4a4a4a;
|
||||
}
|
||||
|
||||
.mx_Login_loader {
|
||||
position: absolute;
|
||||
left: 50%;
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -14,21 +14,21 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_MatrixToolbar {
|
||||
text-align: center;
|
||||
background-color: #ff0064;
|
||||
.mx_BaseAvatar {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_BaseAvatar_initial {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
padding: 6px;
|
||||
text-align: center;
|
||||
speak: none;
|
||||
pointer-events: none;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.mx_MatrixToolbar button {
|
||||
margin-left: 12px;
|
||||
.mx_BaseAvatar_image {
|
||||
border-radius: 40px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.mx_MatrixToolbar_close {
|
||||
float: right;
|
||||
margin-top: 3px;
|
||||
margin-right: 12px;
|
||||
cursor: pointer;
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
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_SetDisplayNameDialog_input {
|
||||
border-radius: 3px;
|
||||
border: 1px solid #f0f0f0;
|
||||
padding: 9px;
|
||||
color: #454545;
|
||||
font-size: 15px;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -25,7 +25,7 @@ limitations under the License.
|
||||
|
||||
.mx_ServerConfig_help:link {
|
||||
opacity: 0.8;
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 300;
|
||||
color: #4a4a4a;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -14,7 +14,8 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_MImageTile_thumbnail {
|
||||
.mx_MImageBody_thumbnail {
|
||||
max-width: 100%;
|
||||
/*
|
||||
background-color: #fff;
|
||||
border: 2px solid #fff;
|
||||
@ -22,16 +23,20 @@ limitations under the License.
|
||||
*/
|
||||
}
|
||||
|
||||
.mx_MImageTile_download {
|
||||
color: #80cef4;
|
||||
.mx_MImageBody_download {
|
||||
color: #76cfa6;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_MImageTile_download a {
|
||||
color: #80cef4;
|
||||
.mx_MImageBody_download a {
|
||||
color: #76cfa6;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.mx_MImageTile_download img {
|
||||
padding-right: 8px;
|
||||
}
|
||||
.mx_MImageBody_download object {
|
||||
margin-left: -16px;
|
||||
padding-right: 4px;
|
||||
margin-top: -4px;
|
||||
vertical-align: middle;
|
||||
pointer-events: none;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_UserSettings {
|
||||
width: 720px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
.mx_MNoticeBody {
|
||||
white-space: pre-wrap;
|
||||
opacity: 0.6;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -14,7 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_MTextTile {
|
||||
.mx_MTextBody {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -14,3 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_TextualEvent {
|
||||
opacity: 0.5;
|
||||
overflow-y: hidden;
|
||||
}
|
108
src/skins/vector/css/matrix-react-sdk/views/rooms/EntityTile.css
Normal file
108
src/skins/vector/css/matrix-react-sdk/views/rooms/EntityTile.css
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
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_EntityTile {
|
||||
display: table-row;
|
||||
position: relative;
|
||||
color: #454545;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_EntityTile_invite {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
margin-left: 10px;
|
||||
width: 26px;
|
||||
}
|
||||
|
||||
.mx_EntityTile_avatar {
|
||||
display: table-cell;
|
||||
padding-left: 3px;
|
||||
padding-right: 12px;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
vertical-align: middle;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_EntityTile_power {
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 17px;
|
||||
top: 0px;
|
||||
right: 6px;
|
||||
}
|
||||
|
||||
.mx_EntityTile_name {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.mx_EntityTile_details {
|
||||
display: table-cell;
|
||||
padding-right: 14px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_EntityTile_name_hover {
|
||||
font-size: 13px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.mx_EntityTile_chevron {
|
||||
margin-top: 8px;
|
||||
margin-right: -4px;
|
||||
margin-left: 6px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.mx_EntityTile_ellipsis .mx_EntityTile_name {
|
||||
font-style: italic;
|
||||
font-color: #454545;
|
||||
}
|
||||
|
||||
.mx_EntityTile_invitePlaceholder .mx_EntityTile_name {
|
||||
font-style: italic;
|
||||
font-color: #454545;
|
||||
}
|
||||
|
||||
.mx_EntityTile_unavailable .mx_EntityTile_avatar,
|
||||
.mx_EntityTile_unavailable .mx_EntityTile_name,
|
||||
.mx_EntityTile_unavailable .mx_EntityTile_name_hover
|
||||
{
|
||||
opacity: 0.66;
|
||||
}
|
||||
|
||||
.mx_EntityTile_offline .mx_EntityTile_avatar,
|
||||
.mx_EntityTile_offline .mx_EntityTile_name,
|
||||
.mx_EntityTile_offline .mx_EntityTile_name_hover
|
||||
{
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
.mx_EntityTile_unknown .mx_EntityTile_avatar,
|
||||
.mx_EntityTile_unknown .mx_EntityTile_name,
|
||||
.mx_EntityTile_unknown .mx_EntityTile_name_hover
|
||||
{
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
|
192
src/skins/vector/css/matrix-react-sdk/views/rooms/EventTile.css
Normal file
192
src/skins/vector/css/matrix-react-sdk/views/rooms/EventTile.css
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
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_EventTile {
|
||||
max-width: 100%;
|
||||
clear: both;
|
||||
margin-top: 24px;
|
||||
margin-left: 65px;
|
||||
}
|
||||
|
||||
.mx_EventTile_avatar {
|
||||
padding-left: 18px;
|
||||
padding-right: 12px;
|
||||
margin-left: -73px;
|
||||
margin-top: -2px;
|
||||
float: left;
|
||||
position: relative;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.mx_EventTile_continuation {
|
||||
margin-top: 8px ! important;
|
||||
}
|
||||
|
||||
.mx_EventTile .mx_SenderProfile {
|
||||
color: #454545;
|
||||
opacity: 0.5;
|
||||
font-size: 13px;
|
||||
margin-bottom: 4px;
|
||||
display: block;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.mx_EventTile .mx_MessageTimestamp {
|
||||
color: #acacac;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.mx_EventTile_line {
|
||||
position: relative;
|
||||
/* ideally should be 100px, but 95px gives us a max thumbnail size of 800x600, which is nice */
|
||||
margin-right: 95px;
|
||||
}
|
||||
|
||||
.mx_EventTile_content {
|
||||
display: block;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
/* Various markdown overrides */
|
||||
|
||||
.mx_EventTile_content .markdown-body {
|
||||
font-family: inherit ! important;
|
||||
white-space: normal ! important;
|
||||
line-height: inherit ! important;
|
||||
color: inherit;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.mx_EventTile_content .markdown-body h1,
|
||||
.mx_EventTile_content .markdown-body h2,
|
||||
.mx_EventTile_content .markdown-body h3,
|
||||
.mx_EventTile_content .markdown-body h4,
|
||||
.mx_EventTile_content .markdown-body h5,
|
||||
.mx_EventTile_content .markdown-body h6
|
||||
{
|
||||
font-family: inherit ! important;
|
||||
}
|
||||
|
||||
.mx_EventTile_content .markdown-body a {
|
||||
color: #76cfa6;
|
||||
}
|
||||
|
||||
.mx_EventTile_content .markdown-body .hljs {
|
||||
display: inline ! important;
|
||||
}
|
||||
|
||||
/* end of overrides */
|
||||
|
||||
/* this is used for the tile for the event which is selected via the URL.
|
||||
* TODO: ultimately we probably want some transition on here.
|
||||
*/
|
||||
.mx_EventTile_selected {
|
||||
border-left: #76cfa6 5px solid;
|
||||
margin-left: 53px;
|
||||
padding-left: 7px;
|
||||
}
|
||||
|
||||
.mx_EventTile_searchHighlight {
|
||||
background-color: #76cfa6;
|
||||
color: #fff;
|
||||
border-radius: 5px;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_EventTile_searchHighlight a {
|
||||
background-color: #76cfa6;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.mx_EventTile_sending {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.mx_EventTile_notSent {
|
||||
color: #f44;
|
||||
}
|
||||
|
||||
.mx_EventTile_highlight,
|
||||
.mx_EventTile_highlight .markdown-body
|
||||
{
|
||||
color: #FF0064;
|
||||
}
|
||||
|
||||
.mx_EventTile_contextual {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.mx_EventTile_msgOption {
|
||||
float: right;
|
||||
text-align: right;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
width: 90px;
|
||||
height: 1px; /* Hack to stop the height of this pushing the messages apart. Replaces marigin-top: -6px. This interacts better with a read marker being in between. Content overflows. */
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.mx_EventTile .mx_MessageTimestamp {
|
||||
display: block;
|
||||
visibility: hidden;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.mx_EventTile_last .mx_MessageTimestamp {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.mx_EventTile:hover .mx_MessageTimestamp {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.mx_EventTile_editButton {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.mx_EventTile:hover .mx_EventTile_editButton {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.mx_EventTile.menu .mx_EventTile_editButton {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.mx_EventTile.menu .mx_MessageTimestamp {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.mx_EventTile_readAvatars {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.mx_EventTile_readAvatars .mx_BaseAvatar {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_EventTile_readAvatarRemainder {
|
||||
color: #acacac;
|
||||
font-size: 11px;
|
||||
position: absolute;
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
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_MemberInfo {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mx_MemberInfo h2 {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.mx_MemberInfo_cancel {
|
||||
float: right;
|
||||
margin-right: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_MemberInfo_avatar {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.mx_MemberInfo_profile {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.mx_MemberInfo h3 {
|
||||
text-transform: uppercase;
|
||||
color: #3d3b39;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.mx_MemberInfo_profileField {
|
||||
font-color: #999999;
|
||||
font-size: 13px;
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.mx_MemberInfo_buttons {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.mx_MemberInfo_field {
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
color: #76cfa6;
|
||||
margin-left: 8px;
|
||||
line-height: 23px;
|
||||
}
|
106
src/skins/vector/css/matrix-react-sdk/views/rooms/MemberList.css
Normal file
106
src/skins/vector/css/matrix-react-sdk/views/rooms/MemberList.css
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
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_MemberList {
|
||||
height: 100%;
|
||||
|
||||
-webkit-flex: 1;
|
||||
flex: 1;
|
||||
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
|
||||
flex-direction: column;
|
||||
-webkit-flex-direction: column;
|
||||
}
|
||||
|
||||
.mx_MemberList_chevron {
|
||||
position: absolute;
|
||||
right: 35px;
|
||||
margin-top: -15px;
|
||||
}
|
||||
|
||||
.mx_MemberList_border {
|
||||
overflow-y: auto;
|
||||
|
||||
order: 1;
|
||||
-webkit-flex: 1 1 0;
|
||||
flex: 1 1 0px;
|
||||
}
|
||||
|
||||
.mx_MemberList .mx_SearchableEntityList {
|
||||
order: 1;
|
||||
flex: 0 0 auto;
|
||||
-webkit-flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.mx_MemberList .mx_SearchableEntityList_expanded {
|
||||
flex: 1 0 0;
|
||||
-webkit-flex: 1 0 0;
|
||||
}
|
||||
|
||||
.mx_MemberList_joined {
|
||||
order: 2;
|
||||
flex: 1 0 0;
|
||||
-webkit-flex: 1 0 0;
|
||||
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
.mx_MemberList_invited {
|
||||
order: 3;
|
||||
flex: 0 0 100px;
|
||||
-webkit-flex: 0 0 100px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
*/
|
||||
|
||||
.mx_MemberList_bottom {
|
||||
order: 4;
|
||||
flex: 0 0 72px;
|
||||
-webkit-flex: 0 0 72px;
|
||||
}
|
||||
|
||||
.mx_MemberList_bottomRule {
|
||||
border-top: 2px solid #e1dddd;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.mx_MemberList_invited h2 {
|
||||
text-transform: uppercase;
|
||||
color: #3d3b39;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
padding-left: 3px;
|
||||
padding-right: 12px;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
/* we have to have display: table in order for the horizontal wrapping to work */
|
||||
.mx_MemberList_wrapper {
|
||||
display: table;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mx_MemberList_outerWrapper {
|
||||
height: 0px;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -15,70 +15,90 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_MessageComposer_wrapper {
|
||||
max-width: 720px;
|
||||
height: 50px;
|
||||
max-width: 960px;
|
||||
vertical-align: middle;
|
||||
margin: auto;
|
||||
background-color: #fff;
|
||||
border-radius: 25px;
|
||||
border: 1px solid #a9dbf4;
|
||||
border-top: 2px solid #e1dddd;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_row {
|
||||
display: table-row;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.mx_MessageComposer .mx_MessageComposer_avatar {
|
||||
display: table-cell;
|
||||
padding-left: 5px;
|
||||
padding-right: 10px;
|
||||
height: 50px;
|
||||
padding-left: 10px;
|
||||
padding-right: 28px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_MessageComposer .mx_MessageComposer_avatar img {
|
||||
margin-top: 5px;
|
||||
border-radius: 20px;
|
||||
background-color: #dbdbdb;
|
||||
.mx_MessageComposer .mx_MessageComposer_avatar .mx_BaseAvatar {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_input {
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
vertical-align: middle;
|
||||
height: 50px;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_input textarea {
|
||||
display: block;
|
||||
font-size: 15px;
|
||||
width: 100%;
|
||||
height: 1.2em;
|
||||
padding-top: 0.7em;
|
||||
padding-bottom: 0.7em;
|
||||
padding: 0px;
|
||||
margin-top: 6px;
|
||||
margin-bottom: 6px;
|
||||
border: 0px;
|
||||
resize: none;
|
||||
outline: none;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
box-shadow: none;
|
||||
|
||||
/* needed for FF */
|
||||
font-family: 'Lato', Helvetica, Arial, Sans-Serif;
|
||||
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
|
||||
}
|
||||
|
||||
/* hack for FF as vertical alignment of custom placeholder text is broken */
|
||||
.mx_MessageComposer_input textarea::-moz-placeholder {
|
||||
line-height: 100%;
|
||||
color: #76cfa6;
|
||||
}
|
||||
.mx_MessageComposer_input textarea::-webkit-input-placeholder {
|
||||
color: #76cfa6;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_upload {
|
||||
.mx_MessageComposer_upload,
|
||||
.mx_MessageComposer_hangup,
|
||||
.mx_MessageComposer_voicecall,
|
||||
.mx_MessageComposer_videocall {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
padding-right: 15px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_upload img {
|
||||
.mx_MessageComposer_upload object,
|
||||
.mx_MessageComposer_hangup object,
|
||||
.mx_MessageComposer_voicecall object,
|
||||
.mx_MessageComposer_videocall object {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_videocall {
|
||||
padding-right: 10px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_voicecall {
|
||||
padding-right: 10px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_upload object {
|
||||
margin-top: 5px;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
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.
|
||||
@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_MNoticeTile {
|
||||
.mx_PresenceLabel {
|
||||
font-size: 11px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
258
src/skins/vector/css/matrix-react-sdk/views/rooms/RoomHeader.css
Normal file
258
src/skins/vector/css/matrix-react-sdk/views/rooms/RoomHeader.css
Normal file
@ -0,0 +1,258 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/* add 20px to the height of the header when editing */
|
||||
.mx_RoomHeader_editing {
|
||||
-webit-flex: 0 0 93px ! important;
|
||||
flex: 0 0 93px ! important;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_wrapper {
|
||||
max-width: 960px;
|
||||
margin: auto;
|
||||
height: 83px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_editing .mx_RoomHeader_wrapper {
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_leftRow {
|
||||
margin-left: -2px;
|
||||
|
||||
-webkit-box-ordinal-group: 1;
|
||||
-moz-box-ordinal-group: 1;
|
||||
-ms-flex-order: 1;
|
||||
-webkit-order: 1;
|
||||
order: 1;
|
||||
|
||||
-webkit-flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_textButton {
|
||||
height: 36px;
|
||||
background-color: #76cfa6;
|
||||
border-radius: 36px;
|
||||
margin-right: 8px;
|
||||
color: #fff;
|
||||
line-height: 34px;
|
||||
margin-top: -2px;
|
||||
text-align: center;
|
||||
|
||||
-webkit-box-ordinal-group: 2;
|
||||
-moz-box-ordinal-group: 2;
|
||||
-ms-flex-order: 2;
|
||||
-webkit-order: 2;
|
||||
order: 2;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
/*
|
||||
-webkit-flex: 0 0 90px;
|
||||
flex: 0 0 90px;
|
||||
*/
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_cancelButton {
|
||||
-webkit-box-ordinal-group: 2;
|
||||
-moz-box-ordinal-group: 2;
|
||||
-ms-flex-order: 2;
|
||||
-webkit-order: 2;
|
||||
order: 2;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_rightRow {
|
||||
margin-top: 4px;
|
||||
background-color: #fff;
|
||||
|
||||
-webkit-box-ordinal-group: 3;
|
||||
-moz-box-ordinal-group: 3;
|
||||
-ms-flex-order: 3;
|
||||
-webkit-order: 3;
|
||||
order: 3;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_info {
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_simpleHeader {
|
||||
line-height: 83px;
|
||||
color: #454545;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
overflow: hidden;
|
||||
margin-left: 63px;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_simpleHeaderCancel {
|
||||
float: right;
|
||||
margin-top: 8px;
|
||||
padding: 24px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_name {
|
||||
vertical-align: middle;
|
||||
width: 100%;
|
||||
height: 31px;
|
||||
overflow: hidden;
|
||||
color: #454545;
|
||||
font-weight: bold;
|
||||
font-size: 22px;
|
||||
padding-left: 19px;
|
||||
padding-right: 16px;
|
||||
/* why isn't text-overflow working? */
|
||||
text-overflow: ellipsis;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_nametext {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_settingsHint {
|
||||
color: #a2a2a2 ! important;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_searchStatus {
|
||||
display: inline-block;
|
||||
font-weight: normal;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_settingsButton {
|
||||
display: inline-block;
|
||||
visibility: hidden;
|
||||
position: relative;
|
||||
bottom: 10px;
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_settingsButton object {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_name,
|
||||
.mx_RoomHeader_avatar,
|
||||
.mx_RoomHeader_avatarPicker,
|
||||
.mx_RoomHeader_avatarPicker_edit {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_name:hover div:not(.mx_RoomHeader_editable) {
|
||||
color: #76cfa6;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_name:hover .mx_RoomHeader_settingsButton {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_leaveButton {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_placeholder {
|
||||
color: #a2a2a2 ! important;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_editable {
|
||||
border-bottom: 1px solid #c7c7c7 ! important;
|
||||
min-width: 150px;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_editable:focus {
|
||||
border-bottom: 1px solid #76CFA6 ! important;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_topic {
|
||||
vertical-align: bottom;
|
||||
float: left;
|
||||
max-height: 42px;
|
||||
color: #454545;
|
||||
font-weight: 300;
|
||||
margin-left: 19px;
|
||||
margin-right: 16px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_avatar {
|
||||
display: table-cell;
|
||||
width: 48px;
|
||||
height: 50px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_avatarPicker_edit {
|
||||
position: absolute;
|
||||
margin-left: 16px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_avatarPicker_edit > label {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_avatarPicker_edit > input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_button {
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_button object {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_voipButton {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_voipButtons {
|
||||
margin-top: 18px;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -14,14 +14,22 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_RoomDropTarget {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
margin-left: 8px;
|
||||
margin-right: 8px;
|
||||
padding-top: 16px;
|
||||
padding-bottom: 16px;
|
||||
background-color: #fbfbfb;
|
||||
border: 1px dashed #d7d7d7;
|
||||
border-radius: 8px;
|
||||
.mx_RoomList {
|
||||
padding-top: 24px;
|
||||
padding-bottom: 12px;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.mx_RoomList_expandButton {
|
||||
margin-left: 8px;
|
||||
cursor: pointer;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
/* Evil hacky override until Chrome fixes drop and drag table cells
|
||||
and we can correctly fix horizontal wrapping in the sidebar again */
|
||||
.mx_RoomList_scrollbar .gm-scroll-view {
|
||||
overflow-x: hidden ! important;
|
||||
overflow-y: scroll ! important;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -14,47 +14,43 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_MemberList {
|
||||
height: 100%;
|
||||
margin-bottom: 100px;
|
||||
padding: 8px;
|
||||
.mx_RoomPreviewBar {
|
||||
text-align: center;
|
||||
height: 176px;
|
||||
|
||||
-webkit-flex: 1;
|
||||
flex: 1;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
|
||||
flex-direction: column;
|
||||
-webkit-flex-direction: column;
|
||||
|
||||
justify-content: center;
|
||||
-webkit-justify-content: center;
|
||||
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
|
||||
flex-direction: column;
|
||||
-webkit-flex-direction: column;
|
||||
}
|
||||
|
||||
.mx_MemberList_chevron {
|
||||
position: absolute;
|
||||
right: 35px;
|
||||
margin-top: -15px;
|
||||
.mx_RoomPreviewBar_wrapper {
|
||||
}
|
||||
|
||||
.mx_MemberList_border {
|
||||
border: 1px solid #a9dbf4;
|
||||
overflow-y: auto;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
|
||||
order: 1;
|
||||
-webkit-flex: 1 1 0;
|
||||
flex: 1 1 0px;
|
||||
.mx_RoomPreviewBar_invite_text {
|
||||
color: #454545;
|
||||
}
|
||||
|
||||
.mx_MemberList_wrapper {
|
||||
display: table;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
.mx_RoomPreviewBar_join_text {
|
||||
color: #ff0064;
|
||||
}
|
||||
|
||||
.mx_MemberList h2 {
|
||||
margin: 14px;
|
||||
.mx_RoomPreviewBar_preview_text {
|
||||
margin-top: 25px;
|
||||
color: #a4a4a4;
|
||||
}
|
||||
|
||||
.mx_RoomPreviewBar_join_text a {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
@ -0,0 +1,192 @@
|
||||
/*
|
||||
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_RoomSettings {
|
||||
margin-left: 65px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_powerLevels {
|
||||
display: table;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_powerLevel {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_powerLevelKey,
|
||||
.mx_RoomSettings_powerLevel .mx_PowerSelector {
|
||||
display: table-cell;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_powerLevelKey {
|
||||
text-align: right;
|
||||
padding-right: 0.3em;
|
||||
}
|
||||
|
||||
.mx_RoomSettings h3 {
|
||||
text-transform: uppercase;
|
||||
color: #3d3b39;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
margin-top: 36px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/*
|
||||
.mx_RoomSettings input,
|
||||
.mx_RoomSettings textarea {
|
||||
border-radius: 3px;
|
||||
border: 1px solid #c7c7c7;
|
||||
font-weight: 300;
|
||||
font-size: 13px;
|
||||
padding: 9px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
*/
|
||||
|
||||
.mx_RoomSettings .mx_RoomSettings_toggles label {
|
||||
margin-bottom: 8px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mx_RoomSettings .mx_RoomSettings_toggles input[type="checkbox"],
|
||||
.mx_RoomSettings .mx_RoomSettings_toggles input[type="radio"] {
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings .mx_RoomSettings_tags input[type="checkbox"] {
|
||||
margin-left: 1em;
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings .mx_RoomSettings_tags {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings .mx_RoomSettings_roomColor {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 37px;
|
||||
height: 37px;
|
||||
border: 1px solid #979797;
|
||||
margin-right: 13px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings .mx_RoomSettings_roomColor_selected {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings .mx_RoomSettings_roomColorPrimary {
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mx_RoomSettings .mx_RoomSettings_aliasLabel {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings .mx_RoomSettings_aliasesTable {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 0px;
|
||||
margin-left: 56px;
|
||||
display: table;
|
||||
}
|
||||
|
||||
.mx_RoomSettings .mx_RoomSettings_aliasesTableRow {
|
||||
display: table-row;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings .mx_RoomSettings_alias {
|
||||
max-width: 400px;
|
||||
margin-bottom: 16px;
|
||||
/*
|
||||
commented out so margin applies
|
||||
display: table-cell; */
|
||||
}
|
||||
|
||||
.mx_RoomSettings .mx_RoomSettings_addAlias,
|
||||
.mx_RoomSettings .mx_RoomSettings_deleteAlias {
|
||||
display: table-cell;
|
||||
padding-left: 0.5em;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomSettings .mx_RoomSettings_addAlias img,
|
||||
.mx_RoomSettings .mx_RoomSettings_deleteAlias img {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.mx_RoomSettings .mx_RoomSettings_aliasesTableRow:hover .mx_RoomSettings_addAlias img,
|
||||
.mx_RoomSettings .mx_RoomSettings_aliasesTableRow:hover .mx_RoomSettings_deleteAlias img {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_editable {
|
||||
border: 0px;
|
||||
border-bottom: 1px solid #c7c7c7;
|
||||
padding: 0px;
|
||||
min-width: 240px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_editable:focus {
|
||||
border-bottom: 1px solid #76CFA6;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_deleteAlias,
|
||||
.mx_RoomSettings_addAlias {
|
||||
display: table-cell;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_deleteAlias:hover,
|
||||
.mx_RoomSettings_addAlias:hover {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_aliasPlaceholder {
|
||||
color: #a2a2a2;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_buttons {
|
||||
text-align: right;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_button {
|
||||
display: inline;
|
||||
border: 0px;
|
||||
height: 36px;
|
||||
border-radius: 36px;
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
color: #fff;
|
||||
background-color: #76cfa6;
|
||||
width: auto;
|
||||
margin: auto;
|
||||
padding: 6px;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -16,33 +16,41 @@ limitations under the License.
|
||||
|
||||
.mx_RoomTile {
|
||||
cursor: pointer;
|
||||
display: table-row;
|
||||
color: #818794;
|
||||
/* This fixes wrapping of long room names, but breaks drag & drop previews */
|
||||
/* display: table-row; */
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.mx_RoomTile_avatar {
|
||||
display: table-cell;
|
||||
padding-right: 10px;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
padding-left: 10px;
|
||||
vertical-align: middle;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
padding-right: 8px;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
padding-left: 18px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_RoomTile_avatar img {
|
||||
border-radius: 20px;
|
||||
background-color: #dbdbdb;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_RoomTile_name {
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
vertical-align: middle;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
padding-right: 16px;
|
||||
color: rgba(69, 69, 69, 0.8);
|
||||
}
|
||||
|
||||
.mx_RoomTile_ellipsis .mx_RoomTile_name {
|
||||
font-style: italic;
|
||||
color: #454545;
|
||||
}
|
||||
|
||||
.mx_RoomTile_invite {
|
||||
/* color: rgba(69, 69, 69, 0.5);
|
||||
*/
|
||||
}
|
||||
|
||||
.collapsed .mx_RoomTile_name {
|
||||
@ -63,7 +71,7 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_RoomTile_badge {
|
||||
background-color: #80cef4;
|
||||
background-color: #76cfa6;
|
||||
color: #fff;
|
||||
border-radius: 26px;
|
||||
font-weight: 400;
|
||||
@ -75,6 +83,7 @@ limitations under the License.
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
.mx_RoomTile_badge {
|
||||
background-color: #ff0064;
|
||||
border: 3px solid #fff;
|
||||
@ -85,20 +94,48 @@ limitations under the License.
|
||||
right: 9px;
|
||||
bottom: 3px;
|
||||
}
|
||||
*/
|
||||
|
||||
.mx_RoomTile_unread,
|
||||
.mx_RoomTile_highlight,
|
||||
.mx_RoomTile_invited
|
||||
{
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
.mx_RoomTile_badge {
|
||||
background-color: #ff0064;
|
||||
width: 4px;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 5px;
|
||||
bottom: 5px;
|
||||
}
|
||||
|
||||
.mx_RoomTile_unreadNotify .mx_RoomTile_badge {
|
||||
background-color: #454545;
|
||||
}
|
||||
|
||||
.mx_RoomTile_selected {
|
||||
background-color: #f3f8fa;
|
||||
color: #80cef4;
|
||||
.mx_RoomTile_highlight .mx_RoomTile_badge {
|
||||
background-color: #ff0064;
|
||||
}
|
||||
|
||||
.mx_RoomTile_unread,
|
||||
.mx_RoomTile_highlight {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mx_RoomTile_selected .mx_RoomTile_name {
|
||||
color: #76cfa6 ! important;
|
||||
}
|
||||
|
||||
.mx_RoomTile_highlight .mx_RoomTile_name {
|
||||
color: #ff0064 ! important;
|
||||
}
|
||||
|
||||
.mx_RoomTile.mx_RoomTile_selected .mx_RoomTile_name {
|
||||
background: url('img/selected.png');
|
||||
background-repeat: no-repeat;
|
||||
background-position: right center;
|
||||
}
|
||||
|
||||
.mx_RoomTile_arrow {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.mx_RoomTile:hover {
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
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_SearchableEntityList {
|
||||
display: flex;
|
||||
display: -webkit-flex;
|
||||
|
||||
flex-direction: column;
|
||||
-webkit-flex-direction: column;
|
||||
}
|
||||
|
||||
.mx_SearchableEntityList_query {
|
||||
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #f0f0f0;
|
||||
padding: 9px;
|
||||
color: #454545;
|
||||
margin-left: 3px;
|
||||
font-size: 15px;
|
||||
margin-bottom: 8px;
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
.mx_SearchableEntityList_query::-moz-placeholder {
|
||||
color: #454545;
|
||||
opacity: 0.5;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.mx_SearchableEntityList_query::-webkit-input-placeholder {
|
||||
color: #454545;
|
||||
opacity: 0.5;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.mx_SearchableEntityList_listWrapper {
|
||||
flex: 1;
|
||||
-webkit-flex: 1;
|
||||
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.mx_SearchableEntityList_list {
|
||||
display: table;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mx_SearchableEntityList_list .mx_EntityTile_chevron {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_SearchableEntityList_hrWrapper {
|
||||
width: 100%;
|
||||
flex: 0 0 auto;
|
||||
-webkit-flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.mx_SearchableEntityList hr {
|
||||
height: 1px;
|
||||
border: 0px;
|
||||
color: #e1dddd;
|
||||
background-color: #e1dddd;
|
||||
margin-right: 15px;
|
||||
margin-top: 11px;
|
||||
margin-bottom: 11px;
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
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_TabCompleteBar {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mx_TabCompleteBar_item {
|
||||
display: inline-block;
|
||||
margin-right: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_TabCompleteBar_command {
|
||||
margin-right: 8px;
|
||||
background-color: #76CFA6;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
margin-bottom: 6px;
|
||||
border-radius: 30px;
|
||||
}
|
||||
|
||||
.mx_TabCompleteBar_command .mx_TabCompleteBar_text {
|
||||
opacity: 1.0;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.mx_TabCompleteBar_item img {
|
||||
margin-right: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_TabCompleteBar_text {
|
||||
color: #4a4a4a;
|
||||
opacity: 0.5;
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
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_TopUnreadMessagesBar {
|
||||
margin: auto; /* centre horizontally */
|
||||
max-width: 960px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.mx_TopUnreadMessagesBar_scrollUp {
|
||||
display: inline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_TopUnreadMessagesBar_scrollUp img {
|
||||
padding-left: 10px;
|
||||
padding-right: 31px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_TopUnreadMessagesBar_scrollUp span {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.mx_TopUnreadMessagesBar_close {
|
||||
float: right;
|
||||
padding-right: 14px;
|
||||
padding-top: 3px;
|
||||
cursor: pointer;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -16,14 +16,15 @@ limitations under the License.
|
||||
|
||||
.mx_IncomingCallBox {
|
||||
text-align: center;
|
||||
border: 1px solid #a9dbf4;
|
||||
border: 1px solid #a4a4a4;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
left: 235px;
|
||||
top: 155px;
|
||||
padding: 6px;
|
||||
margin-top: -3px;
|
||||
margin-left: -20px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.mx_IncomingCallBox_chevron {
|
||||
@ -39,14 +40,15 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_IncomingCallBox_buttons {
|
||||
display: table-row;
|
||||
display: flex;
|
||||
display: -webkit-flex;
|
||||
}
|
||||
|
||||
.mx_IncomingCallBox_buttons_cell {
|
||||
vertical-align: middle;
|
||||
display: table-cell;
|
||||
padding: 6px;
|
||||
width: 50%;
|
||||
flex: 1;
|
||||
-webkit-flex: 1;
|
||||
}
|
||||
|
||||
.mx_IncomingCallBox_buttons_decline,
|
||||
@ -57,6 +59,7 @@ limitations under the License.
|
||||
line-height: 36px;
|
||||
border-radius: 36px;
|
||||
color: #fff;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.mx_IncomingCallBox_buttons_decline {
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -31,9 +31,15 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_VideoView_localVideoFeed {
|
||||
width: 20%;
|
||||
width: 25%;
|
||||
height: 25%;
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
bottom: 28px;
|
||||
left: 10px;
|
||||
bottom: 10px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.mx_VideoView_localVideoFeed video {
|
||||
width: auto;
|
||||
height: 100%;
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_EventTile {
|
||||
max-width: 100%;
|
||||
clear: both;
|
||||
margin-top: 32px;
|
||||
margin-left: 56px;
|
||||
}
|
||||
|
||||
.mx_EventTile_avatar {
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
margin-left: -64px;
|
||||
margin-top: -7px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.mx_EventTile_avatar img {
|
||||
background-color: #dbdbdb;
|
||||
border-radius: 20px;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.mx_EventTile_continuation {
|
||||
margin-top: 8px ! important;
|
||||
}
|
||||
|
||||
.mx_EventTile .mx_SenderProfile {
|
||||
color: #454545;
|
||||
opacity: 0.5;
|
||||
font-size: 14px;
|
||||
margin-bottom: 4px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mx_EventTile .mx_MessageTimestamp {
|
||||
color: #454545;
|
||||
opacity: 0.5;
|
||||
font-size: 14px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.mx_EventTile_content {
|
||||
padding-right: 100px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mx_EventTile_notice .mx_MessageTile_content {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.mx_EventTile_sending {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.mx_EventTile_notSent {
|
||||
color: #f11;
|
||||
}
|
||||
|
||||
.mx_EventTile_highlight {
|
||||
color: #FF0064;
|
||||
}
|
||||
|
||||
.mx_EventTile_msgOption {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.mx_MessageTimestamp {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_EventTile_last .mx_MessageTimestamp {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mx_EventTile:hover .mx_MessageTimestamp {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mx_EventTile_editButton {
|
||||
float: right;
|
||||
display: none;
|
||||
border: 0px;
|
||||
outline: none;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.mx_EventTile:hover .mx_EventTile_editButton {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_EventTile.menu .mx_EventTile_editButton {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_EventTile.menu .mx_MessageTimestamp {
|
||||
display: inline-block;
|
||||
}
|
@ -1,134 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_MemberTile {
|
||||
display: table-row;
|
||||
height: 49px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_MemberTile_avatar {
|
||||
display: table-cell;
|
||||
padding-left: 14px;
|
||||
padding-right: 12px;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
vertical-align: middle;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_MemberTile_inviteTile {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_MemberTile_inviteEditing {
|
||||
display: initial ! important;
|
||||
}
|
||||
|
||||
.mx_MemberTile_inviteEditing .mx_MemberTile_avatar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_MemberTile_inviteEditing .mx_MemberTile_name {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.mx_MemberTile_inviteEditing .mx_MemberTile_name input {
|
||||
border-radius: 3px;
|
||||
border: 1px solid #c7c7c7;
|
||||
font-weight: 300;
|
||||
font-size: 14px;
|
||||
padding: 9px;
|
||||
margin-top: 6px;
|
||||
margin-left: 14px;
|
||||
}
|
||||
|
||||
.mx_MemberTile_power {
|
||||
position: absolute;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
left: 10px;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
.mx_MemberTile_name {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.mx_MemberTile_details {
|
||||
display: table-cell;
|
||||
padding-right: 14px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_MemberTile_hover {
|
||||
background-color: #f0f0f0;
|
||||
font-size: 12px;
|
||||
color: #747474;
|
||||
}
|
||||
|
||||
.mx_MemberTile_userId {
|
||||
font-weight: bold;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.mx_MemberTile_leave {
|
||||
cursor: pointer;
|
||||
margin-top: 8px;
|
||||
margin-right: -4px;
|
||||
margin-left: 6px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
/*
|
||||
.mx_MemberTile_nameWrapper {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.mx_MemberTile_nameSpan {
|
||||
}
|
||||
*/
|
||||
|
||||
.mx_MemberTile_unavailable .mx_MemberTile_avatar,
|
||||
.mx_MemberTile_unavailable .mx_MemberTile_name,
|
||||
.mx_MemberTile_unavailable .mx_MemberTile_nameSpan
|
||||
{
|
||||
opacity: 0.66;
|
||||
}
|
||||
|
||||
.mx_MemberTile_offline .mx_MemberTile_avatar,
|
||||
.mx_MemberTile_offline .mx_MemberTile_name,
|
||||
.mx_MemberTile_offline .mx_MemberTile_nameSpan
|
||||
{
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
.mx_MemberTile_zalgo {
|
||||
font-family: Helvetica, Arial, Sans-Serif;
|
||||
}
|
||||
|
||||
.mx_MemberTile:hover .mx_MessageTimestamp {
|
||||
display: block;
|
||||
}
|
@ -1,173 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_RoomHeader {
|
||||
}
|
||||
|
||||
.mx_RoomHeader_wrapper {
|
||||
max-width: 720px;
|
||||
margin: auto;
|
||||
height: 88px;
|
||||
border-bottom: 1px solid #a8dbf3;
|
||||
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_leftRow {
|
||||
height: 48px;
|
||||
margin-top: 18px;
|
||||
|
||||
-webkit-box-ordinal-group: 1;
|
||||
-moz-box-ordinal-group: 1;
|
||||
-ms-flex-order: 1;
|
||||
-webkit-order: 1;
|
||||
order: 1;
|
||||
|
||||
-webkit-flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_textButton {
|
||||
height: 48px;
|
||||
margin-top: 18px;
|
||||
background-color: #80cef4;
|
||||
border-radius: 48px;
|
||||
margin-right: 8px;
|
||||
color: #fff;
|
||||
line-height: 48px;
|
||||
text-align: center;
|
||||
|
||||
-webkit-box-ordinal-group: 2;
|
||||
-moz-box-ordinal-group: 2;
|
||||
-ms-flex-order: 2;
|
||||
-webkit-order: 2;
|
||||
order: 2;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
/*
|
||||
-webkit-flex: 0 0 90px;
|
||||
flex: 0 0 90px;
|
||||
*/
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_rightRow {
|
||||
height: 48px;
|
||||
margin-top: 18px;
|
||||
background-color: #fff;
|
||||
border-radius: 48px;
|
||||
border: 1px solid #a9dbf4;
|
||||
|
||||
-webkit-box-ordinal-group: 3;
|
||||
-moz-box-ordinal-group: 3;
|
||||
-ms-flex-order: 3;
|
||||
-webkit-order: 3;
|
||||
order: 3;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_info {
|
||||
display: table-cell;
|
||||
height: 48px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_simpleHeader {
|
||||
line-height: 88px;
|
||||
color: #80cef4;
|
||||
font-weight: 400;
|
||||
font-size: 20px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_name {
|
||||
vertical-align: middle;
|
||||
height: 28px;
|
||||
color: #80cef4;
|
||||
font-weight: 400;
|
||||
font-size: 20px;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_nameEditing {
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_name input, .mx_RoomHeader_nameInput {
|
||||
border-radius: 3px;
|
||||
width: 260px;
|
||||
border: 1px solid #c7c7c7;
|
||||
font-weight: 300;
|
||||
font-size: 14px;
|
||||
padding: 9px;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_nameInput {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_topic {
|
||||
vertical-align: bottom;
|
||||
float: left;
|
||||
max-height: 38px;
|
||||
color: #70b5d7;
|
||||
font-weight: 300;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_avatar {
|
||||
display: table-cell;
|
||||
width: 48px;
|
||||
height: 50px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_avatar img {
|
||||
border-radius: 24px;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_button {
|
||||
height: 48px;
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_button img {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_voipButton {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_voipButtons {
|
||||
margin-top: 18px;
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_RoomSettings {
|
||||
max-height: 250px;
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_settings {
|
||||
display: table;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_settings > div {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_settings > div > * {
|
||||
display: table-cell;
|
||||
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings input,
|
||||
.mx_RoomSettings textarea {
|
||||
border-radius: 3px;
|
||||
border: 1px solid #c7c7c7;
|
||||
font-weight: 300;
|
||||
font-size: 14px;
|
||||
padding: 9px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_description {
|
||||
width: 330px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_buttons {
|
||||
text-align: right;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.mx_RoomSettings_button {
|
||||
display: inline;
|
||||
border: 0px;
|
||||
height: 36px;
|
||||
border-radius: 36px;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
background-color: #80cef4;
|
||||
width: auto;
|
||||
margin: auto;
|
||||
padding: 6px;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
.mx_ViewSource pre {
|
||||
text-align: left;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
.mx_CompatibilityPage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #e55;
|
||||
}
|
||||
|
||||
.mx_CompatibilityPage_box {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
width: 500px;
|
||||
height: 300px;
|
||||
border: 1px solid;
|
||||
padding: 10px;
|
||||
background-color: #fcc;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -34,16 +34,21 @@ limitations under the License.
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_LeftPanel .mx_RoomList {
|
||||
.mx_LeftPanel_callView {
|
||||
|
||||
}
|
||||
|
||||
.mx_LeftPanel .mx_RoomList_scrollbar {
|
||||
-webkit-box-ordinal-group: 1;
|
||||
-moz-box-ordinal-group: 1;
|
||||
-ms-flex-order: 1;
|
||||
-webkit-order: 1;
|
||||
order: 1;
|
||||
|
||||
overflow-y: auto;
|
||||
-webkit-flex: 1 1 0;
|
||||
flex: 1 1 0;
|
||||
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.mx_LeftPanel .mx_BottomLeftMenu {
|
||||
@ -53,17 +58,23 @@ limitations under the License.
|
||||
-webkit-order: 3;
|
||||
order: 3;
|
||||
|
||||
-webkit-flex: 0 0 170px;
|
||||
flex: 0 0 170px;
|
||||
-webkit-flex: 0 0 140px;
|
||||
flex: 0 0 140px;
|
||||
|
||||
border-top: 1px solid #f3f8fa;
|
||||
background-color: rgba(118,207,166,0.2);
|
||||
}
|
||||
|
||||
.mx_LeftPanel .mx_BottomLeftMenu .mx_RoomTile {
|
||||
color: #378bb4;
|
||||
color: #454545;
|
||||
}
|
||||
|
||||
.mx_LeftPanel .mx_BottomLeftMenu .mx_BottomLeftMenu_options {
|
||||
margin-top: 12px;
|
||||
margin-top: 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mx_LeftPanel .mx_BottomLeftMenu img {
|
||||
border-radius: 0px;
|
||||
background-color: transparent;
|
||||
vertical-align: middle;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -33,32 +33,57 @@ limitations under the License.
|
||||
-webkit-order: 1;
|
||||
order: 1;
|
||||
|
||||
-webkit-flex: 0 0 66px;
|
||||
flex: 0 0 66px;
|
||||
-webkit-flex: 0 0 83px;
|
||||
flex: 0 0 83px;
|
||||
}
|
||||
|
||||
/** Fixme - factor this out with the main header **/
|
||||
|
||||
.mx_RightPanel_headerButtonGroup {
|
||||
margin-top: 18px;
|
||||
height: 48px;
|
||||
float: right;
|
||||
margin-top: 32px;
|
||||
float: left;
|
||||
background-color: #fff;
|
||||
border-radius: 48px;
|
||||
border: 1px solid #a9dbf4;
|
||||
margin-right: 22px;
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
.mx_RightPanel_headerButton {
|
||||
cursor: pointer;
|
||||
height: 48px;
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_RightPanel .mx_MemberList {
|
||||
.mx_RightPanel_headerButton object {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mx_RightPanel_headerButton_highlight {
|
||||
position: absolute;
|
||||
bottom: -2px;
|
||||
left: 10px;
|
||||
width: 25px;
|
||||
height: 4px;
|
||||
background-color: #76cfa6;
|
||||
}
|
||||
|
||||
.mx_RightPanel_headerButton_badge {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 28px;
|
||||
font-size: 12px;
|
||||
background-color: #76cfa6;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
border-radius: 20px;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
.mx_RightPanel .mx_MemberList,
|
||||
.mx_RightPanel .mx_MemberInfo {
|
||||
-webkit-box-ordinal-group: 2;
|
||||
-moz-box-ordinal-group: 2;
|
||||
-ms-flex-order: 2;
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -15,7 +15,8 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_RoomDirectory {
|
||||
width: 720px;
|
||||
max-width: 960px;
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-bottom: 12px;
|
||||
@ -50,7 +51,7 @@ limitations under the License.
|
||||
border-radius: 3px;
|
||||
border: 1px solid #c7c7c7;
|
||||
font-weight: 300;
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
padding: 9px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 12px;
|
||||
@ -63,37 +64,61 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_table {
|
||||
font-size: 14px;
|
||||
color: #4a4a4a;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_table th {
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
.mx_RoomDirectory_roomAvatar {
|
||||
width: 24px;
|
||||
padding-left: 12px;
|
||||
padding-right: 24px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_table tbody {
|
||||
.mx_RoomDirectory_roomDescription {
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_name {
|
||||
display: inline-block;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_perms {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_perm {
|
||||
display: inline;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
height: 15px;
|
||||
border-radius: 11px;
|
||||
background-color: #eaf5f0;
|
||||
text-transform: uppercase;
|
||||
font-weight: 600;
|
||||
font-size: 11px;
|
||||
color: #61c295;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_topic {
|
||||
cursor: initial;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_alias {
|
||||
font-size: 12px;
|
||||
color: #b3b3b3;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_roomMemberCount {
|
||||
text-align: right;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_table tr {
|
||||
padding-bottom: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_table td {
|
||||
font-weight: 300;
|
||||
font-size: 16px;
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_table .mx_RoomDirectory_name {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_table .mx_RoomDirectory_topic {
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_table td,
|
||||
.mx_RoomDirectory_table th, {
|
||||
padding: 6px;
|
||||
}
|
41
src/skins/vector/css/vector-web/structures/RoomSubList.css
Normal file
41
src/skins/vector/css/vector-web/structures/RoomSubList.css
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
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_RoomSubList {
|
||||
display: table;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_label {
|
||||
text-transform: uppercase;
|
||||
color: #3d3b39;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_chevron {
|
||||
padding-left: 5px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.collapsed .mx_RoomSubList_chevron {
|
||||
padding-left: 13px;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -14,9 +14,9 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_MemberAvatar {
|
||||
z-index: 20;
|
||||
border-radius: 20px;
|
||||
background-color: #dbdbdb;
|
||||
.mx_ViewSource pre {
|
||||
text-align: left;
|
||||
font-size: 12px;
|
||||
padding: 0.5em 1em 0.5em 1em;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
150
src/skins/vector/css/vector-web/views/elements/ImageView.css
Normal file
150
src/skins/vector/css/vector-web/views/elements/ImageView.css
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/* This has got to be the most fragile piece of CSS ever written.
|
||||
But empirically it works on Chrome/FF/Safari
|
||||
*/
|
||||
|
||||
.mx_ImageView {
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mx_ImageView_lhs {
|
||||
-webkit-box-ordinal-group: 1;
|
||||
order: 1;
|
||||
-webkit-flex: 1;
|
||||
flex: 1 1 10%;
|
||||
min-width: 60px;
|
||||
/*
|
||||
background-color: #080;
|
||||
height: 20px;
|
||||
*/
|
||||
}
|
||||
|
||||
.mx_ImageView_content {
|
||||
-webkit-box-ordinal-group: 2;
|
||||
order: 2;
|
||||
/* min-width hack needed for FF */
|
||||
min-width: 0px;
|
||||
height: 90%;
|
||||
-webkit-flex: 15;
|
||||
flex: 15 15 0;
|
||||
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
-webkit-justify-content: center;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.mx_ImageView_content img {
|
||||
max-width: 100%;
|
||||
/* XXX: max-height interacts badly with flex on Chrome and doesn't relayout properly until you refresh */
|
||||
max-height: 100%;
|
||||
/* object-fit hack needed for Chrome due to Chrome not re-laying-out until you refresh */
|
||||
object-fit: contain;
|
||||
/* background-image: url('img/trans.png'); */
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.mx_ImageView_labelWrapper {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.mx_ImageView_label {
|
||||
text-align: left;
|
||||
display: flex;
|
||||
display: -webkit-flex;
|
||||
justify-content: center;
|
||||
-webkit-justify-content: center;
|
||||
flex-direction: column;
|
||||
-webkit-flex-direction: column;
|
||||
padding-left: 60px;
|
||||
padding-right: 60px;
|
||||
min-height: 100%;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.mx_ImageView_cancel {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
padding: 35px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_ImageView_name {
|
||||
font-size: 18px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.mx_ImageView_metadata {
|
||||
font-size: 15px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.mx_ImageView_download {
|
||||
display: table;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 6px;
|
||||
border-radius: 5px;
|
||||
background-color: #454545;
|
||||
font-size: 14px;
|
||||
padding: 9px;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
|
||||
.mx_ImageView_size {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.mx_ImageView_link {
|
||||
color: #fff ! important;
|
||||
text-decoration: none ! important;
|
||||
}
|
||||
|
||||
.mx_ImageView_button {
|
||||
font-size: 15px;
|
||||
opacity: 0.5;
|
||||
margin-top: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_ImageView_shim {
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.mx_ImageView_rhs {
|
||||
-webkit-box-ordinal-group: 3;
|
||||
order: 3;
|
||||
-webkit-flex: 1;
|
||||
flex: 1 1 10%;
|
||||
min-width: 300px;
|
||||
/*
|
||||
background-color: #800;
|
||||
height: 20px;
|
||||
*/
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -14,18 +14,19 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_RoomList {
|
||||
}
|
||||
|
||||
.mx_RoomList_recents {
|
||||
margin-top: -12px;
|
||||
display: table;
|
||||
table-layout: fixed;
|
||||
.mx_Spinner {
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
-webkit-justify-content: center;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
-webkit-flex: 1;
|
||||
}
|
||||
|
||||
.mx_RoomList h2 {
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
padding-bottom: 10px;
|
||||
.mx_MatrixChat_middlePanel .mx_Spinner {
|
||||
height: auto;
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
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_GuestWarningBar {
|
||||
background-color: #76cfa6;
|
||||
color: #fff;
|
||||
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mx_GuestWarningBar_warning {
|
||||
margin-left: 16px;
|
||||
margin-right: 8px;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.mx_GuestWarningBar a {
|
||||
color: #fff ! important;
|
||||
text-decoration: underline ! important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
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_MatrixToolbar {
|
||||
background-color: #76cfa6;
|
||||
color: #fff;
|
||||
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mx_MatrixToolbar_warning {
|
||||
margin-left: 16px;
|
||||
margin-right: 8px;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.mx_MatrixToolbar_link
|
||||
{
|
||||
color: #fff ! important;
|
||||
text-decoration: underline ! important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_MatrixToolbar_close {
|
||||
-webkit-flex: 1;
|
||||
flex: 1;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.mx_MatrixToolbar_close img {
|
||||
display: block;
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -13,8 +13,3 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_SenderProfile_zalgo {
|
||||
font-family: Helvetica, Arial, Sans-Serif;
|
||||
display: table-row ! important;
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
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_RoomDropTarget {
|
||||
font-size: 13px;
|
||||
margin-left: 10px;
|
||||
margin-right: 15px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
border: 1px dashed #76cfa6;
|
||||
color: #454545;
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.collapsed .mx_RoomDropTarget {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.mx_RoomDropTarget_placeholder {
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
.mx_RoomDropTarget_avatar {
|
||||
background-color: #fff;
|
||||
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;
|
||||
}
|
||||
|
||||
.collapsed .mx_RoomDropTarget_avatar {
|
||||
float: none;
|
||||
}
|
||||
|
||||
.collapsed .mx_RoomDropTarget_label {
|
||||
display: none;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -17,11 +17,10 @@ limitations under the License.
|
||||
.mx_RoomTooltip {
|
||||
display: none;
|
||||
position: fixed;
|
||||
border: 1px solid #a9dbf4;
|
||||
border: 1px solid #a4a4a4;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
z-index: 1000;
|
||||
margin-top: 6px;
|
||||
left: 64px;
|
||||
padding: 6px;
|
||||
}
|
86
src/skins/vector/css/vector-web/views/rooms/SearchBar.css
Normal file
86
src/skins/vector/css/vector-web/views/rooms/SearchBar.css
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
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_SearchBar {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
display: flex;
|
||||
display: -webkit-flex;
|
||||
align-items: center;
|
||||
-webkit-align-items: center;
|
||||
}
|
||||
|
||||
.mx_SearchBar_input {
|
||||
display: inline block;
|
||||
border-radius: 3px 0px 0px 3px;
|
||||
border: 1px solid #f0f0f0;
|
||||
font-size: 15px;
|
||||
padding: 9px;
|
||||
padding-left: 11px;
|
||||
width: auto;
|
||||
flex: 1 1 0;
|
||||
-webkit-flex: 1 1 0;
|
||||
}
|
||||
|
||||
.mx_SearchBar_searchButton {
|
||||
cursor: pointer;
|
||||
margin-right: 10px;
|
||||
width: 37px;
|
||||
height: 37px;
|
||||
border-radius: 0px 3px 3px 0px;
|
||||
background-color: #76CFA6;
|
||||
}
|
||||
|
||||
@keyframes pulsate {
|
||||
0% { opacity: 1.0; }
|
||||
50% { opacity: 0.1; }
|
||||
100% { opacity: 1.0; }
|
||||
}
|
||||
|
||||
.mx_SearchBar_searching img {
|
||||
animation: pulsate 0.5s ease-out;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
.mx_SearchBar_button {
|
||||
display: inline;
|
||||
border: 0px;
|
||||
border-radius: 36px;
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
color: #fff;
|
||||
background-color: #76cfa6;
|
||||
width: auto;
|
||||
margin: auto;
|
||||
margin-left: 7px;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 4px;
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_SearchBar_unselected {
|
||||
background-color: #fff;
|
||||
color: #76CFA6;
|
||||
border: #76CFA6 1px solid;
|
||||
}
|
||||
|
||||
.mx_SearchBar_cancel {
|
||||
padding-left: 14px;
|
||||
padding-right: 14px;
|
||||
cursor: pointer;
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
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_UserNotifSettings_tableRow
|
||||
{
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.mx_UserNotifSettings_inputCell {
|
||||
display: table-cell;
|
||||
padding-bottom: 21px;
|
||||
padding-right: 8px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.mx_UserNotifSettings_labelCell
|
||||
{
|
||||
padding-bottom: 21px;
|
||||
width: 270px;
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.mx_UserNotifSettings_pushRulesTableWrapper {
|
||||
padding-bottom: 21px;
|
||||
}
|
||||
|
||||
.mx_UserNotifSettings_pushRulesTable {
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.mx_UserNotifSettings_pushRulesTable thead {
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.mx_UserNotifSettings_pushRulesTable tbody th {
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.mx_UserNotifSettings_pushRulesTable tbody th:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.mx_UserNotifSettings_keywords {
|
||||
cursor: pointer;
|
||||
color: #76cfa6;
|
||||
}
|
24
src/skins/vector/fonts/OpenSans.css
Normal file
24
src/skins/vector/fonts/OpenSans.css
Normal file
@ -0,0 +1,24 @@
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans'), local('OpenSans'), url(opensans/v13/cJZKeOuBrn4kERxqtaUH3ZBw1xU1rKptJj_0jans920.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(opensans/v13/MTP_ySUJH_bn48VBG8sNShampu5_7CjHW5spxoeN3Vs.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold'), local('OpenSans-Bold'), url(opensans/v13/k3k702ZOKiLJc3WVjuplzBampu5_7CjHW5spxoeN3Vs.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user