Merge branch 'develop'
This commit is contained in:
commit
04b51f6f0f
|
@ -1,3 +1,8 @@
|
||||||
node_modules
|
node_modules
|
||||||
vector/bundle.*
|
vector/bundle.*
|
||||||
lib
|
lib
|
||||||
|
.DS_Store
|
||||||
|
key.pem
|
||||||
|
cert.pem
|
||||||
|
vector/components.css
|
||||||
|
packages/
|
||||||
|
|
|
@ -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
|
* https://github.com/neko259
|
||||||
Improved scrollbar CSS
|
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`
|
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`
|
1. Clone the repo: `git clone https://github.com/vector-im/vector-web.git`
|
||||||
3. Switch to the SDK directory: `cd vector-web`
|
1. Switch to the vector directory: `cd vector-web`
|
||||||
4. Install the prerequisites: `npm install`
|
1. Install the prerequisites: `npm install`
|
||||||
5. Start the development builder and a testing server: `npm start`
|
1. Start the development builder and a testing server: `npm start`
|
||||||
6. Wait a few seconds for the initial build to finish.
|
1. Wait a few seconds for the initial build to finish (the command won't
|
||||||
7. Open http://127.0.0.1:8080/ in your browser to see your newly built Vector.
|
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
|
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
|
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
|
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
|
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`
|
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
|
too, which can't be installed automatically due to https://github.com/npm/npm/issues/3055.
|
||||||
the `develop` branches of these libraries and then use `npm link` to tell Vector
|
To get the right dependencies, check out the `develop` branches of these libraries and
|
||||||
about them:
|
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`
|
1. `git clone git@github.com:matrix-org/matrix-react-sdk.git`
|
||||||
2. `cd matrix-react-sdk`
|
1. `pushd matrix-react-sdk`
|
||||||
3. `git checkout develop`
|
1. `git checkout develop`
|
||||||
4. `npm install`
|
1. `npm install`
|
||||||
5. `npm start` (to start the dev rebuilder)
|
1. `rm -r node_modules/matrix-js-sdk; ln -s ../../matrix-js-sdk node_modules/`
|
||||||
6. `cd ../vector-web`
|
1. `popd`
|
||||||
7. Link the react sdk package into the example:
|
|
||||||
`npm link path/to/your/react/sdk`
|
|
||||||
|
|
||||||
Similarly, you may need to `npm link path/to/your/js/sdk` in your `matrix-react-sdk`
|
Finally, build and start vector itself:
|
||||||
directory.
|
|
||||||
|
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
|
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`.
|
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
|
Enabling encryption
|
||||||
about "Cannot resolve module 'source-map-loader'" due to shortcomings in webpack.
|
===================
|
||||||
|
|
||||||
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
|
To build a version of vector with support for end-to-end encryption, install
|
||||||
actually serve up the app, which is entirely static content.
|
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.
|
||||||
|
|
|
@ -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)
|
|
@ -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",
|
"name": "vector-web",
|
||||||
"version": "0.1.2",
|
"version": "0.2.0",
|
||||||
"description": "Vector webapp",
|
"description": "Vector webapp",
|
||||||
"author": "matrix.org",
|
"author": "matrix.org",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -9,40 +9,56 @@
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"style": "bundle.css",
|
"style": "bundle.css",
|
||||||
|
"matrix-react-parent": "matrix-react-sdk",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"reskindex": "reskindex vector -h src/skins/vector/header",
|
"reskindex": "reskindex -h src/header",
|
||||||
"build:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/bundle.css -c uglifycss --no-watch",
|
"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:compile": "babel --source-maps -d lib src",
|
||||||
"build:bundle": "NODE_ENV=production webpack -p lib/vector/index.js vector/bundle.js",
|
"build:bundle": "NODE_ENV=production webpack -p lib/vector/index.js vector/bundle.js",
|
||||||
"build": "npm run build:css && npm run build:compile && npm run build:bundle",
|
"build": "npm run build:css && npm run build:compile && npm run build:bundle",
|
||||||
|
"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: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",
|
"//cache": "Note the -c 1 below due to https://code.google.com/p/chromium/issues/detail?id=508270",
|
||||||
"start": "parallelshell \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
|
"start": "parallelshell \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
|
||||||
"clean": "rimraf lib vector/bundle.css vector/bundle.js vector/bundle.js.map",
|
"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"
|
"prepublish": "npm run build:css && npm run build:compile"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"babel-polyfill": "^6.5.0",
|
||||||
"classnames": "^2.1.2",
|
"classnames": "^2.1.2",
|
||||||
|
"extract-text-webpack-plugin": "^0.9.1",
|
||||||
"filesize": "^3.1.2",
|
"filesize": "^3.1.2",
|
||||||
"flux": "~2.0.3",
|
"flux": "~2.0.3",
|
||||||
|
"gemini-scrollbar": "^1.3.0",
|
||||||
|
"gfm.css": "^1.1.1",
|
||||||
|
"highlight.js": "^9.0.0",
|
||||||
"linkifyjs": "^2.0.0-beta.4",
|
"linkifyjs": "^2.0.0-beta.4",
|
||||||
"matrix-js-sdk": "^0.3.0",
|
"matrix-js-sdk": "^0.4.0",
|
||||||
"matrix-react-sdk": "^0.0.2",
|
"matrix-react-sdk": "^0.1.0",
|
||||||
|
"modernizr": "^3.1.0",
|
||||||
"q": "^1.4.1",
|
"q": "^1.4.1",
|
||||||
"react": "^0.13.3",
|
"react": "^0.14.2",
|
||||||
"react-loader": "^1.4.0"
|
"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": {
|
"devDependencies": {
|
||||||
"babel": "^5.8.23",
|
"babel": "^5.8.23",
|
||||||
"babel-core": "^5.8.25",
|
"babel-core": "^5.8.25",
|
||||||
"babel-loader": "^5.3.2",
|
"babel-loader": "^5.3.2",
|
||||||
"catw": "^1.0.1",
|
"catw": "^1.0.1",
|
||||||
|
"css-raw-loader": "^0.1.1",
|
||||||
"http-server": "^0.8.4",
|
"http-server": "^0.8.4",
|
||||||
"json-loader": "^0.5.3",
|
"json-loader": "^0.5.3",
|
||||||
"parallelshell": "^1.2.0",
|
"parallelshell": "^1.2.0",
|
||||||
"rimraf": "^2.4.3",
|
"rimraf": "^2.4.3",
|
||||||
"source-map-loader": "^0.1.5",
|
"source-map-loader": "^0.1.5",
|
||||||
"uglifycss": "0.0.15"
|
"webpack": "^1.12.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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -85,15 +85,15 @@ ConferenceCall.prototype._getConferenceUserRoom = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if this room member is in fact a conference bot.
|
* Check if this user ID is in fact a conference bot.
|
||||||
* @param {RoomMember} The room member to check
|
* @param {string} userId The user ID to check.
|
||||||
* @return {boolean} True if it is a conference bot.
|
* @return {boolean} True if it is a conference bot.
|
||||||
*/
|
*/
|
||||||
module.exports.isConferenceUser = function(roomMember) {
|
module.exports.isConferenceUser = function(userId) {
|
||||||
if (roomMember.userId.indexOf("@" + USER_PREFIX) !== 0) {
|
if (userId.indexOf("@" + USER_PREFIX) !== 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var base64part = roomMember.userId.split(":")[0].substring(1 + USER_PREFIX.length);
|
var base64part = userId.split(":")[0].substring(1 + USER_PREFIX.length);
|
||||||
if (base64part) {
|
if (base64part) {
|
||||||
var decoded = new Buffer(base64part, "base64").toString();
|
var decoded = new Buffer(base64part, "base64").toString();
|
||||||
// ! $STUFF : $STUFF
|
// ! $STUFF : $STUFF
|
|
@ -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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -40,19 +40,19 @@ module.exports = React.createClass({
|
||||||
return <div className="mx_RoomTile_name">{name}</div>
|
return <div className="mx_RoomTile_name">{name}</div>
|
||||||
}
|
}
|
||||||
else if (this.state.hover) {
|
else if (this.state.hover) {
|
||||||
var RoomTooltip = sdk.getComponent("molecules.RoomTooltip");
|
var RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
|
||||||
return <RoomTooltip name={name}/>;
|
return <RoomTooltip name={name}/>;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var BottomLeftMenuTile = sdk.getComponent('molecules.BottomLeftMenuTile');
|
var BottomLeftMenuTile = sdk.getComponent('rooms.BottomLeftMenuTile');
|
||||||
return (
|
return (
|
||||||
<div className="mx_BottomLeftMenu">
|
<div className="mx_BottomLeftMenu">
|
||||||
<div className="mx_BottomLeftMenu_options">
|
<div className="mx_BottomLeftMenu_options">
|
||||||
<BottomLeftMenuTile collapsed={ this.props.collapsed } img="img/create-big.png" label="Create new room" onClick={ this.onCreateRoomClick }/>
|
<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.png" label="Directory" onClick={ this.onRoomDirectoryClick }/>
|
<BottomLeftMenuTile collapsed={ this.props.collapsed } img="img/directory-big.svg" 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/settings-big.svg" label="Settings" onClick={ this.onSettingsClick }/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
|
@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
|
@ -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);
|
|
@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -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);
|
|
@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -26,7 +26,7 @@ module.exports = React.createClass({
|
||||||
var h = this.props.h || 32;
|
var h = this.props.h || 32;
|
||||||
var imgClass = this.props.imgClassName || "";
|
var imgClass = this.props.imgClassName || "";
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="mx_Spinner">
|
||||||
<img src="img/spinner.gif" width={w} height={h} className={imgClass}/>
|
<img src="img/spinner.gif" width={w} height={h} className={imgClass}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
|
@ -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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -17,23 +17,28 @@ limitations under the License.
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
var Notifier = require("matrix-react-sdk/lib/Notifier");
|
||||||
var sdk = require('matrix-react-sdk')
|
var sdk = require('matrix-react-sdk')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'MatrixToolbar',
|
displayName: 'MatrixToolbar',
|
||||||
|
|
||||||
hideToolbar: function() {
|
hideToolbar: function() {
|
||||||
var Notifier = sdk.getComponent('organisms.Notifier');
|
|
||||||
Notifier.setToolbarHidden(true);
|
Notifier.setToolbarHidden(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onClick: function() {
|
||||||
|
Notifier.setEnabled(true);
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var EnableNotificationsButton = sdk.getComponent("atoms.EnableNotificationsButton");
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_MatrixToolbar">
|
<div className="mx_MatrixToolbar">
|
||||||
You are not receiving desktop notifications. <EnableNotificationsButton />
|
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="/!\"/>
|
||||||
<div className="mx_MatrixToolbar_close"><img src="img/close-white.png" width="16" height="16" onClick={ this.hideToolbar } /></div>
|
<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>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -17,17 +17,20 @@ limitations under the License.
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
var sdk = require('matrix-react-sdk')
|
||||||
//var RoomDropTargetController = require('matrix-react-sdk/lib/controllers/molecules/RoomDropTargetController')
|
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'RoomDropTarget',
|
displayName: 'NewVersionBar',
|
||||||
// mixins: [RoomDropTargetController],
|
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div className="mx_RoomDropTarget">
|
<div className="mx_MatrixToolbar">
|
||||||
{this.props.text}
|
<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>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -18,26 +18,20 @@ limitations under the License.
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
|
||||||
var TextForEvent = require('matrix-react-sdk/lib/TextForEvent');
|
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'EventAsTextTile',
|
displayName: 'VectorLoginFooter',
|
||||||
|
|
||||||
statics: {
|
statics: {
|
||||||
needsSenderProfile: function() {
|
replaces: 'LoginFooter',
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var text = TextForEvent.textForEvent(this.props.mxEvent);
|
|
||||||
if (text == null || text.length == 0) return null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_EventAsTextTile">
|
<div className="mx_Login_links">
|
||||||
{TextForEvent.textForEvent(this.props.mxEvent)}
|
<a href="https://medium.com/@Vector">blog</a> ·
|
||||||
|
<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>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -19,16 +19,16 @@ limitations under the License.
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'ViewSource',
|
displayName: 'VectorLoginHeader',
|
||||||
|
statics: {
|
||||||
|
replaces: 'LoginHeader',
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div className="mx_ViewSource">
|
<div className="mx_Login_logo">
|
||||||
<pre>
|
<img src="img/logo.png" width="249" height="78" alt="vector"/>
|
||||||
{JSON.stringify(this.props.mxEvent.event, null, 2)}
|
|
||||||
</pre>
|
|
||||||
</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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -17,16 +17,18 @@ limitations under the License.
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
var DateUtils = require('matrix-react-sdk/lib/DateUtils');
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'UnknownMessageTile',
|
displayName: 'MessageTimestamp',
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var content = this.props.mxEvent.getContent();
|
var date = new Date(this.props.ts);
|
||||||
return (
|
return (
|
||||||
<span className="mx_UnknownMessageTile">
|
<span className="mx_MessageTimestamp">
|
||||||
{content.body}
|
{ DateUtils.formatDate(date) }
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -18,19 +18,20 @@ limitations under the License.
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
|
||||||
var MEmoteTileController = require('matrix-react-sdk/lib/controllers/molecules/MEmoteTile')
|
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'MEmoteTile',
|
displayName: 'SenderProfile',
|
||||||
mixins: [MEmoteTileController],
|
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var mxEvent = this.props.mxEvent;
|
var mxEvent = this.props.mxEvent;
|
||||||
var content = mxEvent.getContent();
|
|
||||||
var name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
|
var name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
|
||||||
|
|
||||||
|
var msgtype = mxEvent.getContent().msgtype;
|
||||||
|
if (msgtype && msgtype == 'm.emote') {
|
||||||
|
name = ''; // emote message must include the name so don't duplicate it
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<span ref="content" className="mx_MEmoteTile mx_MessageTile_content">
|
<span className="mx_SenderProfile">
|
||||||
* {name} {content.body}
|
{name} { this.props.aux }
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
},
|
},
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -41,14 +41,14 @@ module.exports = React.createClass({
|
||||||
label = <div className="mx_RoomTile_name">{ this.props.label }</div>;
|
label = <div className="mx_RoomTile_name">{ this.props.label }</div>;
|
||||||
}
|
}
|
||||||
else if (this.state.hover) {
|
else if (this.state.hover) {
|
||||||
var RoomTooltip = sdk.getComponent("molecules.RoomTooltip");
|
var RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
|
||||||
label = <RoomTooltip bottom={ true } label={ this.props.label }/>;
|
label = <RoomTooltip bottom={ true } label={ this.props.label }/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_RoomTile" onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} onClick={this.props.onClick}>
|
<div className="mx_RoomTile" onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} onClick={this.props.onClick}>
|
||||||
<div className="mx_RoomTile_avatar">
|
<div className="mx_RoomTile_avatar">
|
||||||
<img src={ this.props.img } width="36" height="36"/>
|
<img src={ this.props.img } width="26" height="26"/>
|
||||||
</div>
|
</div>
|
||||||
{ label }
|
{ 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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -22,30 +22,18 @@ var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||||
var sdk = require('matrix-react-sdk')
|
var sdk = require('matrix-react-sdk')
|
||||||
var Modal = require('matrix-react-sdk/lib/Modal');
|
var Modal = require('matrix-react-sdk/lib/Modal');
|
||||||
|
var Resend = require("matrix-react-sdk/lib/Resend");
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'MessageContextMenu',
|
displayName: 'MessageContextMenu',
|
||||||
|
|
||||||
onResendClick: function() {
|
onResendClick: function() {
|
||||||
MatrixClientPeg.get().resendEvent(
|
Resend.resend(this.props.mxEvent);
|
||||||
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'});
|
|
||||||
if (this.props.onFinished) this.props.onFinished();
|
if (this.props.onFinished) this.props.onFinished();
|
||||||
},
|
},
|
||||||
|
|
||||||
onViewSourceClick: function() {
|
onViewSourceClick: function() {
|
||||||
var ViewSource = sdk.getComponent('organisms.ViewSource');
|
var ViewSource = sdk.getComponent('structures.ViewSource');
|
||||||
Modal.createDialog(ViewSource, {
|
Modal.createDialog(ViewSource, {
|
||||||
mxEvent: this.props.mxEvent
|
mxEvent: this.props.mxEvent
|
||||||
});
|
});
|
||||||
|
@ -58,7 +46,7 @@ module.exports = React.createClass({
|
||||||
).done(function() {
|
).done(function() {
|
||||||
// message should disappear by itself
|
// message should disappear by itself
|
||||||
}, function(e) {
|
}, function(e) {
|
||||||
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
|
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
// display error message stating you couldn't delete this.
|
// display error message stating you couldn't delete this.
|
||||||
var code = e.errcode || e.statusCode;
|
var code = e.errcode || e.statusCode;
|
||||||
Modal.createDialog(ErrorDialog, {
|
Modal.createDialog(ErrorDialog, {
|
||||||
|
@ -69,25 +57,42 @@ module.exports = React.createClass({
|
||||||
if (this.props.onFinished) this.props.onFinished();
|
if (this.props.onFinished) this.props.onFinished();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onCancelSendClick: function() {
|
||||||
|
Resend.removeFromQueue(this.props.mxEvent);
|
||||||
|
if (this.props.onFinished) this.props.onFinished();
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
var eventStatus = this.props.mxEvent.status;
|
||||||
var resendButton;
|
var resendButton;
|
||||||
var viewSourceButton;
|
var viewSourceButton;
|
||||||
var redactButton;
|
var redactButton;
|
||||||
|
var cancelButton;
|
||||||
|
|
||||||
if (this.props.mxEvent.status == 'not_sent') {
|
if (eventStatus === 'not_sent') {
|
||||||
resendButton = (
|
resendButton = (
|
||||||
<div className="mx_ContextualMenu_field" onClick={this.onResendClick}>
|
<div className="mx_ContextualMenu_field" onClick={this.onResendClick}>
|
||||||
Resend
|
Resend
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
|
if (!eventStatus) { // sent
|
||||||
redactButton = (
|
redactButton = (
|
||||||
<div className="mx_ContextualMenu_field" onClick={this.onRedactClick}>
|
<div className="mx_ContextualMenu_field" onClick={this.onRedactClick}>
|
||||||
Delete
|
Redact
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (eventStatus === "queued" || eventStatus === "not_sent") {
|
||||||
|
cancelButton = (
|
||||||
|
<div className="mx_ContextualMenu_field" onClick={this.onCancelSendClick}>
|
||||||
|
Cancel Sending
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
viewSourceButton = (
|
viewSourceButton = (
|
||||||
<div className="mx_ContextualMenu_field" onClick={this.onViewSourceClick}>
|
<div className="mx_ContextualMenu_field" onClick={this.onViewSourceClick}>
|
||||||
View Source
|
View Source
|
||||||
|
@ -98,6 +103,7 @@ module.exports = React.createClass({
|
||||||
<div>
|
<div>
|
||||||
{resendButton}
|
{resendButton}
|
||||||
{redactButton}
|
{redactButton}
|
||||||
|
{cancelButton}
|
||||||
{viewSourceButton}
|
{viewSourceButton}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
|
@ -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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -18,20 +18,24 @@ limitations under the License.
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
|
||||||
var EnableNotificationsButtonController = require('matrix-react-sdk/lib/controllers/atoms/EnableNotificationsButton')
|
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'EnableNotificationsButton',
|
displayName: 'RoomDropTarget',
|
||||||
mixins: [EnableNotificationsButtonController],
|
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
if (this.enabled()) {
|
if (this.props.placeholder) {
|
||||||
return (
|
return (
|
||||||
<button className="mx_EnableNotificationsButton" onClick={this.onClick}>Disable Notifications</button>
|
<div className="mx_RoomDropTarget mx_RoomDropTarget_placeholder">
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return (
|
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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
var ReactDOM = require('react-dom');
|
||||||
|
|
||||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||||
|
|
||||||
|
@ -24,21 +25,21 @@ module.exports = React.createClass({
|
||||||
displayName: 'RoomTooltip',
|
displayName: 'RoomTooltip',
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
var tooltip = ReactDOM.findDOMNode(this);
|
||||||
if (!this.props.bottom) {
|
if (!this.props.bottom) {
|
||||||
// tell the roomlist about us so it can position us
|
// tell the roomlist about us so it can position us
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'view_tooltip',
|
action: 'view_tooltip',
|
||||||
tooltip: this.getDOMNode(),
|
tooltip: tooltip,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var tooltip = this.getDOMNode();
|
|
||||||
tooltip.style.top = tooltip.parentElement.getBoundingClientRect().top + "px";
|
tooltip.style.top = tooltip.parentElement.getBoundingClientRect().top + "px";
|
||||||
tooltip.style.display = "block";
|
tooltip.style.display = "block";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
if (!this.props.bottom) {
|
if (!this.props.bottom) {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'view_tooltip',
|
action: 'view_tooltip',
|
|
@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -22,8 +22,13 @@ html {
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: 'Lato', Helvetica, Arial, Sans-Serif;
|
/* Open Sans lacks combining diacritics, so these will fall through
|
||||||
font-size: 16px;
|
to the next font. Helevetica's diacritics however do not combine
|
||||||
|
nicely with Open Sans (on OSX, at least) and result in a huge
|
||||||
|
horizontal mess. Arial empirically gets it right, hence prioritising
|
||||||
|
Arial here. */
|
||||||
|
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
|
||||||
|
font-size: 15px;
|
||||||
color: #454545;
|
color: #454545;
|
||||||
border: 0px;
|
border: 0px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
|
@ -34,9 +39,9 @@ div.error {
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
color: #80cef4;
|
color: #454545;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 20px;
|
font-size: 18px;
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
@ -44,7 +49,21 @@ h2 {
|
||||||
a:hover,
|
a:hover,
|
||||||
a:link,
|
a:link,
|
||||||
a:visited {
|
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 {
|
.mx_ContextualMenu_background {
|
||||||
|
@ -58,7 +77,7 @@ a:visited {
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_ContextualMenu {
|
.mx_ContextualMenu {
|
||||||
border: 1px solid #a9dbf4;
|
border: 1px solid #a4a4a4;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
color: #747474;
|
color: #747474;
|
||||||
|
@ -91,19 +110,9 @@ a:visited {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Dialog_background {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: #000;
|
|
||||||
opacity: 0.2;
|
|
||||||
z-index: 2000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_Dialog_wrapper {
|
.mx_Dialog_wrapper {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
z-index: 4000;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -124,18 +133,36 @@ a:visited {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
color: #747474;
|
color: #747474;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
z-index: 2010;
|
z-index: 4010;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-size: 16px;
|
font-size: 15px;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
max-width: 75%;
|
max-width: 80%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_ImageView {
|
.mx_Dialog_background {
|
||||||
margin: 6px;
|
position: fixed;
|
||||||
/* hack: flexbox bug? */
|
top: 0;
|
||||||
margin-bottom: 4px;
|
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 {
|
.mx_Dialog_content {
|
||||||
|
@ -146,26 +173,38 @@ a:visited {
|
||||||
padding-bottom: 24px;
|
padding-bottom: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Dialog button {
|
.mx_Dialog button, .mx_Dialog input[type="submit"] {
|
||||||
border: 0px;
|
border: 0px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
border-radius: 36px;
|
border-radius: 36px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 16px;
|
font-size: 15px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #80cef4;
|
background-color: #76cfa6;
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
padding-left: 1em;
|
padding-left: 1em;
|
||||||
padding-right: 1em;
|
padding-right: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_ErrorDialogTitle,
|
.mx_Dialog_title {
|
||||||
.mx_QuestionDialogTitle {
|
|
||||||
min-height: 16px;
|
min-height: 16px;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
border-bottom: 1px solid #a9dbf4;
|
border-bottom: 1px solid #a4a4a4;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 20px;
|
font-size: 18px;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.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_RoomSettings_encrypt,
|
||||||
.mx_CreateRoom_encrypt,
|
.mx_CreateRoom_encrypt,
|
||||||
.mx_RightPanel_filebutton
|
.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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_CreateRoom {
|
.mx_CreateRoom {
|
||||||
width: 720px;
|
width: 960px;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
color: #4a4a4a;
|
color: #4a4a4a;
|
||||||
|
@ -26,7 +26,7 @@ limitations under the License.
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
border: 1px solid #c7c7c7;
|
border: 1px solid #c7c7c7;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
padding: 9px;
|
padding: 9px;
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -14,6 +14,18 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
.mx_MatrixChat_splash {
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_MatrixChat_splashButtons {
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
.mx_MatrixChat_wrapper {
|
.mx_MatrixChat_wrapper {
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
display: -moz-box;
|
display: -moz-box;
|
||||||
|
@ -35,7 +47,17 @@ limitations under the License.
|
||||||
-webkit-order: 1;
|
-webkit-order: 1;
|
||||||
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 {
|
.mx_MatrixChat_toolbarShowing {
|
||||||
|
@ -69,8 +91,10 @@ limitations under the License.
|
||||||
-webkit-order: 1;
|
-webkit-order: 1;
|
||||||
order: 1;
|
order: 1;
|
||||||
|
|
||||||
-webkit-flex: 0 0 230px;
|
background-color: #eaf5f0;
|
||||||
flex: 0 0 230px;
|
|
||||||
|
-webkit-flex: 0 0 210px;
|
||||||
|
flex: 0 0 210px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MatrixChat .mx_LeftPanel.collapsed {
|
.mx_MatrixChat .mx_LeftPanel.collapsed {
|
||||||
|
@ -85,17 +109,25 @@ limitations under the License.
|
||||||
-webkit-order: 2;
|
-webkit-order: 2;
|
||||||
order: 2;
|
order: 2;
|
||||||
|
|
||||||
padding-left: 12px;
|
padding-left: 25px;
|
||||||
padding-right: 12px;
|
padding-right: 22px;
|
||||||
background-color: #f3f8fa;
|
background-color: #fff;
|
||||||
|
|
||||||
-webkit-flex: 1;
|
-webkit-flex: 1;
|
||||||
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
|
/* XXX: Hack: apparently if you try to nest a flex-box
|
||||||
* within a non-flex-box within a flex-box, the height
|
* within a non-flex-box within a flex-box, the height
|
||||||
* of the innermost element gets miscalculated if the
|
* 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
|
* Ideally we'd launch straight into the RoomView at this
|
||||||
* point, but instead we fudge it and make the middlePanel
|
* point, but instead we fudge it and make the middlePanel
|
||||||
* flex itself.
|
* flex itself.
|
||||||
|
@ -114,9 +146,8 @@ limitations under the License.
|
||||||
-webkit-order: 3;
|
-webkit-order: 3;
|
||||||
order: 3;
|
order: 3;
|
||||||
|
|
||||||
background-color: #f3f8fa;
|
-webkit-flex: 0 0 235px;
|
||||||
-webkit-flex: 0 0 230px;
|
flex: 0 0 235px;
|
||||||
flex: 0 0 230px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MatrixChat .mx_RightPanel.collapsed {
|
.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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -36,15 +36,15 @@ limitations under the License.
|
||||||
-webkit-order: 1;
|
-webkit-order: 1;
|
||||||
order: 1;
|
order: 1;
|
||||||
|
|
||||||
-webkit-flex: 0 0 88px;
|
-webkit-flex: 0 0 83px;
|
||||||
flex: 0 0 88px;
|
flex: 0 0 83px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomView_fileDropTarget {
|
.mx_RoomView_fileDropTarget {
|
||||||
min-width: 0px;
|
min-width: 0px;
|
||||||
max-width: 720px;
|
max-width: 960px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 20px;
|
font-size: 18px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
@ -61,10 +61,10 @@ limitations under the License.
|
||||||
border-top-right-radius: 10px;
|
border-top-right-radius: 10px;
|
||||||
|
|
||||||
background-color: rgba(255, 255, 255, 0.9);
|
background-color: rgba(255, 255, 255, 0.9);
|
||||||
border: 2px dashed #80cef4;
|
border: 2px #e1dddd solid;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 88px;
|
top: 83px;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
z-index: 3000;
|
z-index: 3000;
|
||||||
}
|
}
|
||||||
|
@ -84,23 +84,31 @@ limitations under the License.
|
||||||
order: 2;
|
order: 2;
|
||||||
|
|
||||||
min-width: 0px;
|
min-width: 0px;
|
||||||
max-width: 720px;
|
max-width: 960px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
border-bottom: 1px solid #a8dbf3;
|
border-bottom: 1px solid #eee;
|
||||||
|
|
||||||
-webkit-flex: 0 0 auto;
|
-webkit-flex: 0 0 auto;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomView_messagePanel {
|
.mx_RoomView_topUnreadMessagesBar {
|
||||||
-webkit-box-ordinal-group: 3;
|
-webkit-box-ordinal-group: 3;
|
||||||
-moz-box-ordinal-group: 3;
|
-moz-box-ordinal-group: 3;
|
||||||
-ms-flex-order: 3;
|
-ms-flex-order: 3;
|
||||||
-webkit-order: 3;
|
-webkit-order: 3;
|
||||||
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;
|
-webkit-flex: 1 1 0;
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
|
@ -111,8 +119,22 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomView_messageListWrapper {
|
.mx_RoomView_messageListWrapper {
|
||||||
max-width: 720px;
|
max-width: 960px;
|
||||||
margin: auto;
|
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 {
|
.mx_RoomView_MessageList {
|
||||||
|
@ -129,8 +151,9 @@ limitations under the License.
|
||||||
clear: both;
|
clear: both;
|
||||||
margin-top: 32px;
|
margin-top: 32px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
|
margin-left: 63px;
|
||||||
padding-bottom: 6px;
|
padding-bottom: 6px;
|
||||||
border-bottom: 1px solid #a8dbf3;
|
border-bottom: 1px solid #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomView_invitePrompt {
|
.mx_RoomView_invitePrompt {
|
||||||
|
@ -141,7 +164,7 @@ limitations under the License.
|
||||||
order: 2;
|
order: 2;
|
||||||
|
|
||||||
min-width: 0px;
|
min-width: 0px;
|
||||||
max-width: 720px;
|
max-width: 960px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
|
||||||
|
@ -149,55 +172,22 @@ limitations under the License.
|
||||||
margin-bottom: 12px;
|
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 {
|
.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;
|
-webkit-box-ordinal-group: 5;
|
||||||
-moz-box-ordinal-group: 5;
|
-moz-box-ordinal-group: 5;
|
||||||
-ms-flex-order: 5;
|
-ms-flex-order: 5;
|
||||||
|
@ -205,44 +195,62 @@ limitations under the License.
|
||||||
order: 5;
|
order: 5;
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
-webkit-flex: 0 0 63px;
|
-webkit-flex: 0 0 auto;
|
||||||
flex: 0 0 63px;
|
flex: 0 0 auto;
|
||||||
margin-right: 2px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomView_uploadProgressOuter {
|
.mx_RoomView_statusAreaBox {
|
||||||
width: 100%;
|
max-width: 960px;
|
||||||
background-color: rgba(169, 219, 244, 0.5);
|
margin: auto;
|
||||||
height: 4px;
|
min-height: 36px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomView_uploadProgressInner {
|
.mx_RoomView_statusAreaBox_line {
|
||||||
background-color: #80cef4;
|
border-top: 1px solid #eee;
|
||||||
height: 4px;
|
height: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomView_uploadFilename {
|
.mx_RoomView_inCall .mx_RoomView_statusAreaBox_line {
|
||||||
margin-top: 15px;
|
border-top: 1px hidden;
|
||||||
margin-left: 56px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomView_uploadIcon {
|
.mx_RoomView_inCall .mx_MessageComposer_wrapper {
|
||||||
float: left;
|
border-top: 2px hidden;
|
||||||
margin-top: 6px;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.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;
|
float: right;
|
||||||
margin-top: 6px;
|
margin-right: 13px;
|
||||||
margin-right: 10px;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomView_uploadBytes {
|
.mx_RoomView_voipButton object {
|
||||||
float: right;
|
pointer-events: none;
|
||||||
opacity: 0.5;
|
}
|
||||||
margin-top: 15px;
|
|
||||||
margin-right: 10px;
|
.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 {
|
.mx_RoomView_ongoingConfCallNotification {
|
||||||
|
@ -251,5 +259,5 @@ limitations under the License.
|
||||||
background-color: #ff0064;
|
background-color: #ff0064;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-weight: bold;
|
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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -17,6 +17,18 @@ limitations under the License.
|
||||||
.mx_Login {
|
.mx_Login {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 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 {
|
.mx_Login h2 {
|
||||||
|
@ -28,8 +40,10 @@ limitations under the License.
|
||||||
|
|
||||||
.mx_Login_box {
|
.mx_Login_box {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
|
min-height: 450px;
|
||||||
|
padding-top: 50px;
|
||||||
|
padding-bottom: 50px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
padding-top: 100px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Login_logo {
|
.mx_Login_logo {
|
||||||
|
@ -41,7 +55,7 @@ limitations under the License.
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
border: 1px solid #c7c7c7;
|
border: 1px solid #c7c7c7;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
padding: 9px;
|
padding: 9px;
|
||||||
margin-bottom: 14px;
|
margin-bottom: 14px;
|
||||||
}
|
}
|
||||||
|
@ -54,12 +68,12 @@ limitations under the License.
|
||||||
height: 40px;
|
height: 40px;
|
||||||
border: 0px;
|
border: 0px;
|
||||||
background-color: #76cfa6;
|
background-color: #76cfa6;
|
||||||
font-size: 16px;
|
font-size: 15px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Login_label {
|
.mx_Login_label {
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +85,7 @@ limitations under the License.
|
||||||
display: block;
|
display: block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +97,7 @@ limitations under the License.
|
||||||
display: block;
|
display: block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +105,15 @@ limitations under the License.
|
||||||
color: #4a4a4a;
|
color: #4a4a4a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_Login_forgot {
|
||||||
|
font-size: 13px;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_Login_forgot:link {
|
||||||
|
color: #4a4a4a;
|
||||||
|
}
|
||||||
|
|
||||||
.mx_Login_loader {
|
.mx_Login_loader {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 50%;
|
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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -14,21 +14,21 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_MatrixToolbar {
|
.mx_BaseAvatar {
|
||||||
text-align: center;
|
position: relative;
|
||||||
background-color: #ff0064;
|
}
|
||||||
|
|
||||||
|
.mx_BaseAvatar_initial {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-weight: bold;
|
text-align: center;
|
||||||
padding: 6px;
|
speak: none;
|
||||||
|
pointer-events: none;
|
||||||
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MatrixToolbar button {
|
.mx_BaseAvatar_image {
|
||||||
margin-left: 12px;
|
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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -25,7 +25,7 @@ limitations under the License.
|
||||||
|
|
||||||
.mx_ServerConfig_help:link {
|
.mx_ServerConfig_help:link {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
color: #4a4a4a;
|
color: #4a4a4a;
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -14,7 +14,8 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_MImageTile_thumbnail {
|
.mx_MImageBody_thumbnail {
|
||||||
|
max-width: 100%;
|
||||||
/*
|
/*
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 2px solid #fff;
|
border: 2px solid #fff;
|
||||||
|
@ -22,16 +23,20 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MImageTile_download {
|
.mx_MImageBody_download {
|
||||||
color: #80cef4;
|
color: #76cfa6;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MImageTile_download a {
|
.mx_MImageBody_download a {
|
||||||
color: #80cef4;
|
color: #76cfa6;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MImageTile_download img {
|
.mx_MImageBody_download object {
|
||||||
padding-right: 8px;
|
margin-left: -16px;
|
||||||
}
|
padding-right: 4px;
|
||||||
|
margin-top: -4px;
|
||||||
|
vertical-align: middle;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
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_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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -14,7 +14,6 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_MTextTile {
|
.mx_MTextBody {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
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_TextualEvent {
|
||||||
|
opacity: 0.5;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -15,70 +15,90 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_MessageComposer_wrapper {
|
.mx_MessageComposer_wrapper {
|
||||||
max-width: 720px;
|
max-width: 960px;
|
||||||
height: 50px;
|
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
background-color: #fff;
|
border-top: 2px solid #e1dddd;
|
||||||
border-radius: 25px;
|
|
||||||
border: 1px solid #a9dbf4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MessageComposer_row {
|
.mx_MessageComposer_row {
|
||||||
display: table-row;
|
display: table-row;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 50px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MessageComposer .mx_MessageComposer_avatar {
|
.mx_MessageComposer .mx_MessageComposer_avatar {
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
padding-left: 5px;
|
padding-left: 10px;
|
||||||
padding-right: 10px;
|
padding-right: 28px;
|
||||||
height: 50px;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MessageComposer .mx_MessageComposer_avatar img {
|
.mx_MessageComposer .mx_MessageComposer_avatar .mx_BaseAvatar {
|
||||||
margin-top: 5px;
|
display: block;
|
||||||
border-radius: 20px;
|
|
||||||
background-color: #dbdbdb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MessageComposer_input {
|
.mx_MessageComposer_input {
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
height: 50px;
|
height: 70px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MessageComposer_input textarea {
|
.mx_MessageComposer_input textarea {
|
||||||
|
display: block;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 1.2em;
|
padding: 0px;
|
||||||
padding-top: 0.7em;
|
margin-top: 6px;
|
||||||
padding-bottom: 0.7em;
|
margin-bottom: 6px;
|
||||||
border: 0px;
|
border: 0px;
|
||||||
resize: none;
|
resize: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
-webkit-box-shadow: none;
|
-webkit-box-shadow: none;
|
||||||
-moz-box-shadow: none;
|
-moz-box-shadow: none;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
|
||||||
/* needed for FF */
|
/* 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 */
|
/* hack for FF as vertical alignment of custom placeholder text is broken */
|
||||||
.mx_MessageComposer_input textarea::-moz-placeholder {
|
.mx_MessageComposer_input textarea::-moz-placeholder {
|
||||||
line-height: 100%;
|
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;
|
display: table-cell;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
padding-right: 15px;
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
cursor: pointer;
|
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;
|
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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_MNoticeTile {
|
.mx_PresenceLabel {
|
||||||
|
font-size: 11px;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
|
@ -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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -14,14 +14,22 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_RoomDropTarget {
|
.mx_RoomList {
|
||||||
font-size: 14px;
|
padding-top: 24px;
|
||||||
text-align: center;
|
padding-bottom: 12px;
|
||||||
margin-left: 8px;
|
min-height: 400px;
|
||||||
margin-right: 8px;
|
}
|
||||||
padding-top: 16px;
|
|
||||||
padding-bottom: 16px;
|
.mx_RoomList_expandButton {
|
||||||
background-color: #fbfbfb;
|
margin-left: 8px;
|
||||||
border: 1px dashed #d7d7d7;
|
cursor: pointer;
|
||||||
border-radius: 8px;
|
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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -14,47 +14,43 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_MemberList {
|
.mx_RoomPreviewBar {
|
||||||
height: 100%;
|
text-align: center;
|
||||||
margin-bottom: 100px;
|
height: 176px;
|
||||||
padding: 8px;
|
|
||||||
|
|
||||||
-webkit-flex: 1;
|
-webkit-align-items: center;
|
||||||
flex: 1;
|
align-items: center;
|
||||||
|
|
||||||
|
flex-direction: column;
|
||||||
|
-webkit-flex-direction: column;
|
||||||
|
|
||||||
|
justify-content: center;
|
||||||
|
-webkit-justify-content: center;
|
||||||
|
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
display: -moz-box;
|
display: -moz-box;
|
||||||
display: -ms-flexbox;
|
display: -ms-flexbox;
|
||||||
display: -webkit-flex;
|
display: -webkit-flex;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
flex-direction: column;
|
|
||||||
-webkit-flex-direction: column;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MemberList_chevron {
|
.mx_RoomPreviewBar_wrapper {
|
||||||
position: absolute;
|
|
||||||
right: 35px;
|
|
||||||
margin-top: -15px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MemberList_border {
|
.mx_RoomPreviewBar_invite_text {
|
||||||
border: 1px solid #a9dbf4;
|
color: #454545;
|
||||||
overflow-y: auto;
|
|
||||||
border-radius: 8px;
|
|
||||||
background-color: #fff;
|
|
||||||
|
|
||||||
order: 1;
|
|
||||||
-webkit-flex: 1 1 0;
|
|
||||||
flex: 1 1 0px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MemberList_wrapper {
|
.mx_RoomPreviewBar_join_text {
|
||||||
display: table;
|
color: #ff0064;
|
||||||
table-layout: fixed;
|
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MemberList h2 {
|
.mx_RoomPreviewBar_preview_text {
|
||||||
margin: 14px;
|
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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -16,33 +16,41 @@ limitations under the License.
|
||||||
|
|
||||||
.mx_RoomTile {
|
.mx_RoomTile {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: table-row;
|
/* This fixes wrapping of long room names, but breaks drag & drop previews */
|
||||||
color: #818794;
|
/* display: table-row; */
|
||||||
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomTile_avatar {
|
.mx_RoomTile_avatar {
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
padding-right: 10px;
|
padding-right: 8px;
|
||||||
padding-top: 3px;
|
padding-top: 6px;
|
||||||
padding-bottom: 3px;
|
padding-bottom: 6px;
|
||||||
padding-left: 10px;
|
padding-left: 18px;
|
||||||
vertical-align: middle;
|
width: 24px;
|
||||||
width: 36px;
|
height: 24px;
|
||||||
height: 36px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
vertical-align: middle;
|
||||||
|
|
||||||
.mx_RoomTile_avatar img {
|
|
||||||
border-radius: 20px;
|
|
||||||
background-color: #dbdbdb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomTile_name {
|
.mx_RoomTile_name {
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
|
width: 100%;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
padding-right: 16px;
|
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 {
|
.collapsed .mx_RoomTile_name {
|
||||||
|
@ -63,7 +71,7 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomTile_badge {
|
.mx_RoomTile_badge {
|
||||||
background-color: #80cef4;
|
background-color: #76cfa6;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-radius: 26px;
|
border-radius: 26px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
@ -75,6 +83,7 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
.mx_RoomTile_badge {
|
.mx_RoomTile_badge {
|
||||||
background-color: #ff0064;
|
background-color: #ff0064;
|
||||||
border: 3px solid #fff;
|
border: 3px solid #fff;
|
||||||
|
@ -85,20 +94,48 @@ limitations under the License.
|
||||||
right: 9px;
|
right: 9px;
|
||||||
bottom: 3px;
|
bottom: 3px;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
.mx_RoomTile_unread,
|
.mx_RoomTile_badge {
|
||||||
.mx_RoomTile_highlight,
|
background-color: #ff0064;
|
||||||
.mx_RoomTile_invited
|
width: 4px;
|
||||||
{
|
position: absolute;
|
||||||
font-weight: bold;
|
left: 0px;
|
||||||
color: #000;
|
top: 5px;
|
||||||
|
bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomTile_unreadNotify .mx_RoomTile_badge {
|
||||||
|
background-color: #454545;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomTile_selected {
|
.mx_RoomTile_highlight .mx_RoomTile_badge {
|
||||||
background-color: #f3f8fa;
|
background-color: #ff0064;
|
||||||
color: #80cef4;
|
}
|
||||||
|
|
||||||
|
.mx_RoomTile_unread,
|
||||||
|
.mx_RoomTile_highlight {
|
||||||
font-weight: bold;
|
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 {
|
.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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -16,14 +16,15 @@ limitations under the License.
|
||||||
|
|
||||||
.mx_IncomingCallBox {
|
.mx_IncomingCallBox {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: 1px solid #a9dbf4;
|
border: 1px solid #a4a4a4;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
position: absolute;
|
position: fixed;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
left: 235px;
|
|
||||||
top: 155px;
|
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
|
margin-top: -3px;
|
||||||
|
margin-left: -20px;
|
||||||
|
width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_IncomingCallBox_chevron {
|
.mx_IncomingCallBox_chevron {
|
||||||
|
@ -39,14 +40,15 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_IncomingCallBox_buttons {
|
.mx_IncomingCallBox_buttons {
|
||||||
display: table-row;
|
display: flex;
|
||||||
|
display: -webkit-flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_IncomingCallBox_buttons_cell {
|
.mx_IncomingCallBox_buttons_cell {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
display: table-cell;
|
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
width: 50%;
|
flex: 1;
|
||||||
|
-webkit-flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_IncomingCallBox_buttons_decline,
|
.mx_IncomingCallBox_buttons_decline,
|
||||||
|
@ -57,6 +59,7 @@ limitations under the License.
|
||||||
line-height: 36px;
|
line-height: 36px;
|
||||||
border-radius: 36px;
|
border-radius: 36px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_IncomingCallBox_buttons_decline {
|
.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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -31,9 +31,15 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_VideoView_localVideoFeed {
|
.mx_VideoView_localVideoFeed {
|
||||||
width: 20%;
|
width: 25%;
|
||||||
|
height: 25%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 16px;
|
left: 10px;
|
||||||
bottom: 28px;
|
bottom: 10px;
|
||||||
z-index: 100;
|
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,20 +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_SenderProfile_zalgo {
|
|
||||||
font-family: Helvetica, Arial, Sans-Serif;
|
|
||||||
display: table-row ! important;
|
|
||||||
}
|
|
|
@ -1,21 +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_UserSettings {
|
|
||||||
width: 720px;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
|
@ -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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -34,16 +34,21 @@ limitations under the License.
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel .mx_RoomList {
|
.mx_LeftPanel_callView {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_LeftPanel .mx_RoomList_scrollbar {
|
||||||
-webkit-box-ordinal-group: 1;
|
-webkit-box-ordinal-group: 1;
|
||||||
-moz-box-ordinal-group: 1;
|
-moz-box-ordinal-group: 1;
|
||||||
-ms-flex-order: 1;
|
-ms-flex-order: 1;
|
||||||
-webkit-order: 1;
|
-webkit-order: 1;
|
||||||
order: 1;
|
order: 1;
|
||||||
|
|
||||||
overflow-y: auto;
|
|
||||||
-webkit-flex: 1 1 0;
|
-webkit-flex: 1 1 0;
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
|
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu {
|
.mx_LeftPanel .mx_BottomLeftMenu {
|
||||||
|
@ -53,17 +58,23 @@ limitations under the License.
|
||||||
-webkit-order: 3;
|
-webkit-order: 3;
|
||||||
order: 3;
|
order: 3;
|
||||||
|
|
||||||
-webkit-flex: 0 0 170px;
|
-webkit-flex: 0 0 140px;
|
||||||
flex: 0 0 170px;
|
flex: 0 0 140px;
|
||||||
|
|
||||||
border-top: 1px solid #f3f8fa;
|
background-color: rgba(118,207,166,0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu .mx_RoomTile {
|
.mx_LeftPanel .mx_BottomLeftMenu .mx_RoomTile {
|
||||||
color: #378bb4;
|
color: #454545;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu .mx_BottomLeftMenu_options {
|
.mx_LeftPanel .mx_BottomLeftMenu .mx_BottomLeftMenu_options {
|
||||||
margin-top: 12px;
|
margin-top: 15px;
|
||||||
width: 100%;
|
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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -33,32 +33,57 @@ limitations under the License.
|
||||||
-webkit-order: 1;
|
-webkit-order: 1;
|
||||||
order: 1;
|
order: 1;
|
||||||
|
|
||||||
-webkit-flex: 0 0 66px;
|
-webkit-flex: 0 0 83px;
|
||||||
flex: 0 0 66px;
|
flex: 0 0 83px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Fixme - factor this out with the main header **/
|
/** Fixme - factor this out with the main header **/
|
||||||
|
|
||||||
.mx_RightPanel_headerButtonGroup {
|
.mx_RightPanel_headerButtonGroup {
|
||||||
margin-top: 18px;
|
margin-top: 32px;
|
||||||
height: 48px;
|
float: left;
|
||||||
float: right;
|
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-radius: 48px;
|
margin-left: -4px;
|
||||||
border: 1px solid #a9dbf4;
|
|
||||||
margin-right: 22px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RightPanel_headerButton {
|
.mx_RightPanel_headerButton {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 48px;
|
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
padding-left: 8px;
|
padding-left: 15px;
|
||||||
padding-right: 8px;
|
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;
|
-webkit-box-ordinal-group: 2;
|
||||||
-moz-box-ordinal-group: 2;
|
-moz-box-ordinal-group: 2;
|
||||||
-ms-flex-order: 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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -15,7 +15,8 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_RoomDirectory {
|
.mx_RoomDirectory {
|
||||||
width: 720px;
|
max-width: 960px;
|
||||||
|
width: 100%;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
|
@ -50,7 +51,7 @@ limitations under the License.
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
border: 1px solid #c7c7c7;
|
border: 1px solid #c7c7c7;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
padding: 9px;
|
padding: 9px;
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
|
@ -63,37 +64,61 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomDirectory_table {
|
.mx_RoomDirectory_table {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #4a4a4a;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
table-layout: fixed;
|
table-layout: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomDirectory_table th {
|
.mx_RoomDirectory_roomAvatar {
|
||||||
font-weight: 400;
|
width: 24px;
|
||||||
font-size: 12px;
|
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;
|
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;
|
|
||||||
}
|
|
|
@ -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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -14,9 +14,9 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_MemberAvatar {
|
.mx_ViewSource pre {
|
||||||
z-index: 20;
|
text-align: left;
|
||||||
border-radius: 20px;
|
font-size: 12px;
|
||||||
background-color: #dbdbdb;
|
padding: 0.5em 1em 0.5em 1em;
|
||||||
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -14,18 +14,19 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_RoomList {
|
.mx_Spinner {
|
||||||
}
|
display: -webkit-flex;
|
||||||
|
display: flex;
|
||||||
.mx_RoomList_recents {
|
-webkit-align-items: center;
|
||||||
margin-top: -12px;
|
-webkit-justify-content: center;
|
||||||
display: table;
|
align-items: center;
|
||||||
table-layout: fixed;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
flex: 1;
|
||||||
|
-webkit-flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomList h2 {
|
.mx_MatrixChat_middlePanel .mx_Spinner {
|
||||||
padding-left: 16px;
|
height: auto;
|
||||||
padding-right: 16px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
}
|
|
@ -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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -13,4 +13,3 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -17,11 +17,10 @@ limitations under the License.
|
||||||
.mx_RoomTooltip {
|
.mx_RoomTooltip {
|
||||||
display: none;
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
border: 1px solid #a9dbf4;
|
border: 1px solid #a4a4a4;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
margin-top: 6px;
|
|
||||||
left: 64px;
|
left: 64px;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue