Compare commits
278 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d77fab18f | ||
|
|
3650c3f08b | ||
|
|
5512fd4220 | ||
|
|
678393e2bd | ||
|
|
25d8a7999f | ||
|
|
014f7ade86 | ||
|
|
2b671fcafc | ||
|
|
df5b243e75 | ||
|
|
5e43f2752a | ||
|
|
0cb14ba5ec | ||
|
|
d65477891e | ||
|
|
bb1854814c | ||
|
|
9e15bda803 | ||
|
|
e7ac66ad04 | ||
|
|
4a0a911f3b | ||
|
|
7286aeb013 | ||
|
|
244265d52b | ||
|
|
ab93e96a1f | ||
|
|
5a17d8b450 | ||
|
|
43e3662e60 | ||
|
|
19d5063814 | ||
|
|
da7a556629 | ||
|
|
c2cb4dff4c | ||
|
|
dd6868c255 | ||
|
|
b411a2e489 | ||
|
|
28343aaa33 | ||
|
|
3f615c6664 | ||
|
|
804b17fbf1 | ||
|
|
9798e14733 | ||
|
|
b742342062 | ||
|
|
f8fa19ed47 | ||
|
|
fe4bb3e413 | ||
|
|
ff13782ab5 | ||
|
|
b1dd7efed8 | ||
|
|
699a58e0b3 | ||
|
|
6a19655886 | ||
|
|
afc889ff4d | ||
|
|
b06c9f037e | ||
|
|
1c812b340d | ||
|
|
bd9f5d3e06 | ||
|
|
cf8164bcc3 | ||
|
|
33612b7076 | ||
|
|
5a97786cc6 | ||
|
|
ee2329d236 | ||
|
|
66f80b2239 | ||
|
|
62ebeb9fd8 | ||
|
|
72ba708bfe | ||
|
|
d0d7f2d2d2 | ||
|
|
b3459be707 | ||
|
|
d1e22d50f0 | ||
|
|
bf46c3cfab | ||
|
|
7880734d77 | ||
|
|
5ce1aba493 | ||
|
|
c929076a83 | ||
|
|
99625067fe | ||
|
|
c9ab977d73 | ||
|
|
b99e7598f9 | ||
|
|
b9e06bcf66 | ||
|
|
eb108c7866 | ||
|
|
a190862ed3 | ||
|
|
34a31a71fd | ||
|
|
7774756ed1 | ||
|
|
ee9f78d156 | ||
|
|
70754db27a | ||
|
|
16f8143f3e | ||
|
|
be1f014294 | ||
|
|
f53f9af1c5 | ||
|
|
58b1d62976 | ||
|
|
8e0f7f18a0 | ||
|
|
75ea62f351 | ||
|
|
ee8572559f | ||
|
|
f640be90ad | ||
|
|
472acd4792 | ||
|
|
8087e99808 | ||
|
|
51b74251f9 | ||
|
|
8c7aede0cc | ||
|
|
2829d95705 | ||
|
|
28057fd086 | ||
|
|
2e3ad3206c | ||
|
|
4f94cf5dfb | ||
|
|
51e8c28ab6 | ||
|
|
0f73228d55 | ||
|
|
d21e4fb86a | ||
|
|
645db7fa2f | ||
|
|
0d4f35bed1 | ||
|
|
2123fec8ed | ||
|
|
3860488bb5 | ||
|
|
ef5ea46830 | ||
|
|
d4faacf462 | ||
|
|
4a7d2901ac | ||
|
|
f382946138 | ||
|
|
bb93a59cfb | ||
|
|
0ad84fd7b0 | ||
|
|
87bddcd8ce | ||
|
|
18701a2dae | ||
|
|
2f65064688 | ||
|
|
2f08f2441f | ||
|
|
6c4c0bf57a | ||
|
|
55a10ee275 | ||
|
|
49545ce0c2 | ||
|
|
b87058508e | ||
|
|
fd53f10fbd | ||
|
|
6329e274ab | ||
|
|
b5fdaac947 | ||
|
|
22bf74dc65 | ||
|
|
d376df478a | ||
|
|
53f4da1d30 | ||
|
|
e34db7b8c6 | ||
|
|
074bbc7149 | ||
|
|
4b33164ab6 | ||
|
|
dab707a893 | ||
|
|
5cf164fcc1 | ||
|
|
37a7ce809a | ||
|
|
15f9f5dbe8 | ||
|
|
187818aaa0 | ||
|
|
30b1e7078f | ||
|
|
791980cd1f | ||
|
|
6c19504c8b | ||
|
|
497ebce88a | ||
|
|
2768cd2010 | ||
|
|
204e42494a | ||
|
|
72b4a86eed | ||
|
|
ce5311191f | ||
|
|
7eff6d968e | ||
|
|
d01e2506f5 | ||
|
|
53fe372a0c | ||
|
|
4cb04d1e40 | ||
|
|
24e021b91f | ||
|
|
e988f5ca3b | ||
|
|
633a3f4867 | ||
|
|
df163d8cb7 | ||
|
|
73bb317925 | ||
|
|
ad74d264a3 | ||
|
|
e9db975d7d | ||
|
|
0958a6bb62 | ||
|
|
f3586a79c2 | ||
|
|
882d09bf85 | ||
|
|
25eb2e2daf | ||
|
|
d8d9912f2d | ||
|
|
8a28da1986 | ||
|
|
384425582a | ||
|
|
b87b356722 | ||
|
|
6ae0dda9d3 | ||
|
|
6c680ff424 | ||
|
|
c6b455f470 | ||
|
|
f6d7052928 | ||
|
|
2ee1a9c440 | ||
|
|
8fd12d530d | ||
|
|
3f7bd48c0a | ||
|
|
28108476bd | ||
|
|
722cedc92e | ||
|
|
f182e32e3d | ||
|
|
3cfcc13387 | ||
|
|
953bb64e0b | ||
|
|
54f4443428 | ||
|
|
a039450d10 | ||
|
|
1e963a6c3a | ||
|
|
80ad45df06 | ||
|
|
348f133e77 | ||
|
|
cd865bbe8f | ||
|
|
e668d7685d | ||
|
|
6607bee91a | ||
|
|
3a89a5af0b | ||
|
|
35e3621ae7 | ||
|
|
040ef73886 | ||
|
|
74c9ac0872 | ||
|
|
adbad509f4 | ||
|
|
15a97a653f | ||
|
|
9fb97a6b10 | ||
|
|
579f210cfc | ||
|
|
2fb1e156ed | ||
|
|
707ddc61bf | ||
|
|
09e861637f | ||
|
|
1f43f904d5 | ||
|
|
446f74b3dd | ||
|
|
d2391f999e | ||
|
|
e1779ca8bc | ||
|
|
65371c9a39 | ||
|
|
a4dc844338 | ||
|
|
0a4af647c8 | ||
|
|
503bf541c7 | ||
|
|
1fbc249de5 | ||
|
|
959dcd0c49 | ||
|
|
ef4f2f10d9 | ||
|
|
19dbd85d44 | ||
|
|
ef4b604caf | ||
|
|
74f459f8a4 | ||
|
|
fef81748bb | ||
|
|
3e53879adc | ||
|
|
145e61b00f | ||
|
|
49dd93ffab | ||
|
|
7174879ac9 | ||
|
|
486adb717b | ||
|
|
773f592c3f | ||
|
|
2ca9d87b95 | ||
|
|
4bc4292ceb | ||
|
|
cbb72c2f29 | ||
|
|
5f477b313b | ||
|
|
d45e44d01c | ||
|
|
c12839dc7b | ||
|
|
c35c9f7c3a | ||
|
|
ff5c7072d7 | ||
|
|
eca453ee5a | ||
|
|
ad2541299f | ||
|
|
dc840fdf48 | ||
|
|
510bb5785e | ||
|
|
9556795611 | ||
|
|
4c6fa740f3 | ||
|
|
f4a3e9a39b | ||
|
|
bb820bebd1 | ||
|
|
664f809362 | ||
|
|
034c045b37 | ||
|
|
4dfb0e9a90 | ||
|
|
654429dbdb | ||
|
|
c7d0214aaa | ||
|
|
607923b58f | ||
|
|
895fb63d5d | ||
|
|
b172018d08 | ||
|
|
95a0bc92d6 | ||
|
|
a90492e393 | ||
|
|
ec7067e7bd | ||
|
|
42b7410a5d | ||
|
|
4cfcdfa040 | ||
|
|
795986f146 | ||
|
|
d38c338f89 | ||
|
|
a373849b5b | ||
|
|
8cd4637316 | ||
|
|
0635a6f562 | ||
|
|
a8cee87c08 | ||
|
|
a7598ea815 | ||
|
|
22cef7a6a0 | ||
|
|
e507339324 | ||
|
|
b643d8ff6a | ||
|
|
3547bd8d00 | ||
|
|
ab1f37b0bb | ||
|
|
eb37032d8a | ||
|
|
f6ed21559a | ||
|
|
a5986ade51 | ||
|
|
d7504aeda5 | ||
|
|
b2459b2dc6 | ||
|
|
819e06e2cd | ||
|
|
b7f1a3db57 | ||
|
|
a030e46c69 | ||
|
|
f61cfbc542 | ||
|
|
c4b7571c45 | ||
|
|
4dd477e064 | ||
|
|
f595f6f141 | ||
|
|
24602119c5 | ||
|
|
3040d0a474 | ||
|
|
e4ea00ca23 | ||
|
|
4fc311da90 | ||
|
|
7894e52529 | ||
|
|
7999a70cab | ||
|
|
f6aa9a7ea4 | ||
|
|
b3ae9cc9d4 | ||
|
|
5f29729e82 | ||
|
|
e24851456a | ||
|
|
1e40fd750f | ||
|
|
ed1554f4af | ||
|
|
c6cf5febd5 | ||
|
|
f9aaf7d903 | ||
|
|
a2e73cceee | ||
|
|
c672919d1e | ||
|
|
7ab2449ac1 | ||
|
|
e68a2b5e1d | ||
|
|
ddc4ac187c | ||
|
|
ded66bbdfc | ||
|
|
1a11c402fa | ||
|
|
4ec77eeca7 | ||
|
|
635fd927cd | ||
|
|
481a7b160d | ||
|
|
cadedd2919 | ||
|
|
7e563b89c7 | ||
|
|
6a6118e136 | ||
|
|
a288c5b85d | ||
|
|
c4d408d095 | ||
|
|
ac24d6707f | ||
|
|
e5835d2731 |
5
.gitignore
vendored
@@ -1,5 +1,4 @@
|
||||
/cert.pem
|
||||
/.DS_Store
|
||||
/karma-reports
|
||||
/key.pem
|
||||
/lib
|
||||
@@ -7,3 +6,7 @@
|
||||
/packages/
|
||||
/vector/bundle.*
|
||||
/vector/components.css
|
||||
/vector/emojione/
|
||||
/vector/config.json
|
||||
/vector/olm.js
|
||||
.DS_Store
|
||||
|
||||
137
CHANGELOG.md
@@ -1,3 +1,140 @@
|
||||
Changes in [0.7.4-r1](https://github.com/vector-im/vector-web/releases/tag/v0.7.4-r1) (2016-08-12)
|
||||
==================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.4...v0.7.4-r1)
|
||||
* Update to matrix-react-sdk 0.6.4-r1 to fix inviting multiple people
|
||||
|
||||
|
||||
Changes in [0.7.4](https://github.com/vector-im/vector-web/releases/tag/v0.7.4) (2016-08-11)
|
||||
============================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.3...v0.7.4)
|
||||
|
||||
* Don't show border on composer when not in RTE mode
|
||||
[\#1954](https://github.com/vector-im/vector-web/pull/1954)
|
||||
* Wmwragg/room tag menu
|
||||
[\#1941](https://github.com/vector-im/vector-web/pull/1941)
|
||||
* Don't redirect to mobile app if verifying 3pid
|
||||
[\#1951](https://github.com/vector-im/vector-web/pull/1951)
|
||||
* Make sure that we clear localstorage before *all* tests
|
||||
[\#1950](https://github.com/vector-im/vector-web/pull/1950)
|
||||
* Basic CSS for multi-invite dialog
|
||||
[\#1942](https://github.com/vector-im/vector-web/pull/1942)
|
||||
* More tests for the loading process:
|
||||
[\#1947](https://github.com/vector-im/vector-web/pull/1947)
|
||||
* Support for refactored login token handling
|
||||
[\#1946](https://github.com/vector-im/vector-web/pull/1946)
|
||||
* Various fixes and improvements to emojification.
|
||||
[\#1935](https://github.com/vector-im/vector-web/pull/1935)
|
||||
* More app-loading tests
|
||||
[\#1938](https://github.com/vector-im/vector-web/pull/1938)
|
||||
* Some tests of the application load process
|
||||
[\#1936](https://github.com/vector-im/vector-web/pull/1936)
|
||||
* Add 'enable labs' setting to sample config
|
||||
[\#1930](https://github.com/vector-im/vector-web/pull/1930)
|
||||
* Matthew/scalar
|
||||
[\#1928](https://github.com/vector-im/vector-web/pull/1928)
|
||||
* Fix unit tests
|
||||
[\#1929](https://github.com/vector-im/vector-web/pull/1929)
|
||||
* Wmwragg/mute mention state fix
|
||||
[\#1926](https://github.com/vector-im/vector-web/pull/1926)
|
||||
* CSS for deactivate account dialog
|
||||
[\#1919](https://github.com/vector-im/vector-web/pull/1919)
|
||||
* Wmwragg/mention state menu
|
||||
[\#1900](https://github.com/vector-im/vector-web/pull/1900)
|
||||
* Fix UnknownBody styling for #1901
|
||||
[\#1913](https://github.com/vector-im/vector-web/pull/1913)
|
||||
* Exclude olm from the webpack
|
||||
[\#1914](https://github.com/vector-im/vector-web/pull/1914)
|
||||
* Wmwragg/button updates
|
||||
[\#1912](https://github.com/vector-im/vector-web/pull/1912)
|
||||
* Wmwragg/button updates
|
||||
[\#1828](https://github.com/vector-im/vector-web/pull/1828)
|
||||
* CSS for device management UI
|
||||
[\#1909](https://github.com/vector-im/vector-web/pull/1909)
|
||||
* Fix a warning from RoomSubList
|
||||
[\#1908](https://github.com/vector-im/vector-web/pull/1908)
|
||||
* Fix notifications warning layout
|
||||
[\#1907](https://github.com/vector-im/vector-web/pull/1907)
|
||||
* Remove relayoutOnUpdate prop on gemini-scrollbar
|
||||
[\#1883](https://github.com/vector-im/vector-web/pull/1883)
|
||||
* Bump dependency versions
|
||||
[\#1842](https://github.com/vector-im/vector-web/pull/1842)
|
||||
* Wmwragg/mention state indicator round 2
|
||||
[\#1835](https://github.com/vector-im/vector-web/pull/1835)
|
||||
* Wmwragg/spinner fix
|
||||
[\#1822](https://github.com/vector-im/vector-web/pull/1822)
|
||||
* Wmwragg/mention state indicator
|
||||
[\#1823](https://github.com/vector-im/vector-web/pull/1823)
|
||||
* Revert "Presentation for inline link"
|
||||
[\#1809](https://github.com/vector-im/vector-web/pull/1809)
|
||||
* Wmwragg/modal restyle
|
||||
[\#1806](https://github.com/vector-im/vector-web/pull/1806)
|
||||
* Presentation for inline link
|
||||
[\#1799](https://github.com/vector-im/vector-web/pull/1799)
|
||||
* CSS for offline user colours
|
||||
[\#1798](https://github.com/vector-im/vector-web/pull/1798)
|
||||
* Wmwragg/typography updates
|
||||
[\#1776](https://github.com/vector-im/vector-web/pull/1776)
|
||||
* webpack: always use the olm from vector-web
|
||||
[\#1766](https://github.com/vector-im/vector-web/pull/1766)
|
||||
* feat: large emoji support
|
||||
[\#1718](https://github.com/vector-im/vector-web/pull/1718)
|
||||
* Autocomplete
|
||||
[\#1717](https://github.com/vector-im/vector-web/pull/1717)
|
||||
* #1664 Set a maximum height for codeblocks
|
||||
[\#1670](https://github.com/vector-im/vector-web/pull/1670)
|
||||
* CSS for device blocking
|
||||
[\#1688](https://github.com/vector-im/vector-web/pull/1688)
|
||||
* Fix joining rooms by typing the alias
|
||||
[\#1685](https://github.com/vector-im/vector-web/pull/1685)
|
||||
* Add ability to delete an alias from room directory
|
||||
[\#1680](https://github.com/vector-im/vector-web/pull/1680)
|
||||
* package.json: add olm as optionalDependency
|
||||
[\#1678](https://github.com/vector-im/vector-web/pull/1678)
|
||||
* Another go at enabling olm on vector.im/develop
|
||||
[\#1675](https://github.com/vector-im/vector-web/pull/1675)
|
||||
* CSS for unverify button
|
||||
[\#1661](https://github.com/vector-im/vector-web/pull/1661)
|
||||
* CSS fix for rooms with crypto enabled
|
||||
[\#1660](https://github.com/vector-im/vector-web/pull/1660)
|
||||
* Karma: fix warning by ignoring olm
|
||||
[\#1652](https://github.com/vector-im/vector-web/pull/1652)
|
||||
* Update for react-sdk dbkr/fix_peeking branch
|
||||
[\#1639](https://github.com/vector-im/vector-web/pull/1639)
|
||||
* Update README.md
|
||||
[\#1641](https://github.com/vector-im/vector-web/pull/1641)
|
||||
* Fix karma tests
|
||||
[\#1643](https://github.com/vector-im/vector-web/pull/1643)
|
||||
* Rich Text Editor
|
||||
[\#1553](https://github.com/vector-im/vector-web/pull/1553)
|
||||
* Fix RoomDirectory to join by alias whenever possible.
|
||||
[\#1615](https://github.com/vector-im/vector-web/pull/1615)
|
||||
* Make the config optional
|
||||
[\#1612](https://github.com/vector-im/vector-web/pull/1612)
|
||||
* CSS support for device verification
|
||||
[\#1610](https://github.com/vector-im/vector-web/pull/1610)
|
||||
* Don't use SdkConfig
|
||||
[\#1609](https://github.com/vector-im/vector-web/pull/1609)
|
||||
* serve config.json statically instead of bundling it
|
||||
[\#1516](https://github.com/vector-im/vector-web/pull/1516)
|
||||
|
||||
Changes in [0.7.3](https://github.com/vector-im/vector-web/releases/tag/v0.7.3) (2016-06-03)
|
||||
============================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.2...v0.7.3)
|
||||
|
||||
* Update to react-sdk 0.6.3
|
||||
|
||||
Changes in [0.7.2](https://github.com/vector-im/vector-web/releases/tag/v0.7.2) (2016-06-02)
|
||||
============================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.1...v0.7.2)
|
||||
|
||||
* Correctly bump the dep on new matrix-js-sdk and matrix-react-sdk
|
||||
|
||||
Changes in [0.7.1](https://github.com/vector-im/vector-web/releases/tag/v0.7.1) (2016-06-02)
|
||||
============================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.0...v0.7.1)
|
||||
|
||||
* Fix accidentally committed local changes to the default config.json (doh!)
|
||||
|
||||
Changes in [0.7.0](https://github.com/vector-im/vector-web/releases/tag/v0.7.0) (2016-06-02)
|
||||
============================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.6.1...v0.7.0)
|
||||
|
||||
174
README.md
@@ -3,63 +3,122 @@ Vector/Web
|
||||
|
||||
Vector is a Matrix web client built using the Matrix React SDK (https://github.com/matrix-org/matrix-react-sdk).
|
||||
|
||||
Getting started
|
||||
Getting Started
|
||||
===============
|
||||
|
||||
The easiest way to test Vector is to just use the hosted copy at https://vector.im/beta.
|
||||
The develop branch is continuously deployed by Jenkins at https://vector.im/develop for
|
||||
those who like living dangerously.
|
||||
|
||||
To host your own copy of Vector, the quickest bet is to use a pre-built released version
|
||||
of Vector:
|
||||
|
||||
1. Download the latest version from https://vector.im/packages/
|
||||
1. Untar the tarball on your web server
|
||||
1. Move (or symlink) the vector-x.x.x directory to an appropriate name
|
||||
1. If desired, copy `config.sample.json` to `config.json` and edit it
|
||||
as desired. See below for details.
|
||||
1. Enter the URL into your browser and log into vector!
|
||||
|
||||
Building From Source
|
||||
====================
|
||||
|
||||
Vector is a modular webapp built with modern ES6 and requires a npm build system to build.
|
||||
|
||||
1. Install or update `node.js` so that your `npm` is at least at version `2.0.0`
|
||||
1. 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`
|
||||
1. Switch to the vector directory: `cd vector-web`
|
||||
1. Install the prerequisites: `npm install`
|
||||
1. If you are using the `develop` branch of vector, you will probably need to
|
||||
rebuild one of the dependencies, due to https://github.com/npm/npm/issues/3055:
|
||||
`(cd node_modules/matrix-react-sdk && npm install)`
|
||||
1. Start the development builder and a testing server: `npm start`
|
||||
1. Wait a few seconds for the initial build to finish (the command won't
|
||||
terminate: it's running a web server for you).
|
||||
1. Open http://127.0.0.1:8080/ in your browser to see your newly built Vector.
|
||||
1. Configure the app by copying `config.sample.json` to `config.json` and modifying
|
||||
it (see below for details)
|
||||
1. `npm run package` to build a tarball to deploy. Untaring this file will give
|
||||
a version-specific directory containing all the files that need to go on your
|
||||
web server.
|
||||
|
||||
With `npm start`, any changes you make to the source files will cause a rebuild so
|
||||
your changes will show up when you refresh. This development server also disables
|
||||
caching, so do NOT use it in production.
|
||||
Note that `npm run package` is not supported on Windows, so Windows users can run `npm
|
||||
run build`, which will build all the necessary files into the `vector`
|
||||
directory. The version of Vector will not appear in Settings without
|
||||
using the package script. You can then mount the vector directory on your
|
||||
webserver to actually serve up the app, which is entirely static content.
|
||||
|
||||
Configuring
|
||||
config.json
|
||||
===========
|
||||
|
||||
Configure the app by modifying the `config.json` file:
|
||||
You can configure the app by copying `vector/config.sample.json` to
|
||||
`vector/config.json` and customising it:
|
||||
|
||||
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.
|
||||
registering with an email address, adding an email address to your account,
|
||||
or inviting users via email address will not work. Matrix identity servers are
|
||||
very simple web services which map third party identifiers (currently only email
|
||||
addresses) to matrix IDs: see http://matrix.org/docs/spec/identity_service/unstable.html
|
||||
for more details. Currently the only public matrix identity servers are https://matrix.org
|
||||
and https://vector.im. In future identity servers will be decentralised.
|
||||
|
||||
You will need to re-run `npm run build` after editing `config.json`.
|
||||
|
||||
Deployment
|
||||
==========
|
||||
Running as a Desktop app
|
||||
========================
|
||||
|
||||
On a Unix-based OS, run `npm run package` to build a tarball package. Untaring
|
||||
this file will give a version-specific directory containing all the files that
|
||||
need to go on your web server.
|
||||
In future we'll do an official distribution of Vector as an desktop app. Meanwhile,
|
||||
there are a few options:
|
||||
|
||||
@asdf:matrix.org points out that you can use nativefier and it just works(tm):
|
||||
|
||||
```
|
||||
sudo npm install nativefier -g
|
||||
nativefier https://vector.im/beta/
|
||||
```
|
||||
|
||||
krisa has a dedicated electron project at https://github.com/krisak/vector-electron-desktop
|
||||
(although you should swap out the 'vector' folder for the latest vector tarball you want to run)
|
||||
|
||||
There's also a (much) older electron distribution at https://github.com/stevenhammerton/vector-desktop
|
||||
|
||||
The package script is not supported on Windows, so Windows users can run `npm
|
||||
run build`, which will build all the necessary files into the `vector`
|
||||
directory. Note that the version of Vector will not appear in Settings without
|
||||
using the package script. You can then mount the vector directory on your
|
||||
webserver to actually serve up the app, which is entirely static content.
|
||||
|
||||
Development
|
||||
===========
|
||||
|
||||
For simple tweaks, you can work on any of the source files within Vector with
|
||||
the setup above, and your changes will cause an instant rebuild.
|
||||
Before attempting to develop on Vector you **must** read the developer guide
|
||||
for `matrix-react-sdk` at https://github.com/matrix-org/matrix-react-sdk, which
|
||||
also defines the design, architecture and style for Vector too.
|
||||
|
||||
However, much of the functionality in Vector is actually in the
|
||||
`matrix-react-sdk` and `matrix-js-sdk` modules. It is possible to set these up
|
||||
in a way that makes it easy to track the `develop` branches in git and to make
|
||||
local changes without having to manually rebuild each time.
|
||||
The idea of Vector is to be a relatively lightweight "skin" of customisations on
|
||||
top of the underlying `matrix-react-sdk`. `matrix-react-sdk` provides both the
|
||||
higher and lower level React components useful for building Matrix communication
|
||||
apps using React.
|
||||
|
||||
[Be aware that there may be problems with this process under npm version 3.]
|
||||
After creating a new component you must run `npm run reskindex` to regenerate
|
||||
the `component-index.js` for the app (used in future for skinning)
|
||||
|
||||
**However, as of July 2016 this layering abstraction is broken due to rapid
|
||||
development on Vector forcing `matrix-react-sdk` to move fast at the expense of
|
||||
maintaining a clear abstraction between the two.** Hacking on Vector inevitably
|
||||
means hacking equally on `matrix-react-sdk`, and there are bits of
|
||||
`matrix-react-sdk` behaviour incorrectly residing in the `vector-web` project
|
||||
(e.g. matrix-react-sdk specific CSS), and a bunch of Vector specific behaviour
|
||||
in the `matrix-react-sdk` (grep for Vector). This separation problem will be
|
||||
solved asap once development on Vector (and thus matrix-react-sdk) has
|
||||
stabilised. Until then, the two projects should basically be considered as a
|
||||
single unit. In particular, `matrix-react-sdk` issues are currently filed
|
||||
against `vector-web` in github.
|
||||
|
||||
Please note that Vector is intended to run correctly without access to the public
|
||||
internet. So please don't depend on resources (JS libs, CSS, images, fonts)
|
||||
hosted by external CDNs or servers but instead please package all dependencies
|
||||
into Vector itself.
|
||||
|
||||
Setting up a dev environment
|
||||
============================
|
||||
|
||||
Much of the functionality in Vector is actually in the `matrix-react-sdk` and
|
||||
`matrix-js-sdk` modules. It is possible to set these up in a way that makes it
|
||||
easy to track the `develop` branches in git and to make local changes without
|
||||
having to manually rebuild each time.
|
||||
|
||||
First clone and build `matrix-js-sdk`:
|
||||
|
||||
@@ -102,17 +161,53 @@ Finally, build and start vector itself:
|
||||
+ 1013 hidden modules
|
||||
```
|
||||
Remember, the command will not terminate since it runs the web server
|
||||
and rebuilds source files when they change.
|
||||
and rebuilds source files when they change. This development server also
|
||||
disables caching, so do NOT use it in production.
|
||||
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.
|
||||
When you make changes to `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 the directory, to start a development builder which
|
||||
will watch for changes to the files and rebuild automatically.
|
||||
|
||||
If you add or remove any components from the Vector skin, you will need to rebuild
|
||||
the skin's index by running, `npm run reskindex`.
|
||||
|
||||
If any of these steps error with, `file table overflow`, you are probably on a mac
|
||||
which has a very low limit on max open files. Run `ulimit -Sn 1024` and try again.
|
||||
You'll need to do this in each new terminal you open before building vector.
|
||||
|
||||
Filing issues
|
||||
=============
|
||||
|
||||
All issues for Vector-web and Matrix-react-sdk should be filed at
|
||||
https://github.com/matrix-org/matrix-react-sdk/issues
|
||||
|
||||
Triaging issues
|
||||
===============
|
||||
|
||||
Issues will be triaged by the core team using the following primary set of tags:
|
||||
|
||||
priority:
|
||||
P1: top priority; typically blocks releases.
|
||||
P2: one below that
|
||||
P3: non-urgent
|
||||
P4/P5: bluesky some day, who knows.
|
||||
|
||||
bug or feature:
|
||||
bug severity:
|
||||
* cosmetic - feature works functionally but UI/UX is broken.
|
||||
* critical - whole app doesn't work
|
||||
* major - entire feature doesn't work
|
||||
* minor - partially broken feature (but still usable)
|
||||
|
||||
* release blocker
|
||||
|
||||
* ui/ux (think of this as cosmetic)
|
||||
|
||||
* network (specific to network conditions)
|
||||
* platform (platform specific)
|
||||
|
||||
Enabling encryption
|
||||
===================
|
||||
|
||||
@@ -121,10 +216,7 @@ 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.
|
||||
|
||||
To build a version of vector with support for end-to-end encryption, install
|
||||
the olm module with `npm i https://matrix.org/packages/npm/olm/olm-0.1.0.tgz`
|
||||
before running `npm start`. The olm library will be detected and used if
|
||||
available.
|
||||
Vector is built with support for end-to-end encryption by default.
|
||||
|
||||
To enable encryption for a room, type
|
||||
|
||||
@@ -140,4 +232,4 @@ 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.
|
||||
room.
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"default_hs_url": "http://127.0.0.1:8008",
|
||||
"default_is_url": "https://vector.im",
|
||||
"brand": "Vector",
|
||||
"integrations_ui_url": "http://localhost:5051/",
|
||||
"integrations_rest_url": "http://localhost:5050"
|
||||
}
|
||||
@@ -27,6 +27,7 @@ module.exports = function (config) {
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
'node_modules/babel-polyfill/browser.js',
|
||||
testFile,
|
||||
{pattern: 'vector/img/*', watched: false, included: false, served: true, nocache: false},
|
||||
],
|
||||
@@ -35,7 +36,7 @@ module.exports = function (config) {
|
||||
proxies: {
|
||||
"/img/": "/base/vector/img/",
|
||||
},
|
||||
|
||||
|
||||
// preprocess matching files before serving them to the browser
|
||||
// available preprocessors:
|
||||
// https://npmjs.org/browse/keyword/karma-preprocessor
|
||||
@@ -122,7 +123,7 @@ module.exports = function (config) {
|
||||
|
||||
// same goes for js-sdk
|
||||
"matrix-js-sdk": path.resolve('./node_modules/matrix-js-sdk'),
|
||||
|
||||
|
||||
sinon: 'sinon/pkg/sinon.js',
|
||||
},
|
||||
root: [
|
||||
@@ -130,6 +131,11 @@ module.exports = function (config) {
|
||||
path.resolve('./test'),
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
// olm may not be installed, so avoid webpack warnings by
|
||||
// ignoring it.
|
||||
new webpack.IgnorePlugin(/^olm$/),
|
||||
],
|
||||
devtool: 'inline-source-map',
|
||||
},
|
||||
});
|
||||
|
||||
37
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vector-web",
|
||||
"version": "0.7.0",
|
||||
"version": "0.7.4-r1",
|
||||
"description": "Vector webapp",
|
||||
"author": "matrix.org",
|
||||
"repository": {
|
||||
@@ -12,44 +12,49 @@
|
||||
"matrix-react-parent": "matrix-react-sdk",
|
||||
"scripts": {
|
||||
"reskindex": "reskindex -h src/header",
|
||||
"build:emojione": "cpx \"node_modules/emojione/assets/svg/*\" vector/emojione/svg/",
|
||||
"build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js",
|
||||
"build:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css --no-watch",
|
||||
"build:compile": "babel --source-maps -d lib src",
|
||||
"build:bundle": "NODE_ENV=production webpack -p lib/vector/index.js vector/bundle.js",
|
||||
"build:bundle:dev": "NODE_ENV=production webpack --optimize-occurence-order lib/vector/index.js vector/bundle.js",
|
||||
"build": "npm run build:css && npm run build:compile && npm run build:bundle",
|
||||
"build:dev": "npm run build:css && npm run build:compile && npm run build:bundle:dev",
|
||||
"build:staticfiles": "scripts/staticfiles.js",
|
||||
"build": "npm run build:staticfiles && npm run build:emojione && npm run build:css && npm run build:compile && npm run build:bundle",
|
||||
"build:dev": "npm run build:staticfiles && npm run build:emojione && npm run build:css && npm run build:compile && npm run build:bundle:dev",
|
||||
"package": "scripts/package.sh",
|
||||
"start:emojione": "cpx \"node_modules/emojione/assets/svg/*\" vector/emojione/svg/ -w",
|
||||
"start:js": "webpack -w src/vector/index.js vector/bundle.js",
|
||||
"start:js:prod": "NODE_ENV=production webpack -w src/vector/index.js vector/bundle.js",
|
||||
"start:skins:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css",
|
||||
"//cache": "Note the -c 1 below due to https://code.google.com/p/chromium/issues/detail?id=508270",
|
||||
"start": "parallelshell \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
|
||||
"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*",
|
||||
"start": "parallelshell \"npm run build:staticfiles\" \"npm run start:emojione\" \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
|
||||
"start:prod": "parallelshell \"npm run build:staticfiles\" \"npm run start:emojione\" \"npm run start:js:prod\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
|
||||
"clean": "rimraf lib vector/olm.js vector/bundle.css vector/bundle.js vector/bundle.js.map vector/webpack.css* vector/emojione",
|
||||
"prepublish": "npm run build:css && npm run build:compile",
|
||||
"test": "karma start --single-run=true --autoWatch=false --browsers PhantomJS --colors=false",
|
||||
"test:multi": "karma start"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-polyfill": "^6.5.0",
|
||||
"browser-request": "^0.3.3",
|
||||
"classnames": "^2.1.2",
|
||||
"draft-js": "^0.7.0",
|
||||
"extract-text-webpack-plugin": "^0.9.1",
|
||||
"filesize": "^3.1.2",
|
||||
"flux": "~2.0.3",
|
||||
"gemini-scrollbar": "matrix-org/gemini-scrollbar#87ebaa7",
|
||||
"gemini-scrollbar": "matrix-org/gemini-scrollbar#b302279",
|
||||
"gfm.css": "^1.1.1",
|
||||
"highlight.js": "^9.0.0",
|
||||
"linkifyjs": "^2.0.0-beta.4",
|
||||
"matrix-js-sdk": "^0.5.3",
|
||||
"matrix-react-sdk": "^0.6.0",
|
||||
"matrix-js-sdk": "0.5.5",
|
||||
"matrix-react-sdk": "0.6.4-r1",
|
||||
"modernizr": "^3.1.0",
|
||||
"q": "^1.4.1",
|
||||
"react": "^15.0.1",
|
||||
"react": "^15.2.1",
|
||||
"react-dnd": "^2.1.4",
|
||||
"react-dnd-html5-backend": "^2.1.2",
|
||||
"react-dom": "^15.0.1",
|
||||
"react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#c3d942e",
|
||||
"react-dom": "^15.2.1",
|
||||
"react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef",
|
||||
"sanitize-html": "^1.11.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -57,8 +62,11 @@
|
||||
"babel-core": "^5.8.25",
|
||||
"babel-loader": "^5.3.2",
|
||||
"catw": "^1.0.1",
|
||||
"cpx": "^1.3.2",
|
||||
"css-raw-loader": "^0.1.1",
|
||||
"emojione": "^2.2.3",
|
||||
"expect": "^1.16.0",
|
||||
"fs-extra": "^0.30.0",
|
||||
"http-server": "^0.8.4",
|
||||
"json-loader": "^0.5.3",
|
||||
"karma": "^0.13.22",
|
||||
@@ -72,10 +80,13 @@
|
||||
"mocha": "^2.4.5",
|
||||
"parallelshell": "^1.2.0",
|
||||
"phantomjs-prebuilt": "^2.1.7",
|
||||
"react-addons-test-utils": "^15.0.1",
|
||||
"react-addons-perf": "^15.0",
|
||||
"react-addons-test-utils": "^15.0.1",
|
||||
"rimraf": "^2.4.3",
|
||||
"source-map-loader": "^0.1.5",
|
||||
"webpack": "^1.12.14"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"olm": "https://matrix.org/packages/npm/olm/olm-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
|
||||
21
scripts/staticfiles.js
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// copy static files from node_modules to the vector directory
|
||||
//
|
||||
|
||||
var fs = require('fs-extra');
|
||||
|
||||
function exists(f) {
|
||||
try {
|
||||
fs.statSync(f);
|
||||
return true;
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const olm = 'node_modules/olm/olm.js';
|
||||
if (exists(olm)) {
|
||||
console.log("copy", olm, "-> vector");
|
||||
fs.copySync(olm, 'vector/olm.js');
|
||||
}
|
||||
@@ -34,6 +34,9 @@ module.exports.components['structures.RoomDirectory'] = require('./components/st
|
||||
module.exports.components['structures.RoomSubList'] = require('./components/structures/RoomSubList');
|
||||
module.exports.components['structures.SearchBox'] = require('./components/structures/SearchBox');
|
||||
module.exports.components['structures.ViewSource'] = require('./components/structures/ViewSource');
|
||||
module.exports.components['views.context_menus.MessageContextMenu'] = require('./components/views/context_menus/MessageContextMenu');
|
||||
module.exports.components['views.context_menus.NotificationStateContextMenu'] = require('./components/views/context_menus/NotificationStateContextMenu');
|
||||
module.exports.components['views.context_menus.RoomTagContextMenu'] = require('./components/views/context_menus/RoomTagContextMenu');
|
||||
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');
|
||||
@@ -44,11 +47,10 @@ module.exports.components['views.login.VectorLoginFooter'] = require('./componen
|
||||
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.IntegrationsManager'] = require('./components/views/settings/IntegrationsManager');
|
||||
module.exports.components['views.settings.Notifications'] = require('./components/views/settings/Notifications');
|
||||
|
||||
@@ -52,13 +52,13 @@ module.exports = React.createClass({
|
||||
<div className="mx_BottomLeftMenu">
|
||||
<div className="mx_BottomLeftMenu_options">
|
||||
<div className="mx_BottomLeftMenu_createRoom" title="Start chat" onClick={ this.onCreateRoomClick }>
|
||||
<TintableSvg src="img/icons-create-room.svg" width="24" height="24"/>
|
||||
<TintableSvg src="img/icons-create-room.svg" width="25" height="25"/>
|
||||
</div>
|
||||
<div className="mx_BottomLeftMenu_directory" title="Room directory" onClick={ this.onRoomDirectoryClick }>
|
||||
<TintableSvg src="img/icons-directory.svg" width="24" height="24"/>
|
||||
<TintableSvg src="img/icons-directory.svg" width="25" height="25"/>
|
||||
</div>
|
||||
<div className="mx_BottomLeftMenu_settings" title="Settings" onClick={ this.onSettingsClick }>
|
||||
<TintableSvg src="img/icons-settings.svg" width="24" height="24"/>
|
||||
<TintableSvg src="img/icons-settings.svg" width="25" height="25"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -45,8 +45,8 @@ module.exports = React.createClass({
|
||||
available or experimental in your current browser.
|
||||
</p>
|
||||
<p>
|
||||
Please install <a href="https://www.google.com/chrome">Chrome</a> for
|
||||
the best experience. <a href="https://getfirefox.com">Firefox</a>,
|
||||
Please install <a href="https://www.google.com/chrome">Chrome</a> or
|
||||
<a href="https://getfirefox.com">Firefox</a> for the best experience.
|
||||
<a href="http://apple.com/safari">Safari</a> and
|
||||
<a href="http://opera.com">Opera</a> work too.
|
||||
</p>
|
||||
|
||||
@@ -136,8 +136,8 @@ module.exports = React.createClass({
|
||||
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 }
|
||||
<TintableSvg src="img/icons-people.svg" width="25" height="25"/>
|
||||
{ membersHighlight }
|
||||
</div>
|
||||
<div className="mx_RightPanel_headerButton mx_RightPanel_filebutton" title="Files">
|
||||
|
||||
@@ -21,7 +21,7 @@ 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 sdk = require('matrix-react-sdk');
|
||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||
var GeminiScrollbar = require('react-gemini-scrollbar');
|
||||
|
||||
@@ -52,6 +52,18 @@ module.exports = React.createClass({
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.getPublicRooms();
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
// dis.dispatch({
|
||||
// action: 'ui_opacity',
|
||||
// sideOpacity: 1.0,
|
||||
// middleOpacity: 1.0,
|
||||
// });
|
||||
},
|
||||
|
||||
getPublicRooms: function() {
|
||||
var self = this;
|
||||
MatrixClientPeg.get().publicRooms(function (err, data) {
|
||||
if (err) {
|
||||
@@ -68,33 +80,79 @@ module.exports = React.createClass({
|
||||
publicRooms: data.chunk,
|
||||
loading: false,
|
||||
});
|
||||
self.forceUpdate();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
// dis.dispatch({
|
||||
// action: 'ui_opacity',
|
||||
// sideOpacity: 1.0,
|
||||
// middleOpacity: 1.0,
|
||||
// });
|
||||
/**
|
||||
* A limited interface for removing rooms from the directory.
|
||||
* Will set the room to not be publicly visible and delete the
|
||||
* default alias. In the long term, it would be better to allow
|
||||
* HS admins to do this through the RoomSettings interface, but
|
||||
* this needs SPEC-417.
|
||||
*/
|
||||
removeFromDirectory: function(room) {
|
||||
var alias = get_display_alias_for_room(room);
|
||||
var name = room.name || alias || "Unnamed room";
|
||||
|
||||
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
|
||||
var desc;
|
||||
if (alias) {
|
||||
desc = `Delete the room alias '${alias}' and remove '${name}' from the directory?`;
|
||||
} else {
|
||||
desc = `Remove '${name}' from the directory?`;
|
||||
}
|
||||
|
||||
Modal.createDialog(QuestionDialog, {
|
||||
title: "Remove from Directory",
|
||||
description: desc,
|
||||
onFinished: (should_delete) => {
|
||||
if (!should_delete) return;
|
||||
|
||||
var Loader = sdk.getComponent("elements.Spinner");
|
||||
var modal = Modal.createDialog(Loader);
|
||||
var step = `remove '${name}' from the directory.`;
|
||||
|
||||
MatrixClientPeg.get().setRoomDirectoryVisibility(room.room_id, 'private').then(() => {
|
||||
if (!alias) return;
|
||||
step = 'delete the alias.';
|
||||
return MatrixClientPeg.get().deleteAlias(alias);
|
||||
}).done(() => {
|
||||
modal.close();
|
||||
this.getPublicRooms();
|
||||
}, function(err) {
|
||||
modal.close();
|
||||
this.getPublicRooms();
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to "+step,
|
||||
description: err.toString()
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
showRoom: function(roomId) {
|
||||
// extract the metadata from the publicRooms structure to pass
|
||||
// as out-of-band data to view_room, because we get information
|
||||
// here that we can't get other than by joining the room in some
|
||||
// cases.
|
||||
var room;
|
||||
for (var i = 0; i < this.state.publicRooms.length; ++i) {
|
||||
if (this.state.publicRooms[i].room_id == roomId) {
|
||||
room = this.state.publicRooms[i];
|
||||
break;
|
||||
}
|
||||
onRoomClicked: function(room, ev) {
|
||||
if (ev.shiftKey) {
|
||||
ev.preventDefault();
|
||||
this.removeFromDirectory(room);
|
||||
} else {
|
||||
this.showRoom(room);
|
||||
}
|
||||
var oob_data = {};
|
||||
},
|
||||
|
||||
showRoomAlias: function(alias) {
|
||||
this.showRoom(null, alias);
|
||||
},
|
||||
|
||||
showRoom: function(room, room_alias) {
|
||||
var payload = {action: 'view_room'};
|
||||
if (room) {
|
||||
// Don't let the user view a room they won't be able to either
|
||||
// peek or join: fail earlier so they don't have to click back
|
||||
// to the directory.
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
if (!room.world_readable && !room.guest_can_join) {
|
||||
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||
@@ -106,19 +164,27 @@ module.exports = React.createClass({
|
||||
}
|
||||
}
|
||||
|
||||
oob_data = {
|
||||
if (!room_alias) {
|
||||
room_alias = get_display_alias_for_room(room);
|
||||
}
|
||||
|
||||
payload.oob_data = {
|
||||
avatarUrl: room.avatar_url,
|
||||
// XXX: This logic is duplicated from the JS SDK which
|
||||
// would normally decide what the name is.
|
||||
name: room.name || room.canonical_alias || (room.aliases ? room.aliases[0] : "Unnamed room"),
|
||||
name: room.name || room_alias || "Unnamed room",
|
||||
};
|
||||
}
|
||||
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: roomId,
|
||||
oob_data: oob_data,
|
||||
});
|
||||
// It's not really possible to join Matrix rooms by ID because the HS has no way to know
|
||||
// which servers to start querying. However, there's no other way to join rooms in
|
||||
// this list without aliases at present, so if roomAlias isn't set here we have no
|
||||
// choice but to supply the ID.
|
||||
if (room_alias) {
|
||||
payload.room_alias = room_alias;
|
||||
} else {
|
||||
payload.room_id = room.room_id;
|
||||
}
|
||||
dis.dispatch(payload);
|
||||
},
|
||||
|
||||
getRows: function(filter) {
|
||||
@@ -139,8 +205,7 @@ module.exports = React.createClass({
|
||||
var self = this;
|
||||
var guestRead, guestJoin, perms;
|
||||
for (var i = 0; i < rooms.length; i++) {
|
||||
var alias = rooms[i].canonical_alias || (rooms[i].aliases ? rooms[i].aliases[0] : "");
|
||||
var name = rooms[i].name || alias || "Unnamed room";
|
||||
var name = rooms[i].name || get_display_alias_for_room(rooms[i]) || "Unnamed room";
|
||||
guestRead = null;
|
||||
guestJoin = null;
|
||||
|
||||
@@ -164,7 +229,11 @@ module.exports = React.createClass({
|
||||
topic = linkifyString(sanitizeHtml(topic));
|
||||
|
||||
rows.unshift(
|
||||
<tr key={ rooms[i].room_id } onClick={self.showRoom.bind(null, rooms[i].room_id)}>
|
||||
<tr key={ rooms[i].room_id }
|
||||
onClick={self.onRoomClicked.bind(self, rooms[i])}
|
||||
// cancel onMouseDown otherwise shift-clicking highlights text
|
||||
onMouseDown={(ev) => {ev.preventDefault();}}
|
||||
>
|
||||
<td className="mx_RoomDirectory_roomAvatar">
|
||||
<BaseAvatar width={24} height={24} resizeMethod='crop'
|
||||
name={ name } idName={ name }
|
||||
@@ -178,7 +247,7 @@ module.exports = React.createClass({
|
||||
<div className="mx_RoomDirectory_topic"
|
||||
onClick={ function(e) { e.stopPropagation() } }
|
||||
dangerouslySetInnerHTML={{ __html: topic }}/>
|
||||
<div className="mx_RoomDirectory_alias">{ alias }</div>
|
||||
<div className="mx_RoomDirectory_alias">{ get_display_alias_for_room(rooms[i]) }</div>
|
||||
</td>
|
||||
<td className="mx_RoomDirectory_roomMemberCount">
|
||||
{ rooms[i].num_joined_members }
|
||||
@@ -193,7 +262,7 @@ module.exports = React.createClass({
|
||||
this.forceUpdate();
|
||||
this.setState({ roomAlias : this.refs.roomAlias.value })
|
||||
if (ev.key == "Enter") {
|
||||
this.showRoom(this.refs.roomAlias.value);
|
||||
this.showRoomAlias(this.refs.roomAlias.value);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -213,8 +282,7 @@ module.exports = React.createClass({
|
||||
<SimpleRoomHeader title="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"
|
||||
relayoutOnUpdate={false} >
|
||||
<GeminiScrollbar className="mx_RoomDirectory_tableWrapper">
|
||||
<table ref="directory_table" className="mx_RoomDirectory_table">
|
||||
<tbody>
|
||||
{ this.getRows(this.state.roomAlias) }
|
||||
@@ -226,3 +294,9 @@ module.exports = React.createClass({
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Similar to matrix-react-sdk's MatrixTools.getDisplayAliasForRoom
|
||||
// but works with the objects we get from the public room list
|
||||
function get_display_alias_for_room(room) {
|
||||
return room.canonical_alias || (room.aliases ? room.aliases[0] : "");
|
||||
}
|
||||
|
||||
@@ -61,8 +61,12 @@ var RoomSubList = React.createClass({
|
||||
label: React.PropTypes.string.isRequired,
|
||||
tagName: React.PropTypes.string,
|
||||
editable: React.PropTypes.bool,
|
||||
|
||||
order: React.PropTypes.string.isRequired,
|
||||
selectedRoom: React.PropTypes.string.isRequired,
|
||||
|
||||
// undefined if no room is selected (eg we are showing settings)
|
||||
selectedRoom: React.PropTypes.string,
|
||||
|
||||
startAsHidden: React.PropTypes.bool,
|
||||
showSpinner: React.PropTypes.bool, // true to show a spinner if 0 elements when expanded
|
||||
collapsed: React.PropTypes.bool.isRequired, // is LeftPanel collapsed?
|
||||
@@ -145,11 +149,26 @@ var RoomSubList = React.createClass({
|
||||
return this.tsOfNewestEvent(roomB) - this.tsOfNewestEvent(roomA);
|
||||
},
|
||||
|
||||
lexicographicalComparator: function(roomA, roomB) {
|
||||
return roomA.name > roomB.name ? 1 : -1;
|
||||
},
|
||||
|
||||
// Generates the manual comparator using the given list
|
||||
manualComparator: function(roomA, roomB) {
|
||||
if (!roomA.tags[this.props.tagName] || !roomB.tags[this.props.tagName]) return 0;
|
||||
|
||||
// Make sure the room tag has an order element, if not set it to be the bottom
|
||||
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);
|
||||
|
||||
// Order undefined room tag orders to the bottom
|
||||
if (a === undefined && b !== undefined) {
|
||||
return 1;
|
||||
} else if (a !== undefined && b === undefined) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return a == b ? this.lexicographicalComparator(roomA, roomB) : ( a > b ? 1 : -1);
|
||||
},
|
||||
|
||||
sortList: function(list, order) {
|
||||
@@ -160,6 +179,9 @@ var RoomSubList = React.createClass({
|
||||
if (order === "manual") comparator = this.manualComparator;
|
||||
if (order === "recent") comparator = this.recentsComparator;
|
||||
|
||||
// Fix undefined orders here, and make sure the backend gets updated as well
|
||||
this._fixUndefinedOrder(list);
|
||||
|
||||
//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) });
|
||||
},
|
||||
@@ -308,6 +330,46 @@ var RoomSubList = React.createClass({
|
||||
this.props.onShowMoreRooms();
|
||||
},
|
||||
|
||||
// Fix any undefined order elements of a room in a manual ordered list
|
||||
// room.tag[tagname].order
|
||||
_fixUndefinedOrder: function(list) {
|
||||
if (this.props.order === "manual") {
|
||||
var order = 0.0;
|
||||
var self = this;
|
||||
|
||||
// Find the highest (lowest position) order of a room in a manual ordered list
|
||||
list.forEach(function(room) {
|
||||
if (room.tags.hasOwnProperty(self.props.tagName)) {
|
||||
if (order < room.tags[self.props.tagName].order) {
|
||||
order = room.tags[self.props.tagName].order;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Fix any undefined order elements of a room in a manual ordered list
|
||||
// Do this one at a time, as each time a rooms tag data is updated the RoomList
|
||||
// gets triggered and another list is passed in. Doing it one at a time means that
|
||||
// we always correctly calculate the highest order for the list - stops multiple
|
||||
// rooms getting the same order. This is only really relevant for the first time this
|
||||
// is run with historical room tag data, after that there should only be undefined
|
||||
// in the list at a time anyway.
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
if (list[i].tags[self.props.tagName].order === undefined) {
|
||||
MatrixClientPeg.get().setRoomTag(list[i].roomId, self.props.tagName, {order: (order + 1.0) / 2.0}).finally(function() {
|
||||
// Do any final stuff here
|
||||
}).fail(function(err) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to add tag " + self.props.tagName + " to room",
|
||||
description: err.toString()
|
||||
});
|
||||
});
|
||||
break;
|
||||
};
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var connectDropTarget = this.props.connectDropTarget;
|
||||
var RoomDropTarget = sdk.getComponent('rooms.RoomDropTarget');
|
||||
|
||||
@@ -94,7 +94,7 @@ module.exports = React.createClass({
|
||||
<TintableSvg
|
||||
key="button"
|
||||
className="mx_SearchBox_searchButton"
|
||||
src="img/right_search.svg" width="24" height="24"
|
||||
src="img/icons-search-copy.svg" width="13" height="13"
|
||||
/>,
|
||||
<input
|
||||
key="searchfield"
|
||||
@@ -103,7 +103,7 @@ module.exports = React.createClass({
|
||||
className="mx_SearchBox_search"
|
||||
value={ this.state.searchTerm }
|
||||
onChange={ this.onChange }
|
||||
placeholder="Search room names"
|
||||
placeholder="Filter room names"
|
||||
/>
|
||||
];
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ module.exports = React.createClass({
|
||||
var ViewSource = sdk.getComponent('structures.ViewSource');
|
||||
Modal.createDialog(ViewSource, {
|
||||
mxEvent: this.props.mxEvent
|
||||
});
|
||||
}, 'mx_Dialog_viewsource');
|
||||
if (this.props.onFinished) this.props.onFinished();
|
||||
},
|
||||
|
||||
@@ -95,7 +95,7 @@ module.exports = React.createClass({
|
||||
|
||||
if (eventStatus === 'not_sent') {
|
||||
resendButton = (
|
||||
<div className="mx_ContextualMenu_field" onClick={this.onResendClick}>
|
||||
<div className="mx_MessageContextMenu_field" onClick={this.onResendClick}>
|
||||
Resend
|
||||
</div>
|
||||
);
|
||||
@@ -103,7 +103,7 @@ module.exports = React.createClass({
|
||||
|
||||
if (!eventStatus) { // sent
|
||||
redactButton = (
|
||||
<div className="mx_ContextualMenu_field" onClick={this.onRedactClick}>
|
||||
<div className="mx_MessageContextMenu_field" onClick={this.onRedactClick}>
|
||||
Redact
|
||||
</div>
|
||||
);
|
||||
@@ -111,14 +111,14 @@ module.exports = React.createClass({
|
||||
|
||||
if (eventStatus === "queued" || eventStatus === "not_sent") {
|
||||
cancelButton = (
|
||||
<div className="mx_ContextualMenu_field" onClick={this.onCancelSendClick}>
|
||||
<div className="mx_MessageContextMenu_field" onClick={this.onCancelSendClick}>
|
||||
Cancel Sending
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
viewSourceButton = (
|
||||
<div className="mx_ContextualMenu_field" onClick={this.onViewSourceClick}>
|
||||
<div className="mx_MessageContextMenu_field" onClick={this.onViewSourceClick}>
|
||||
View Source
|
||||
</div>
|
||||
);
|
||||
@@ -126,7 +126,7 @@ module.exports = React.createClass({
|
||||
if (this.props.eventTileOps) {
|
||||
if (this.props.eventTileOps.isWidgetHidden()) {
|
||||
unhidePreviewButton = (
|
||||
<div className="mx_ContextualMenu_field" onClick={this.onUnhidePreviewClick}>
|
||||
<div className="mx_MessageContextMenu_field" onClick={this.onUnhidePreviewClick}>
|
||||
Unhide Preview
|
||||
</div>
|
||||
)
|
||||
@@ -136,7 +136,7 @@ module.exports = React.createClass({
|
||||
// XXX: this should be https://matrix.to.
|
||||
// XXX: if we use room ID, we should also include a server where the event can be found (other than in the domain of the event ID)
|
||||
permalinkButton = (
|
||||
<div className="mx_ContextualMenu_field">
|
||||
<div className="mx_MessageContextMenu_field">
|
||||
<a href={ "#/room/" + this.props.mxEvent.getRoomId() +"/"+ this.props.mxEvent.getId() }
|
||||
onClick={ this.onPermalinkClick }>Permalink</a>
|
||||
</div>
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var q = require("q");
|
||||
var React = require('react');
|
||||
var classNames = require('classnames');
|
||||
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'NotificationStateContextMenu',
|
||||
|
||||
propTypes: {
|
||||
room: React.PropTypes.object.isRequired,
|
||||
/* callback called when the menu is dismissed */
|
||||
onFinished: React.PropTypes.func,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
var areNotifsMuted = false;
|
||||
var cli = MatrixClientPeg.get();
|
||||
if (!cli.isGuest()) {
|
||||
var roomPushRule = cli.getRoomPushRule("global", this.props.room.roomId);
|
||||
if (roomPushRule) {
|
||||
if (0 <= roomPushRule.actions.indexOf("dont_notify")) {
|
||||
areNotifsMuted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
areNotifsMuted: areNotifsMuted,
|
||||
};
|
||||
},
|
||||
|
||||
_save: function( areNotifsMuted ) {
|
||||
var self = this;
|
||||
const roomId = this.props.room.roomId;
|
||||
var cli = MatrixClientPeg.get();
|
||||
|
||||
if (!cli.isGuest()) {
|
||||
// Wrapping this in a q promise, as setRoomMutePushRule can return
|
||||
// a promise or a value
|
||||
q(cli.setRoomMutePushRule("global", roomId, areNotifsMuted))
|
||||
.then(function() {
|
||||
self.setState({areNotifsMuted: areNotifsMuted});
|
||||
|
||||
// delay slightly so that the user can see their state change
|
||||
// before closing the menu
|
||||
return q.delay(500).then(function() {
|
||||
// tell everyone that wants to know of the change in
|
||||
// notification state
|
||||
dis.dispatch({
|
||||
action: 'notification_change',
|
||||
roomId: self.props.room.roomId,
|
||||
areNotifsMuted: areNotifsMuted,
|
||||
});
|
||||
|
||||
// Close the context menu
|
||||
if (self.props.onFinished) {
|
||||
self.props.onFinished();
|
||||
};
|
||||
});
|
||||
}).fail(function(error) {
|
||||
// TODO: some form of error notification to the user
|
||||
// to inform them that their state change failed.
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_onClickAlertMe: function() {
|
||||
// Placeholder
|
||||
},
|
||||
|
||||
_onClickAllNotifs: function() {
|
||||
this._save(false);
|
||||
},
|
||||
|
||||
_onClickMentions: function() {
|
||||
this._save(true);
|
||||
},
|
||||
|
||||
_onClickMute: function() {
|
||||
// Placeholder
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var cli = MatrixClientPeg.get();
|
||||
|
||||
var alertMeClasses = classNames({
|
||||
'mx_NotificationStateContextMenu_field': true,
|
||||
'mx_NotificationStateContextMenu_fieldDisabled': true,
|
||||
});
|
||||
|
||||
var allNotifsClasses = classNames({
|
||||
'mx_NotificationStateContextMenu_field': true,
|
||||
'mx_NotificationStateContextMenu_fieldSet': !this.state.areNotifsMuted,
|
||||
});
|
||||
|
||||
var mentionsClasses = classNames({
|
||||
'mx_NotificationStateContextMenu_field': true,
|
||||
'mx_NotificationStateContextMenu_fieldSet': this.state.areNotifsMuted,
|
||||
});
|
||||
|
||||
var muteNotifsClasses = classNames({
|
||||
'mx_NotificationStateContextMenu_field': true,
|
||||
'mx_NotificationStateContextMenu_fieldDisabled': true,
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="mx_NotificationStateContextMenu_picker" >
|
||||
<img src="img/notif-slider.svg" width="20" height="107" />
|
||||
</div>
|
||||
<div className={ alertMeClasses } onClick={this._onClickAlertMe} >
|
||||
<img className="mx_NotificationStateContextMenu_activeIcon" src="img/notif-active.svg" width="12" height="12" />
|
||||
<img className="mx_NotificationStateContextMenu_icon" src="img/icon-context-mute-off-copy.svg" width="16" height="12" />
|
||||
All messages (loud)
|
||||
</div>
|
||||
<div className={ allNotifsClasses } onClick={this._onClickAllNotifs} >
|
||||
<img className="mx_NotificationStateContextMenu_activeIcon" src="img/notif-active.svg" width="12" height="12" />
|
||||
<img className="mx_NotificationStateContextMenu_icon" src="img/icon-context-mute-off.svg" width="16" height="12" />
|
||||
All messages
|
||||
</div>
|
||||
<div className={ mentionsClasses } onClick={this._onClickMentions} >
|
||||
<img className="mx_NotificationStateContextMenu_activeIcon" src="img/notif-active.svg" width="12" height="12" />
|
||||
<img className="mx_NotificationStateContextMenu_icon" src="img/icon-context-mute-mentions.svg" width="16" height="12" />
|
||||
Mentions only
|
||||
</div>
|
||||
<div className={ muteNotifsClasses } onClick={this._onClickMute} >
|
||||
<img className="mx_NotificationStateContextMenu_activeIcon" src="img/notif-active.svg" width="12" height="12" />
|
||||
<img className="mx_NotificationStateContextMenu_icon" src="img/icon-context-mute.svg" width="16" height="12" />
|
||||
Mute
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
171
src/components/views/context_menus/RoomTagContextMenu.js
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var q = require("q");
|
||||
var React = require('react');
|
||||
var classNames = require('classnames');
|
||||
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'RoomTagContextMenu',
|
||||
|
||||
propTypes: {
|
||||
room: React.PropTypes.object.isRequired,
|
||||
/* callback called when the menu is dismissed */
|
||||
onFinished: React.PropTypes.func,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
isFavourite: this.props.room.tags.hasOwnProperty("m.favourite"),
|
||||
isLowPriority: this.props.room.tags.hasOwnProperty("m.lowpriority"),
|
||||
};
|
||||
},
|
||||
|
||||
_toggleTag: function(tagNameOn, tagNameOff) {
|
||||
var self = this;
|
||||
const roomId = this.props.room.roomId;
|
||||
var cli = MatrixClientPeg.get();
|
||||
if (!cli.isGuest()) {
|
||||
q.delay(500).then(function() {
|
||||
if (tagNameOff !== null && tagNameOff !== undefined) {
|
||||
cli.deleteRoomTag(roomId, tagNameOff).finally(function() {
|
||||
// Close the context menu
|
||||
if (self.props.onFinished) {
|
||||
self.props.onFinished();
|
||||
};
|
||||
}).fail(function(err) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to remove tag " + tagNameOff + " from room",
|
||||
description: err.toString()
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (tagNameOn !== null && tagNameOn !== undefined) {
|
||||
// If the tag ordering meta data is required, it is added by
|
||||
// the RoomSubList when it sorts its rooms
|
||||
cli.setRoomTag(roomId, tagNameOn, {}).finally(function() {
|
||||
// Close the context menu
|
||||
if (self.props.onFinished) {
|
||||
self.props.onFinished();
|
||||
};
|
||||
}).fail(function(err) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Failed to add tag " + tagNameOn + " to room",
|
||||
description: err.toString()
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_onClickFavourite: function() {
|
||||
// Tag room as 'Favourite'
|
||||
if (!this.state.isFavourite && this.state.isLowPriority) {
|
||||
this.setState({
|
||||
isFavourite: true,
|
||||
isLowPriority: false,
|
||||
});
|
||||
this._toggleTag("m.favourite", "m.lowpriority");
|
||||
} else if (this.state.isFavourite) {
|
||||
this.setState({isFavourite: false});
|
||||
this._toggleTag(null, "m.favourite");
|
||||
} else if (!this.state.isFavourite) {
|
||||
this.setState({isFavourite: true});
|
||||
this._toggleTag("m.favourite");
|
||||
}
|
||||
},
|
||||
|
||||
_onClickLowPriority: function() {
|
||||
// Tag room as 'Low Priority'
|
||||
if (!this.state.isLowPriority && this.state.isFavourite) {
|
||||
this.setState({
|
||||
isFavourite: false,
|
||||
isLowPriority: true,
|
||||
});
|
||||
this._toggleTag("m.lowpriority", "m.favourite");
|
||||
} else if (this.state.isLowPriority) {
|
||||
this.setState({isLowPriority: false});
|
||||
this._toggleTag(null, "m.lowpriority");
|
||||
} else if (!this.state.isLowPriority) {
|
||||
this.setState({isLowPriority: true});
|
||||
this._toggleTag("m.lowpriority");
|
||||
}
|
||||
},
|
||||
|
||||
_onClickLeave: function() {
|
||||
// Leave room
|
||||
dis.dispatch({
|
||||
action: 'leave_room',
|
||||
room_id: this.props.room.roomId,
|
||||
});
|
||||
|
||||
// Close the context menu
|
||||
if (this.props.onFinished) {
|
||||
this.props.onFinished();
|
||||
};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
var myMember = this.props.room.getMember(myUserId);
|
||||
|
||||
var favouriteClasses = classNames({
|
||||
'mx_RoomTagContextMenu_field': true,
|
||||
'mx_RoomTagContextMenu_fieldSet': this.state.isFavourite,
|
||||
'mx_RoomTagContextMenu_fieldDisabled': false,
|
||||
});
|
||||
|
||||
var lowPriorityClasses = classNames({
|
||||
'mx_RoomTagContextMenu_field': true,
|
||||
'mx_RoomTagContextMenu_fieldSet': this.state.isLowPriority,
|
||||
'mx_RoomTagContextMenu_fieldDisabled': false,
|
||||
});
|
||||
|
||||
var leaveClasses = classNames({
|
||||
'mx_RoomTagContextMenu_field': true,
|
||||
'mx_RoomTagContextMenu_fieldSet': false,
|
||||
'mx_RoomTagContextMenu_fieldDisabled': false,
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={ favouriteClasses } onClick={this._onClickFavourite} >
|
||||
<img className="mx_RoomTagContextMenu_icon" src="img/icon_context_fave.svg" width="15" height="15" />
|
||||
<img className="mx_RoomTagContextMenu_icon_set" src="img/icon_context_fave_on.svg" width="15" height="15" />
|
||||
Favourite
|
||||
</div>
|
||||
<div className={ lowPriorityClasses } onClick={this._onClickLowPriority} >
|
||||
<img className="mx_RoomTagContextMenu_icon" src="img/icon_context_low.svg" width="15" height="15" />
|
||||
<img className="mx_RoomTagContextMenu_icon_set" src="img/icon_context_low_on.svg" width="15" height="15" />
|
||||
Low Priority
|
||||
</div>
|
||||
<hr className="mx_RoomTagContextMenu_separator" />
|
||||
<div className={ leaveClasses } onClick={(myMember && myMember.membership === "join") ? this._onClickLeave : null} >
|
||||
<img className="mx_RoomTagContextMenu_icon" src="img/icon_context_delete.svg" width="15" height="15" />
|
||||
Leave
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -35,7 +35,7 @@ module.exports = React.createClass({
|
||||
return (
|
||||
<div className="mx_MatrixToolbar">
|
||||
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="/!\"/>
|
||||
<div>
|
||||
<div className="mx_MatrixToolbar_content">
|
||||
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>
|
||||
@@ -43,4 +43,3 @@ module.exports = React.createClass({
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'SenderProfile',
|
||||
|
||||
propTypes: {
|
||||
mxEvent: React.PropTypes.object.isRequired, // event whose sender we're showing
|
||||
aux: React.PropTypes.string, // stuff to go after the sender name, if anything
|
||||
onClick: React.PropTypes.func,
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var mxEvent = this.props.mxEvent;
|
||||
var name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
|
||||
|
||||
var msgtype = mxEvent.getContent().msgtype;
|
||||
if (msgtype && msgtype == 'm.emote') {
|
||||
return <span/>; // emote message must include the name so don't duplicate it
|
||||
}
|
||||
return (
|
||||
<span className="mx_SenderProfile" onClick={this.props.onClick}>
|
||||
{name} { this.props.aux }
|
||||
</span>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
56
src/components/views/settings/IntegrationsManager.js
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
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 MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'IntegrationsManager',
|
||||
|
||||
propTypes: {
|
||||
src: React.PropTypes.string.isRequired, // the source of the integration manager being embedded
|
||||
onFinished: React.PropTypes.func.isRequired, // callback when the lightbox is dismissed
|
||||
},
|
||||
|
||||
// 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();
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="mx_IntegrationsManager">
|
||||
<iframe src={ this.props.src }></iframe>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -21,11 +21,10 @@ var sdk = require('matrix-react-sdk');
|
||||
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||
var UserSettingsStore = require('matrix-react-sdk/lib/UserSettingsStore');
|
||||
var Modal = require('matrix-react-sdk/lib/Modal');
|
||||
var configJson = require("../../../../config.json");
|
||||
|
||||
var notifications = require('../../../notifications');
|
||||
|
||||
// TODO: this "view" component still has far to much application logic in it,
|
||||
// TODO: this "view" component still has far too much application logic in it,
|
||||
// which should be factored out to other files.
|
||||
|
||||
// TODO: this component also does a lot of direct poking into this.state, which
|
||||
@@ -73,6 +72,8 @@ module.exports = React.createClass({
|
||||
propTypes: {
|
||||
// The array of threepids from the JS SDK (required for email notifications)
|
||||
threepids: React.PropTypes.array.isRequired,
|
||||
// The brand string set when creating an email pusher
|
||||
brand: React.PropTypes.string,
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
@@ -118,9 +119,7 @@ module.exports = React.createClass({
|
||||
var emailPusherPromise;
|
||||
if (event.target.checked) {
|
||||
var data = {}
|
||||
if (configJson.brand) {
|
||||
data['brand'] = configJson.brand;
|
||||
}
|
||||
data['brand'] = this.props.brand || 'Vector';
|
||||
emailPusherPromise = UserSettingsStore.addEmailPusher(address, data);
|
||||
} else {
|
||||
var emailPusher = UserSettingsStore.getEmailPusher(this.state.pushers, address);
|
||||
|
||||
@@ -32,6 +32,8 @@ body {
|
||||
color: #454545;
|
||||
border: 0px;
|
||||
margin: 0px;
|
||||
/* This should render the fonts the same accross browsers */
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
}
|
||||
|
||||
div.error {
|
||||
@@ -52,12 +54,21 @@ a:visited {
|
||||
color: #76cfa6;
|
||||
}
|
||||
|
||||
input[type=text].error, input[type=password].error {
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
input[type=text]:focus, textarea:focus {
|
||||
border: 1px solid #76CFA6;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* Prevent ugly dotted highlight around selected elements in Firefox */
|
||||
::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* applied to side-panels and messagepanel when in RoomSettings */
|
||||
.mx_fadable {
|
||||
opacity: 1;
|
||||
@@ -75,53 +86,27 @@ input[type=text]:focus, textarea:focus {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/* hack to avoid accidental click-throughs if you miss the narrow scrollbar */
|
||||
/* Expand thumbs on hoverover */
|
||||
.gm-scrollbar {
|
||||
border-radius: 5px ! important;
|
||||
}
|
||||
.gm-scrollbar.-vertical {
|
||||
border-left: 6px solid transparent;
|
||||
width: 6px;
|
||||
transition: width 120ms ease-out ! important;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_background {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 1.0;
|
||||
z-index: 2000;
|
||||
.gm-scrollbar.-vertical:hover,
|
||||
.gm-scrollbar.-vertical:active {
|
||||
width: 8px;
|
||||
transition: width 120ms ease-out ! important;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu {
|
||||
border: 1px solid #a4a4a4;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
color: #747474;
|
||||
position: fixed;
|
||||
z-index: 2001;
|
||||
padding: 6px;
|
||||
.gm-scrollbar.-horizontal {
|
||||
height: 6px;
|
||||
transition: height 120ms ease-out ! important;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_chevron_right {
|
||||
padding: 12px;
|
||||
position: absolute;
|
||||
right: -21px;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_chevron_left {
|
||||
padding: 12px;
|
||||
position: absolute;
|
||||
left: -21px;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_field {
|
||||
padding: 3px 6px 3px 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_spinner {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
.gm-scrollbar.-horizontal:hover,
|
||||
.gm-scrollbar.-horizontal:active {
|
||||
height: 8px;
|
||||
transition: height 120ms ease-out ! important;
|
||||
}
|
||||
|
||||
.mx_Dialog_wrapper {
|
||||
@@ -143,16 +128,31 @@ input[type=text]:focus, textarea:focus {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* Spinner Dialog overide */
|
||||
.mx_Dialog_wrapper.mx_Dialog_spinner .mx_Dialog {
|
||||
width: auto;
|
||||
border-radius: 8px;
|
||||
padding-left: 0px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* View Source Dialog overide */
|
||||
.mx_Dialog_wrapper.mx_Dialog_viewsource .mx_Dialog {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.mx_Dialog {
|
||||
background-color: #fff;
|
||||
color: #747474;
|
||||
text-align: center;
|
||||
z-index: 4010;
|
||||
font-weight: 300;
|
||||
font-size: 15px;
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
max-width: 80%;
|
||||
padding-left: 58px;
|
||||
width: 60%;
|
||||
max-width: 704px;
|
||||
box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.mx_Dialog_background {
|
||||
@@ -161,12 +161,13 @@ input[type=text]:focus, textarea:focus {
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000;
|
||||
opacity: 0.2;
|
||||
background-color: #e9e9e9;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.mx_Dialog_lightbox .mx_Dialog_background {
|
||||
opacity: 0.85;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.mx_Dialog_lightbox .mx_Dialog {
|
||||
@@ -180,34 +181,60 @@ input[type=text]:focus, textarea:focus {
|
||||
}
|
||||
|
||||
.mx_Dialog_content {
|
||||
margin: 24px;
|
||||
margin: 24px 58px 68px 0;
|
||||
font-size: 14px;
|
||||
color: #4a4a4a;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.mx_Dialog_buttons {
|
||||
padding-bottom: 24px;
|
||||
padding-bottom: 36px;
|
||||
}
|
||||
|
||||
.mx_Dialog button, .mx_Dialog input[type="submit"] {
|
||||
border: 0px;
|
||||
height: 36px;
|
||||
border-radius: 36px;
|
||||
border-radius: 40px;
|
||||
border: solid 1px #76cfa6;
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
margin-left: 0px;
|
||||
margin-right: 8px;
|
||||
padding-left: 1.5em;
|
||||
padding-right: 1.5em;
|
||||
outline: none;
|
||||
|
||||
color: #76cfa6;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.mx_Dialog button.mx_Dialog_primary, .mx_Dialog input[type="submit"].mx_Dialog_primary {
|
||||
color: #fff;
|
||||
background-color: #76cfa6;
|
||||
margin-left: 8px;
|
||||
margin-right: 8px;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.mx_Dialog button.danger, .mx_Dialog input[type="submit"].danger {
|
||||
background-color: #ff0064;
|
||||
border: solid 1px #ff0064;
|
||||
}
|
||||
|
||||
.mx_Dialog button:disabled, .mx_Dialog input[type="submit"]:disabled {
|
||||
background-color: #777777;
|
||||
border: solid 1px #777777;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.mx_Dialog_title {
|
||||
min-height: 16px;
|
||||
padding: 12px;
|
||||
border-bottom: 1px solid #a4a4a4;
|
||||
padding-top: 40px;
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
font-size: 22px;
|
||||
line-height: 1.4;
|
||||
color: #454545;
|
||||
}
|
||||
|
||||
.mx_Dialog_title.danger {
|
||||
color: #ff0064;
|
||||
}
|
||||
|
||||
.mx_TextInputDialog_label {
|
||||
@@ -238,3 +265,15 @@ input[type=text]:focus, textarea:focus {
|
||||
background-color: #76CFA6;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/** green button with rounded corners */
|
||||
.textButton {
|
||||
color: #fff;
|
||||
background-color: #76cfa6;
|
||||
border-radius: 17px;
|
||||
text-align: center;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
cursor: pointer;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
@@ -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_ContextualMenu_wrapper {
|
||||
position: fixed;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_background {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 1.0;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu {
|
||||
border: solid 1px rgba(187, 187, 187, 0.5);
|
||||
border-radius: 4px;
|
||||
background-color: #f6f6f6;
|
||||
color: #4a4a4a;
|
||||
position: absolute;
|
||||
padding: 6px;
|
||||
font-size: 14px;
|
||||
z-index: 2001;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu.mx_ContextualMenu_right {
|
||||
right: 8px;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_chevron_right {
|
||||
position: absolute;
|
||||
right: -8px;
|
||||
top: 0px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 8px solid transparent;
|
||||
border-left: 8px solid rgba(187, 187, 187, 0.5);
|
||||
border-bottom: 8px solid transparent;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_chevron_right:after {
|
||||
content:'';
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 7px solid transparent;
|
||||
border-left: 7px solid #f6f6f6;
|
||||
border-bottom: 7px solid transparent;
|
||||
position:absolute;
|
||||
top: -7px;
|
||||
right: 1px;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu.mx_ContextualMenu_left {
|
||||
left: 8px;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_chevron_left {
|
||||
position: absolute;
|
||||
left: -8px;
|
||||
top: 0px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 8px solid transparent;
|
||||
border-right: 8px solid rgba(187, 187, 187, 0.5);
|
||||
border-bottom: 8px solid transparent;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_chevron_left:after{
|
||||
content:'';
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 7px solid transparent;
|
||||
border-right: 7px solid #f6f6f6;
|
||||
border-bottom: 7px solid transparent;
|
||||
position:absolute;
|
||||
top: -7px;
|
||||
left: 1px;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_field {
|
||||
padding: 3px 6px 3px 6px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_spinner {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
@@ -93,8 +93,8 @@ limitations under the License.
|
||||
|
||||
background-color: #eaf5f0;
|
||||
|
||||
-webkit-flex: 0 0 210px;
|
||||
flex: 0 0 210px;
|
||||
-webkit-flex: 0 0 235px;
|
||||
flex: 0 0 235px;
|
||||
}
|
||||
|
||||
.mx_MatrixChat .mx_LeftPanel.collapsed {
|
||||
|
||||
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
.mx_SearchBox {
|
||||
height: 24px;
|
||||
margin-left: 16px;
|
||||
margin-right: 20px;
|
||||
margin-right: 16px;
|
||||
padding-top: 24px;
|
||||
padding-bottom: 22px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
@@ -28,11 +28,13 @@ limitations under the License.
|
||||
|
||||
.mx_SearchBox_searchButton {
|
||||
margin-right: 10px;
|
||||
margin-top: 5px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mx_SearchBox_closeButton {
|
||||
cursor: pointer;
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
.mx_SearchBox_search {
|
||||
@@ -65,4 +67,4 @@ limitations under the License.
|
||||
|
||||
.mx_SearchBox object {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,12 +94,26 @@ limitations under the License.
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_UserSettings_button.danger {
|
||||
background-color: #ff0064;
|
||||
}
|
||||
|
||||
.mx_UserSettings_section {
|
||||
margin-left: 63px;
|
||||
margin-top: 28px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.mx_UserSettings_toggle input {
|
||||
width: 16px;
|
||||
margin-right: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.mx_UserSettings_toggle label {
|
||||
padding-bottom: 21px;
|
||||
}
|
||||
|
||||
.mx_UserSettings_accountTable
|
||||
.mx_UserSettings_notifTable
|
||||
{
|
||||
|
||||
@@ -131,9 +131,19 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_Login_loader {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-top: 12px;
|
||||
display: inline;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
left: 8px;
|
||||
}
|
||||
|
||||
.mx_Login_loader .mx_Spinner {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.mx_Login_loader .mx_Spinner img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.mx_Login_error {
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
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_MultiInviteDialog ul {
|
||||
height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.mx_MultiInviteDialog li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.mx_MultiInviteDialog_statusText {
|
||||
text-indent: 20px;
|
||||
}
|
||||
|
||||
.mx_MultiInviteDialog p.error {
|
||||
color: #ff0064;
|
||||
}
|
||||
|
||||
.mx_MultiInviteDialog p.invited {
|
||||
color: #76cfa6;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
.mx_UserPill {
|
||||
color: white;
|
||||
background-color: #76cfa6;
|
||||
padding: 2px 8px;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.mx_RoomPill {
|
||||
background-color: white;
|
||||
color: #76cfa6;
|
||||
border: 1px solid #76cfa6;
|
||||
padding: 2px 8px;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.mx_Markdown_BOLD {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mx_Markdown_ITALIC {
|
||||
font-style: italic;
|
||||
}
|
||||
@@ -17,3 +17,8 @@ limitations under the License.
|
||||
.mx_MTextBody {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.mx_MTextBody pre{
|
||||
overflow-y: auto;
|
||||
max-height: 30vh;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
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_UnknownBody {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
.mx_Autocomplete {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
z-index: 1000;
|
||||
width: 100%;
|
||||
border: 1px solid #e5e5e5;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border-bottom: none;
|
||||
border-radius: 4px 4px 0 0;
|
||||
max-height: 50vh;
|
||||
overflow: auto
|
||||
}
|
||||
|
||||
.mx_Autocomplete_ProviderSection {
|
||||
padding: 12px;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.mx_Autocomplete_ProviderSection * {
|
||||
padding: 2px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.mx_Autocomplete_Completion {
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
transition: 0.3s all ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mx_Autocomplete_Completion.selected * {
|
||||
transition: 0.3s all ease;
|
||||
}
|
||||
|
||||
.mx_Autocomplete_Completion.selected {
|
||||
background: #76cfa6;
|
||||
color: white;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.mx_Autocomplete_Completion.selected * {
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.mx_Autocomplete_provider_name {
|
||||
color: #76cfa6;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.autocomplete-enter {
|
||||
opacity: 0.01;
|
||||
}
|
||||
|
||||
.autocomplete-enter.autocomplete-enter-active {
|
||||
opacity: 1;
|
||||
transition: opacity 300ms ease-in;
|
||||
}
|
||||
|
||||
.autocomplete-leave {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.autocomplete-leave.autocomplete-leave-active {
|
||||
opacity: 0.01;
|
||||
transition: opacity 300ms ease-in;
|
||||
}
|
||||
@@ -87,14 +87,17 @@ limitations under the License.
|
||||
|
||||
.mx_EntityTile_unavailable .mx_EntityTile_avatar,
|
||||
.mx_EntityTile_unavailable .mx_EntityTile_name,
|
||||
.mx_EntityTile_unavailable .mx_EntityTile_name_hover
|
||||
.mx_EntityTile_unavailable .mx_EntityTile_name_hover,
|
||||
.mx_EntityTile_offline_beenactive .mx_EntityTile_avatar,
|
||||
.mx_EntityTile_offline_beenactive .mx_EntityTile_name,
|
||||
.mx_EntityTile_offline_beenactive .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
|
||||
.mx_EntityTile_offline_neveractive .mx_EntityTile_avatar,
|
||||
.mx_EntityTile_offline_neveractive .mx_EntityTile_name,
|
||||
.mx_EntityTile_offline_neveractive .mx_EntityTile_name_hover
|
||||
{
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
.mx_EventTile {
|
||||
max-width: 100%;
|
||||
clear: both;
|
||||
margin-top: 24px;
|
||||
padding-top: 24px;
|
||||
margin-left: 65px;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,15 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_EventTile_continuation {
|
||||
margin-top: 8px ! important;
|
||||
padding-top: 8px ! important;
|
||||
}
|
||||
|
||||
.mx_EventTile_verified {
|
||||
background-color: #eaf5f0;
|
||||
}
|
||||
|
||||
.mx_EventTile_unverified {
|
||||
background-color: #ffa0a0;
|
||||
}
|
||||
|
||||
.mx_EventTile .mx_SenderProfile {
|
||||
@@ -68,6 +76,11 @@ limitations under the License.
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* De-zalgoing */
|
||||
.mx_EventTile_body {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
/* Various markdown overrides */
|
||||
|
||||
.mx_EventTile_content .markdown-body {
|
||||
@@ -107,6 +120,12 @@ limitations under the License.
|
||||
|
||||
/* end of overrides */
|
||||
|
||||
/* HACK to override line-height which is already marked important elsewhere */
|
||||
.mx_EventTile_bigEmoji.mx_EventTile_bigEmoji {
|
||||
font-size: 48px ! important;
|
||||
line-height: 48px ! important;
|
||||
}
|
||||
|
||||
/* this is used for the tile for the event which is selected via the URL.
|
||||
* TODO: ultimately we probably want some transition on here.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
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_MemberDeviceInfo {
|
||||
font-size: 12px;
|
||||
display: table-row;
|
||||
height: 17px;
|
||||
}
|
||||
|
||||
.mx_MemberDeviceInfo div {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.mx_MemberDeviceInfo_textButton {
|
||||
color: #fff;
|
||||
background-color: #76cfa6;
|
||||
border-radius: 17px;
|
||||
text-align: center;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_verified,
|
||||
.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_unverified,
|
||||
.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_blocked {
|
||||
color: #fff;
|
||||
width: 17px;
|
||||
border-radius: 17px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_verified {
|
||||
background-color: #76cfa6;
|
||||
}
|
||||
|
||||
.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_unverified {
|
||||
background-color: #eca46f;
|
||||
}
|
||||
|
||||
.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_blocked {
|
||||
background-color: #e55e5e;
|
||||
}
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
.mx_MemberInfo {
|
||||
margin-top: 20px;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.mx_MemberInfo h2 {
|
||||
@@ -72,3 +73,8 @@ limitations under the License.
|
||||
margin-left: 8px;
|
||||
line-height: 23px;
|
||||
}
|
||||
|
||||
.mx_MemberInfo_devices {
|
||||
display: table;
|
||||
border-spacing: 5px;
|
||||
}
|
||||
@@ -21,16 +21,21 @@ limitations under the License.
|
||||
border-top: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_autocomplete_wrapper {
|
||||
position: relative;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_row {
|
||||
display: table-row;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mx_MessageComposer .mx_MessageComposer_avatar {
|
||||
display: table-cell;
|
||||
padding-left: 10px;
|
||||
padding-right: 28px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_MessageComposer .mx_MessageComposer_avatar .mx_BaseAvatar {
|
||||
@@ -42,9 +47,7 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_MessageComposer_noperm_error {
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
vertical-align: middle;
|
||||
height: 60px;
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
@@ -52,10 +55,20 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_MessageComposer_input {
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
vertical-align: middle;
|
||||
height: 60px;
|
||||
min-height: 60px;
|
||||
max-height: 120px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: auto;
|
||||
}
|
||||
.mx_MessageComposer_input_rte {
|
||||
border-top: 2px solid #76cfa6; /* placeholder RTE indicator */
|
||||
}
|
||||
|
||||
.mx_MessageComposer_input .DraftEditor-root {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_input textarea {
|
||||
@@ -92,11 +105,12 @@ limitations under the License.
|
||||
.mx_MessageComposer_hangup,
|
||||
.mx_MessageComposer_voicecall,
|
||||
.mx_MessageComposer_videocall {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
/*display: table-cell;*/
|
||||
/*vertical-align: middle;*/
|
||||
/*padding-left: 10px;*/
|
||||
padding-right: 5px;
|
||||
cursor: pointer;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_upload object,
|
||||
@@ -106,16 +120,3 @@ limitations under the License.
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,8 @@ limitations under the License.
|
||||
.mx_RoomHeader_rightRow {
|
||||
margin-top: 4px;
|
||||
background-color: #fff;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
-webkit-box-ordinal-group: 3;
|
||||
-moz-box-ordinal-group: 3;
|
||||
-ms-flex-order: 3;
|
||||
@@ -161,13 +162,6 @@ limitations under the License.
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_settingsButton {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
bottom: 10px;
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_settingsButton object {
|
||||
pointer-events: none;
|
||||
}
|
||||
@@ -183,10 +177,6 @@ limitations under the License.
|
||||
color: #76cfa6;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_leaveButton {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_placeholder {
|
||||
color: #a2a2a2 ! important;
|
||||
}
|
||||
@@ -243,10 +233,7 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_RoomHeader_button {
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
margin-left: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,33 +15,79 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_RoomTile {
|
||||
cursor: pointer;
|
||||
/* This fixes wrapping of long room names, but breaks drag & drop previews */
|
||||
/* display: table-row; */
|
||||
font-size: 13px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
display: block;
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
.mx_RoomTile_nameContainer {
|
||||
display: inline-block;
|
||||
width: 180px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.mx_RoomTile_avatar {
|
||||
display: table-cell;
|
||||
padding-right: 11px;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
padding-left: 18px;
|
||||
display: inline-block;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
padding-left: 16px;
|
||||
padding-right: 6px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_RoomTile_avatar_container:hover:before,
|
||||
.mx_RoomTile_avatar_container.mx_RoomTile_avatar_roomTagMenu:before {
|
||||
display: block;
|
||||
position: absolute;
|
||||
content: "";
|
||||
border-radius: 40px;
|
||||
background-image: url("img/icons_ellipsis.svg");
|
||||
background-size: 25px;
|
||||
left: 15px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.mx_RoomTile_avatar_container:hover:after,
|
||||
.mx_RoomTile_avatar_container.mx_RoomTile_avatar_roomTagMenu:after {
|
||||
display: block;
|
||||
position: absolute;
|
||||
content: "";
|
||||
border-radius: 40px;
|
||||
background: #4A4A4A;
|
||||
top: 5px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
opacity: 0.6;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.collapsed .mx_RoomTile_avatar_container:hover:before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.collapsed .mx_RoomTile_avatar_container:hover:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_RoomTile_name {
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 165px;
|
||||
vertical-align: middle;
|
||||
overflow: hidden;
|
||||
word-break: break-word;
|
||||
padding-right: 15px;
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 3px;
|
||||
color: rgba(69, 69, 69, 0.8);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.mx_RoomTile_ellipsis .mx_RoomTile_name {
|
||||
@@ -54,28 +100,66 @@ limitations under the License.
|
||||
*/
|
||||
}
|
||||
|
||||
.collapsed .mx_RoomTile_nameContainer {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.collapsed .mx_RoomTile_name {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.collapsed .mx_RoomTile_badge {
|
||||
margin-top: -15px;
|
||||
right: 7px;
|
||||
top: -2px;
|
||||
min-width: 12px;
|
||||
height: 16px;
|
||||
border-radius: 16px;
|
||||
padding: 0px 4px 0px 4px;
|
||||
z-index: 200;
|
||||
}
|
||||
|
||||
/* Hide the bottom of speech bubble */
|
||||
.collapsed .mx_RoomTile_highlight .mx_RoomTile_badge:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* This is the bottom of the speech bubble */
|
||||
.mx_RoomTile_highlight .mx_RoomTile_badge:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin-left: 6px;
|
||||
border-top: 8px solid #ff0064;
|
||||
border-right: 10px solid transparent;
|
||||
}
|
||||
|
||||
.mx_RoomTile_badge {
|
||||
min-width: 12px;
|
||||
height: 16px;
|
||||
display: inline-block;
|
||||
min-width: 19px;
|
||||
height: 17px;
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
top: 50%;
|
||||
margin-top: -8px;
|
||||
border-radius: 16px;
|
||||
right: 8px; /*gutter */
|
||||
top: 9px;
|
||||
border-radius: 14px;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
font-weight: 600;
|
||||
font-size: 11px;
|
||||
text-align: center;
|
||||
padding: 0px 4px 0px 4px;
|
||||
padding-top: 1px;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.mx_RoomTile .mx_RoomTile_badge.mx_RoomTile_badgeButton,
|
||||
.mx_RoomTile.mx_RoomTile_notificationStateMenu .mx_RoomTile_badge {
|
||||
letter-spacing: 0.1em;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.mx_RoomTile.mx_RoomTile_noBadges .mx_RoomTile_badge.mx_RoomTile_badgeButton,
|
||||
.mx_RoomTile.mx_RoomTile_notificationStateMenu.mx_RoomTile_noBadges .mx_RoomTile_badge {
|
||||
background-color: rgb(214, 214, 214);
|
||||
}
|
||||
|
||||
.mx_RoomTile_unreadNotify .mx_RoomTile_badge {
|
||||
@@ -86,41 +170,16 @@ limitations under the License.
|
||||
background-color: #ff0064;
|
||||
}
|
||||
|
||||
.mx_RoomTile_unread,
|
||||
.mx_RoomTile_highlight {
|
||||
font-weight: bold;
|
||||
.mx_RoomTile_unread, .mx_RoomTile_highlight {
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
/* the inner highlight span has 4px of padding on it, so we shrink the _avatar by 4px and grow the _name by 4px to fit it in */
|
||||
.mx_RoomTile_selected .mx_RoomTile_name {
|
||||
padding-right: 19px;
|
||||
}
|
||||
.mx_RoomTile_selected .mx_RoomTile_avatar {
|
||||
padding-right: 7px;
|
||||
}
|
||||
|
||||
/* leave room for the badge, if present.
|
||||
N.B. this has to come after the above _selected width tweaks */
|
||||
.mx_RoomTile_unreadNotify .mx_RoomTile_name,
|
||||
.mx_RoomTile_highlight .mx_RoomTile_name {
|
||||
padding-right: 40px;
|
||||
}
|
||||
|
||||
.mx_RoomTile_selected .mx_RoomTile_name span {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding: 4px;
|
||||
margin-top: -4px;
|
||||
margin-bottom: -4px;
|
||||
border-radius: 2px;
|
||||
.mx_RoomTile_selected {
|
||||
background-color: rgba(118,207,166,0.2);
|
||||
}
|
||||
|
||||
/* stop the span from overlapping with the badge */
|
||||
.mx_RoomTile_unreadNotify.mx_RoomTile_selected .mx_RoomTile_name span,
|
||||
.mx_RoomTile_highlight.mx_RoomTile_selected .mx_RoomTile_name span {
|
||||
padding-right: 22px;
|
||||
.mx_RoomTile .mx_RoomTile_name.mx_RoomTile_badgeShown {
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
.mx_RoomTile_arrow {
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
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_DevicesPanel {
|
||||
display: table;
|
||||
table-layout: fixed;
|
||||
width: 880px;
|
||||
border-spacing: 2px;
|
||||
}
|
||||
|
||||
.mx_DevicesPanel_header {
|
||||
display: table-header-group;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mx_DevicesPanel_header > div {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.mx_DevicesPanel_header .mx_DevicesPanel_deviceLastSeen {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.mx_DevicesPanel_header .mx_DevicesPanel_deviceButtons {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.mx_DevicesPanel_device {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.mx_DevicesPanel_device > div {
|
||||
display: table-cell;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
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_IntegrationsManager {
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
-webkit-justify-content: center;
|
||||
}
|
||||
|
||||
.mx_IntegrationsManager iframe {
|
||||
background-color: #fff;
|
||||
border: 0px;
|
||||
width: 720px;
|
||||
height: 512px;
|
||||
}
|
||||
@@ -51,6 +51,10 @@ limitations under the License.
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.mx_LeftPanel.collapsed .mx_BottomLeftMenu {
|
||||
flex: 0 0 120px;
|
||||
}
|
||||
|
||||
.mx_LeftPanel .mx_BottomLeftMenu {
|
||||
-webkit-box-ordinal-group: 3;
|
||||
-moz-box-ordinal-group: 3;
|
||||
@@ -59,10 +63,11 @@ limitations under the License.
|
||||
order: 3;
|
||||
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
margin-left: 18px;
|
||||
margin-right: 18px;
|
||||
margin-left: 16px; /* gutter */
|
||||
margin-right: 16px; /* gutter */
|
||||
-webkit-flex: 0 0 60px;
|
||||
flex: 0 0 60px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.mx_LeftPanel .mx_BottomLeftMenu_options {
|
||||
@@ -95,3 +100,7 @@ limitations under the License.
|
||||
.mx_LeftPanel .mx_BottomLeftMenu_settings {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.mx_LeftPanel.collapsed .mx_BottomLeftMenu_settings {
|
||||
float: none;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ limitations under the License.
|
||||
/** Fixme - factor this out with the main header **/
|
||||
|
||||
.mx_RightPanel_headerButtonGroup {
|
||||
margin-top: 25px;
|
||||
margin-top: 6px;
|
||||
float: left;
|
||||
background-color: #fff;
|
||||
margin-left: -4px;
|
||||
@@ -55,34 +55,27 @@ limitations under the License.
|
||||
vertical-align: middle;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_RightPanel_headerButton object {
|
||||
pointer-events: none;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
|
||||
.mx_RightPanel_headerButton_highlight {
|
||||
position: absolute;
|
||||
bottom: -2px;
|
||||
left: 10px;
|
||||
width: 25px;
|
||||
height: 4px;
|
||||
background-color: #76cfa6;
|
||||
height: 5px;
|
||||
border-radius: 5px;
|
||||
background-color: rgba(118, 207, 166, 0.2);
|
||||
}
|
||||
|
||||
.mx_RightPanel_headerButton_badge {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 28px;
|
||||
font-size: 12px;
|
||||
background-color: #76cfa6;
|
||||
color: #fff;
|
||||
font-size: 11px;
|
||||
color: #76cfa6;
|
||||
font-weight: bold;
|
||||
border-radius: 20px;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.mx_RightPanel .mx_MemberList,
|
||||
|
||||
@@ -25,8 +25,8 @@ limitations under the License.
|
||||
color: #3d3b39;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
padding-left: 16px; /* gutter */
|
||||
padding-right: 16px; /* gutter */
|
||||
margin-top: 8px;
|
||||
margin-bottom: 4px;
|
||||
cursor: pointer;
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
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_MessageContextMenu_field {
|
||||
padding: 3px 6px 3px 6px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_field.mx_MessageContextMenu_fieldSet {
|
||||
font-weight: bold;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_NotificationStateContextMenu_picker {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: 5px;
|
||||
}
|
||||
|
||||
.mx_NotificationStateContextMenu_field {
|
||||
padding-top: 4px;
|
||||
padding-right: 6px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 8px; /* 20px */
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mx_NotificationStateContextMenu_field.mx_NotificationStateContextMenu_fieldSet {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mx_NotificationStateContextMenu_field.mx_NotificationStateContextMenu_fieldDisabled {
|
||||
color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.mx_NotificationStateContextMenu_icon {
|
||||
padding-right: 4px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.mx_NotificationStateContextMenu_activeIcon {
|
||||
display: inline-block;
|
||||
opacity: 0;
|
||||
position: relative;
|
||||
left: -5px;
|
||||
}
|
||||
|
||||
.mx_NotificationStateContextMenu_fieldSet .mx_NotificationStateContextMenu_activeIcon {
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_RoomTagContextMenu_field {
|
||||
padding-top: 8px;
|
||||
padding-right: 20px;
|
||||
padding-bottom: 8px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_field:first-child {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_field:last-child {
|
||||
padding-bottom: 4px;
|
||||
color: #ff0064;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_field.mx_RoomTagContextMenu_fieldSet {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_field.mx_RoomTagContextMenu_fieldSet .mx_RoomTagContextMenu_icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_field.mx_RoomTagContextMenu_fieldSet .mx_RoomTagContextMenu_icon_set {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_field.mx_RoomTagContextMenu_fieldDisabled {
|
||||
color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_icon {
|
||||
padding-right: 8px;
|
||||
padding-left: 4px;
|
||||
display: inline-block
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_icon_set {
|
||||
padding-right: 8px;
|
||||
padding-left: 4px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_separator {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
border-right-style: none;
|
||||
border-top-style: solid;
|
||||
border-top-width: 1px;
|
||||
border-color: #bbbbbb;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.mx_RoomTagContextMenu_fieldSet .mx_RoomTagContextMenu_icon {
|
||||
/* Something to indicate that the icon is the set tag */
|
||||
}
|
||||
@@ -69,6 +69,7 @@ limitations under the License.
|
||||
.mx_ImageView_labelWrapper {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
pointer-events: all;
|
||||
|
||||
@@ -33,6 +33,11 @@ limitations under the License.
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.mx_MatrixToolbar_content {
|
||||
-webkit-flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.mx_MatrixToolbar_link
|
||||
{
|
||||
color: #fff ! important;
|
||||
@@ -41,10 +46,7 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_MatrixToolbar_close {
|
||||
-webkit-flex: 1;
|
||||
flex: 1;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.mx_MatrixToolbar_close img {
|
||||
|
||||
@@ -16,8 +16,8 @@ limitations under the License.
|
||||
|
||||
.mx_RoomDropTarget {
|
||||
font-size: 13px;
|
||||
margin-left: 10px;
|
||||
margin-right: 15px;
|
||||
margin-left: 18px;
|
||||
margin-right: 18px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
border: 1px dashed #76cfa6;
|
||||
@@ -28,6 +28,7 @@ limitations under the License.
|
||||
|
||||
.collapsed .mx_RoomDropTarget {
|
||||
margin-right: 10px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.mx_RoomDropTarget_placeholder {
|
||||
|
||||
@@ -14,19 +14,19 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_RoomTooltip_chevron {
|
||||
position: absolute;
|
||||
left: -9px;
|
||||
top: 7px;
|
||||
}
|
||||
|
||||
.mx_RoomTooltip {
|
||||
display: none;
|
||||
position: fixed;
|
||||
border: 1px solid #a4a4a4;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
z-index: 1000;
|
||||
left: 64px;
|
||||
z-index: 2000;
|
||||
left: 52px;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.mx_RoomTooltip_chevron {
|
||||
position: absolute;
|
||||
left: -9px;
|
||||
top: 8px;
|
||||
}
|
||||
|
||||
@@ -21,20 +21,20 @@ limitations under the License.
|
||||
|
||||
.mx_UserNotifSettings_inputCell {
|
||||
display: table-cell;
|
||||
padding-bottom: 21px;
|
||||
padding-bottom: 8px;
|
||||
padding-right: 8px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.mx_UserNotifSettings_labelCell
|
||||
{
|
||||
padding-bottom: 21px;
|
||||
padding-bottom: 8px;
|
||||
width: 400px;
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.mx_UserNotifSettings_pushRulesTableWrapper {
|
||||
padding-bottom: 21px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.mx_UserNotifSettings_pushRulesTable {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans'), local('OpenSans'), url(opensans/v13/cJZKeOuBrn4kERxqtaUH3ZBw1xU1rKptJj_0jans920.woff2) format('woff2');
|
||||
src: local('Open Sans'), local('OpenSans'), url(opensans/v13/cJZKeOuBrn4kERxqtaUH3ZBw1xU1rKptJj_0jans920.woff2) format('woff2'), url(Open_Sans/OpenSans-Regular.ttf) format('truetype');
|
||||
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 */
|
||||
@@ -11,7 +11,7 @@
|
||||
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');
|
||||
src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(opensans/v13/MTP_ySUJH_bn48VBG8sNShampu5_7CjHW5spxoeN3Vs.woff2) format('woff2'), url(Open_Sans/OpenSans-Semibold.ttf) format('truetype');
|
||||
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 */
|
||||
@@ -19,6 +19,6 @@
|
||||
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');
|
||||
src: local('Open Sans Bold'), local('OpenSans-Bold'), url(opensans/v13/k3k702ZOKiLJc3WVjuplzBampu5_7CjHW5spxoeN3Vs.woff2) format('woff2'), url(Open_Sans/OpenSans-Bold.ttf) format('truetype');
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
202
src/skins/vector/fonts/Open_Sans/LICENSE.txt
Executable file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
BIN
src/skins/vector/fonts/Open_Sans/OpenSans-Bold.ttf
Executable file
BIN
src/skins/vector/fonts/Open_Sans/OpenSans-Regular.ttf
Executable file
BIN
src/skins/vector/fonts/Open_Sans/OpenSans-Semibold.ttf
Executable file
8
src/skins/vector/img/icon-call.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="35" height="35" viewBox="0, 0, 35, 35">
|
||||
<g id="Symbols">
|
||||
<path d="M17.5,35 C27.165,35 35,27.165 35,17.5 C35,7.835 27.165,0 17.5,0 C7.835,0 0,7.835 0,17.5 C0,27.165 7.835,35 17.5,35 z" fill="#EAF5F0" id="Oval-109"/>
|
||||
<path d="M23,28 C21.195,28 16.807,25.624 13.122,20.524 C9.675,15.755 8,12.309 8,9.99 C8,8.164 9.225,7.293 9.883,6.825 L10.045,6.708 C10.773,6.173 11.903,6 12.337,6 C13.097,6 13.417,6.458 13.611,6.857 C13.776,7.195 15.141,10.212 15.28,10.587 C15.492,11.164 15.422,12.005 14.766,12.488 L14.65,12.571 C14.324,12.804 13.718,13.236 13.634,13.761 C13.594,14.016 13.677,14.283 13.889,14.577 C14.946,16.043 18.32,20.346 18.928,20.931 C19.405,21.389 20.009,21.455 20.42,21.098 C20.846,20.729 21.035,20.511 21.037,20.508 L21.081,20.465 C21.116,20.434 21.449,20.162 21.992,20.162 C22.385,20.162 22.783,20.302 23.178,20.576 C24.201,21.287 26.51,22.876 26.51,22.876 L26.547,22.906 C26.842,23.166 27.269,23.917 26.772,24.893 C26.256,25.907 24.655,28 23,28 L23,28 z" fill-opacity="0" stroke="#76CFA6" stroke-width="1" id="path-1"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
10
src/skins/vector/img/icon-context-delete.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="15" height="15" viewBox="0, 0, 15, 15">
|
||||
<g id="Extra-icons">
|
||||
<g>
|
||||
<path d="M3.45,3.45 L11.55,11.55" fill-opacity="0" stroke="#FF0064" stroke-width="1" stroke-linecap="round" id="Line"/>
|
||||
<path d="M11.55,3.45 L3.45,11.55" fill-opacity="0" stroke="#FF0064" stroke-width="1" stroke-linecap="round" id="Line-Copy-2"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 607 B |
15
src/skins/vector/img/icon-context-fave-on.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="13px" height="13px" viewBox="0 0 13 13" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>DAE17B64-40B5-478A-8E8D-97AD1A6E25C8</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="Extra-icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Extra-icons-sheet" transform="translate(-93.000000, -313.000000)">
|
||||
<g id="icon_context_fave_on" transform="translate(92.000000, 312.000000)">
|
||||
<rect id="Rectangle" fill-opacity="0" fill="#D8D8D8" x="0" y="0" width="15" height="15"></rect>
|
||||
<polygon id="Star-1" stroke="#4A4A4A" stroke-linejoin="round" fill="#4A4A4A" points="7.5 10.75 3.67939586 12.7586105 4.40906632 8.50430523 1.31813264 5.49138954 5.58969793 4.87069477 7.5 1 9.41030207 4.87069477 13.6818674 5.49138954 10.5909337 8.50430523 11.3206041 12.7586105"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
15
src/skins/vector/img/icon-context-fave.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="13px" height="13px" viewBox="0 0 13 13" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>8A6E1837-F0F1-432E-A0DA-6F3741F71EBF</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="Extra-icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.2">
|
||||
<g id="Extra-icons-sheet" transform="translate(-63.000000, -313.000000)">
|
||||
<g id="icon_context_fave" transform="translate(62.000000, 312.000000)">
|
||||
<rect id="Rectangle" fill-opacity="0" fill="#D8D8D8" x="0" y="0" width="15" height="15"></rect>
|
||||
<polygon id="Star-1" stroke="#000000" stroke-linejoin="round" points="7.5 10.75 3.67939586 12.7586105 4.40906632 8.50430523 1.31813264 5.49138954 5.58969793 4.87069477 7.5 1 9.41030207 4.87069477 13.6818674 5.49138954 10.5909337 8.50430523 11.3206041 12.7586105"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
15
src/skins/vector/img/icon-context-low-on.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="13px" height="13px" viewBox="0 0 13 13" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>CD51482C-F2D4-4F63-AF9E-86513F9AF87F</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="Extra-icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Extra-icons-sheet" transform="translate(-93.000000, -338.000000)">
|
||||
<g id="icon_context_low_on" transform="translate(92.000000, 337.000000)">
|
||||
<rect id="Rectangle-Copy" fill-opacity="0" fill="#D8D8D8" x="0" y="0" width="15" height="15"></rect>
|
||||
<path d="M12.7604081,8 C13.2413214,8 13.3067421,8.25679316 12.9190465,8.57356358 L8.20351162,12.4264364 C7.81340686,12.7451752 7.18723719,12.7432068 6.79954156,12.4264364 L2.08400668,8.57356358 C1.69390193,8.25482476 1.76733588,8 2.24264506,8 L4.46666667,8 L4.46666667,3.00292933 C4.46666667,2.44902676 4.84616384,2 5.33587209,2 L9.66412791,2 C10.1441768,2 10.5333333,2.43788135 10.5333333,3.00292933 L10.5333333,8 L12.7604081,8 Z" id="Combined-Shape" stroke="#4A4A4A" stroke-linejoin="round" fill="#4A4A4A"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
15
src/skins/vector/img/icon-context-low.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="13px" height="13px" viewBox="0 0 13 13" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>B160345F-40D3-4BE6-A860-6D04BF223EF7</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="Extra-icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Extra-icons-sheet" transform="translate(-63.000000, -338.000000)">
|
||||
<g id="icon_context_low" transform="translate(62.000000, 337.000000)">
|
||||
<rect id="Rectangle" fill-opacity="0" fill="#D8D8D8" x="0" y="0" width="15" height="15"></rect>
|
||||
<path d="M12.7604081,8 C13.2413214,8 13.3067421,8.25679316 12.9190465,8.57356358 L8.20351162,12.4264364 C7.81340686,12.7451752 7.18723719,12.7432068 6.79954156,12.4264364 L2.08400668,8.57356358 C1.69390193,8.25482476 1.76733588,8 2.24264506,8 L4.46666667,8 L4.46666667,3.00292933 C4.46666667,2.44902676 4.84616384,2 5.33587209,2 L9.66412791,2 C10.1441768,2 10.5333333,2.43788135 10.5333333,3.00292933 L10.5333333,8 L12.7604081,8 Z" id="Combined-Shape" stroke="#000000" stroke-linejoin="round" opacity="0.2"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
11
src/skins/vector/img/icon-context-mute-mentions.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="16" height="12" viewBox="0, 0, 16, 12">
|
||||
<g id="Screens-revised" opacity="0.2">
|
||||
<g>
|
||||
<path d="M7.142,0.009 C7.687,0.152 7.921,0.47 8,1 L8,11 C8,11.866 6.974,12.323 6.33,11.743 L3.288,9 L1,9 C0.448,9 0,8.552 0,8 L0,4 C0,3.448 0.448,3 1,3 L3.278,3 L6.332,0.256 C6.744,-0.016 6.487,0.101 7.142,0.009 z M7,1 L3.661,4 L1,4 L1,8 L3.672,8 L7,11 L7,1 z" fill="#000000" id="path-1"/>
|
||||
<path d="M13,3.928 C13,4.757 12.328,5.428 11.5,5.428 C10.672,5.428 10,4.757 10,3.928 C10,3.1 10.672,2.428 11.5,2.428 C12.328,2.428 13,3.1 13,3.928 z" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" id="path-3"/>
|
||||
<path d="M14,9.5 C14,6.84 12.881,6 11.5,6 C10.119,6 9,6.884 9,9.5 L14,9.5 z" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" id="path-5"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
10
src/skins/vector/img/icon-context-mute-off-copy.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="16" height="12" viewBox="0, 0, 16, 12">
|
||||
<g id="Screens-revised" opacity="0.2">
|
||||
<path d="M7.142,0.009 C7.687,0.152 7.921,0.47 8,1 L8,11 C8,11.866 6.974,12.323 6.33,11.743 L3.288,9 L1,9 C0.448,9 0,8.552 0,8 L0,4 C0,3.448 0.448,3 1,3 L3.278,3 L6.332,0.256 C6.744,-0.016 6.487,0.101 7.142,0.009 z M7,1 L3.661,4 L1,4 L1,8 L3.672,8 L7,11 L7,1 z" fill="#000000" id="path-1"/>
|
||||
<path d="M9.878,7.667 C10.82,7.667 11.584,6.92 11.584,6 C11.584,5.08 10.82,4.333 9.878,4.333" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-linecap="round" id="Oval-50"/>
|
||||
<path d="M10.055,9.333 C11.939,9.333 13.466,7.841 13.466,6 C13.466,4.159 11.939,2.667 10.055,2.667" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-linecap="round" id="Oval-50-Copy"/>
|
||||
<path d="M10.055,11 C12.881,11 15.172,8.761 15.172,6 C15.172,3.239 12.881,1 10.055,1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-linecap="round" id="Oval-50-Copy-2"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
9
src/skins/vector/img/icon-context-mute-off.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="16" height="12" viewBox="0, 0, 16, 12">
|
||||
<g id="Screens-revised" opacity="0.2">
|
||||
<path d="M7.142,0.009 C7.687,0.152 7.921,0.47 8,1 L8,11 C8,11.866 6.974,12.323 6.33,11.743 L3.288,9 L1,9 C0.448,9 0,8.552 0,8 L0,4 C0,3.448 0.448,3 1,3 L3.278,3 L6.332,0.256 C6.744,-0.016 6.487,0.101 7.142,0.009 z M7,1 L3.661,4 L1,4 L1,8 L3.672,8 L7,11 L7,1 z" fill="#000000" id="path-1"/>
|
||||
<path d="M10,8 C11.105,8 12,7.105 12,6 C12,4.895 11.105,4 10,4" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-linecap="round" id="Oval-50"/>
|
||||
<path d="M10.207,10 C12.416,10 14.207,8.209 14.207,6 C14.207,3.791 12.416,2 10.207,2" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-linecap="round" id="Oval-50-Copy"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 984 B |
9
src/skins/vector/img/icon-context-mute.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="16" height="12" viewBox="0, 0, 16, 12">
|
||||
<g id="Screens-revised" opacity="0.2">
|
||||
<path d="M7.142,0.009 C7.687,0.152 7.921,0.47 8,1 L8,11 C8,11.866 6.974,12.323 6.33,11.743 L3.288,9 L1,9 C0.448,9 0,8.552 0,8 L0,4 C0,3.448 0.448,3 1,3 L3.278,3 L6.332,0.256 C6.744,-0.016 6.487,0.101 7.142,0.009 z M7,1 L3.661,4 L1,4 L1,8 L3.672,8 L7,11 L7,1 z" fill="#000000" id="path-1"/>
|
||||
<path d="M12.55,4.45 L9.722,7.278" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-linecap="round" id="Line-Copy-2"/>
|
||||
<path d="M12.55,7.278 L9.722,4.45" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-linecap="round" id="Line-Copy-5"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 907 B |
11
src/skins/vector/img/icon_context_delete.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
|
||||
<g transform="matrix(1,0,0,1,-0,-80)">
|
||||
<g id="icon_context_delete" transform="matrix(0.600982,0,0,0.600982,0,80)">
|
||||
<g transform="matrix(1.66394,0,0,1.66394,0,-133.116)">
|
||||
<path d="M7.508,86.728C8.739,85.523 9.979,84.326 11.196,83.109C11.277,83.034 11.364,82.99 11.472,82.968C11.512,82.964 11.549,82.962 11.589,82.964C11.668,82.973 11.743,82.994 11.811,83.036C11.994,83.148 12.086,83.371 12.036,83.579C12.017,83.657 11.98,83.724 11.93,83.787C10.749,85.064 9.524,86.299 8.285,87.52C9.489,88.752 10.686,89.991 11.904,91.209C11.958,91.267 12.001,91.331 12.026,91.408C12.042,91.458 12.05,91.51 12.05,91.562C12.05,91.82 11.846,92.041 11.589,92.061C11.454,92.071 11.33,92.025 11.225,91.942C9.948,90.762 8.713,89.536 7.492,88.297C6.261,89.501 5.021,90.698 3.804,91.916C3.745,91.97 3.681,92.013 3.605,92.038C3.555,92.054 3.502,92.062 3.45,92.062C3.192,92.062 2.972,91.858 2.952,91.602C2.941,91.466 2.987,91.342 3.07,91.238C4.251,89.96 5.476,88.726 6.715,87.505C5.511,86.273 4.314,85.034 3.096,83.816C3.042,83.757 2.999,83.693 2.974,83.617C2.908,83.413 2.983,83.184 3.156,83.058C3.221,83.01 3.294,82.984 3.372,82.968C3.412,82.964 3.449,82.962 3.489,82.964C3.598,82.977 3.689,83.014 3.775,83.082C5.052,84.263 6.287,85.488 7.508,86.728Z" style="fill:rgb(255,0,100);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
12
src/skins/vector/img/icon_context_fave.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
|
||||
<g transform="matrix(1,0,0,1,-0,-40)">
|
||||
<g id="icon_context_fave" transform="matrix(0.600982,0,0,0.600982,0,40)">
|
||||
<g transform="matrix(1.66394,0,0,1.66394,1.66394,2.71716)">
|
||||
<rect x="0" y="0" width="13" height="13" style="fill:rgb(224,223,224);fill-opacity:0;fill-rule:nonzero;"/>
|
||||
<path d="M6.572,-0.495C6.614,-0.486 6.625,-0.486 6.666,-0.472C6.793,-0.427 6.884,-0.337 6.948,-0.221L8.742,3.414L12.754,3.997L12.801,4.006C12.88,4.029 12.951,4.062 13.013,4.117C13.161,4.248 13.218,4.459 13.157,4.646C13.132,4.725 13.087,4.789 13.031,4.849L10.128,7.679L10.813,11.674L10.819,11.722C10.821,11.804 10.812,11.882 10.779,11.958C10.7,12.139 10.517,12.259 10.32,12.259C10.237,12.259 10.162,12.236 10.088,12.201L6.5,10.315L2.912,12.201L2.868,12.222C2.791,12.249 2.714,12.264 2.631,12.256C2.435,12.237 2.265,12.1 2.204,11.913C2.178,11.834 2.177,11.756 2.187,11.674L2.872,7.679L-0.031,4.849L-0.064,4.814C-0.114,4.749 -0.152,4.681 -0.17,4.599C-0.213,4.407 -0.135,4.202 0.024,4.087C0.092,4.038 0.166,4.012 0.246,3.997L4.258,3.414L6.052,-0.221L6.075,-0.264C6.099,-0.299 6.104,-0.309 6.134,-0.34C6.211,-0.423 6.316,-0.478 6.428,-0.495C6.477,-0.502 6.523,-0.499 6.572,-0.495ZM5.038,4.092C5.017,4.13 5.013,4.14 4.987,4.174C4.928,4.251 4.847,4.31 4.755,4.342C4.715,4.357 4.704,4.357 4.662,4.365L1.393,4.841L3.758,7.146L3.791,7.182C3.817,7.216 3.825,7.224 3.846,7.261C3.903,7.364 3.916,7.474 3.902,7.589L3.343,10.845L6.267,9.307L6.311,9.287C6.42,9.249 6.531,9.237 6.643,9.271C6.684,9.283 6.694,9.289 6.733,9.307L9.657,10.845L9.098,7.589L9.092,7.541C9.089,7.425 9.113,7.317 9.18,7.22C9.204,7.185 9.213,7.178 9.242,7.146L11.607,4.841L8.338,4.365L8.291,4.356C8.25,4.344 8.239,4.342 8.2,4.324C8.093,4.275 8.018,4.193 7.962,4.092L6.5,1.13C6.013,2.117 5.525,3.105 5.038,4.092Z" style="fill:rgb(205,205,205);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
29
src/skins/vector/img/icon_context_fave_on.svg
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
|
||||
<g transform="matrix(1,0,0,1,-20,-40)">
|
||||
<g id="icon_context_fave_on" transform="matrix(0.600982,0,0,0.600982,20,40)">
|
||||
<g transform="matrix(1.66394,0,0,1.66394,-14.9755,2.71716)">
|
||||
<g transform="matrix(1,0,0,1,10.0123,0)">
|
||||
<clipPath id="_clip1">
|
||||
<rect x="-1" y="-1" width="15" height="15"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip1)">
|
||||
<g transform="matrix(0.575972,0,0,0.576771,2.73925,2.16505)">
|
||||
<rect x="-6" y="-6" width="25" height="25" style="fill:rgb(216,216,216);fill-opacity:0;fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<clipPath id="_clip2">
|
||||
<path d="M6.5,9.75L2.679,11.759L3.409,7.504L0.318,4.491L4.59,3.871L6.5,0L8.41,3.871L12.682,4.491L9.591,7.504L10.321,11.759L6.5,9.75Z"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip2)">
|
||||
<path d="M-0.682,-1L13.682,-1L13.682,12.759L-0.682,12.759L-0.682,-1Z" style="fill:rgb(74,74,74);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,10.0123,0)">
|
||||
<path d="M6.572,-0.495C6.614,-0.486 6.625,-0.486 6.666,-0.472C6.793,-0.427 6.884,-0.337 6.948,-0.221L8.742,3.414L12.754,3.997L12.801,4.006C12.88,4.029 12.951,4.062 13.013,4.117C13.161,4.248 13.218,4.459 13.157,4.646C13.132,4.725 13.087,4.789 13.031,4.849L10.128,7.679L10.813,11.674L10.819,11.722C10.821,11.804 10.812,11.882 10.779,11.958C10.7,12.139 10.517,12.259 10.32,12.259C10.237,12.259 10.162,12.236 10.088,12.201L6.5,10.315L2.912,12.201L2.868,12.222C2.791,12.249 2.714,12.264 2.631,12.256C2.435,12.237 2.265,12.1 2.204,11.913C2.178,11.834 2.177,11.756 2.187,11.674L2.872,7.679L-0.031,4.849L-0.064,4.814C-0.114,4.749 -0.152,4.681 -0.17,4.599C-0.213,4.407 -0.135,4.202 0.024,4.087C0.092,4.038 0.166,4.012 0.246,3.997L4.258,3.414L6.052,-0.221L6.075,-0.264C6.15,-0.372 6.25,-0.453 6.38,-0.485C6.422,-0.496 6.433,-0.495 6.476,-0.499C6.524,-0.499 6.524,-0.499 6.572,-0.495ZM5.038,4.092C5.017,4.13 5.013,4.14 4.987,4.174C4.928,4.251 4.847,4.31 4.755,4.342C4.715,4.357 4.704,4.357 4.662,4.365L1.393,4.841L3.758,7.146L3.791,7.182C3.861,7.273 3.906,7.375 3.909,7.492C3.91,7.536 3.907,7.546 3.902,7.589L3.343,10.845L6.267,9.307L6.311,9.287C6.42,9.249 6.531,9.237 6.643,9.271C6.684,9.283 6.694,9.289 6.733,9.307L9.657,10.845L9.098,7.589L9.092,7.541C9.091,7.498 9.089,7.487 9.095,7.444C9.109,7.328 9.163,7.231 9.242,7.146L11.607,4.841L8.338,4.365L8.291,4.356C8.18,4.323 8.084,4.267 8.013,4.174C7.987,4.14 7.983,4.13 7.962,4.092L6.5,1.13C6.013,2.117 5.525,3.105 5.038,4.092Z" style="fill:rgb(74,74,74);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
11
src/skins/vector/img/icon_context_low.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
|
||||
<g transform="matrix(1,0,0,1,-0,-60)">
|
||||
<g id="icon_context_fave" transform="matrix(0.600982,0,0,0.600982,0,60)">
|
||||
<g transform="matrix(1.66394,0,0,1.66394,1.66394,1.96327)">
|
||||
<path d="M8.737,0.502C8.882,0.514 9.02,0.542 9.155,0.598C9.544,0.759 9.832,1.105 9.958,1.503C10.008,1.664 10.03,1.829 10.033,1.998L10.033,6.5C10.63,6.5 11.226,6.491 11.822,6.501C11.882,6.504 11.882,6.504 11.942,6.51C12.067,6.527 12.188,6.556 12.301,6.614C12.494,6.715 12.636,6.904 12.665,7.122C12.682,7.246 12.662,7.376 12.613,7.492C12.541,7.662 12.419,7.799 12.282,7.921C10.713,9.244 9.104,10.519 7.515,11.818C7.423,11.889 7.328,11.952 7.223,12.003C6.836,12.19 6.376,12.215 5.969,12.079C5.814,12.028 5.673,11.951 5.539,11.857C3.901,10.585 2.306,9.258 0.72,7.921C0.583,7.798 0.46,7.66 0.389,7.488C0.284,7.235 0.332,6.938 0.528,6.743C0.596,6.676 0.678,6.622 0.766,6.585C0.915,6.521 1.077,6.503 1.238,6.5L2.967,6.5L2.967,1.998C2.968,1.927 2.968,1.928 2.973,1.858C2.991,1.692 3.025,1.532 3.088,1.378C3.229,1.035 3.495,0.744 3.84,0.6C3.975,0.543 4.116,0.515 4.262,0.502C5.753,0.459 7.246,0.46 8.737,0.502ZM4.343,1.5C4.313,1.501 4.285,1.503 4.256,1.511C4.096,1.559 4.003,1.732 3.977,1.886C3.972,1.915 3.969,1.944 3.967,1.973C3.932,3.648 3.967,5.324 3.967,7C3.964,7.063 3.956,7.122 3.933,7.181C3.877,7.326 3.753,7.438 3.603,7.481C3.558,7.494 3.514,7.498 3.467,7.5L1.784,7.5C3.234,8.685 4.656,9.904 6.134,11.053C6.16,11.071 6.187,11.087 6.215,11.102C6.433,11.202 6.7,11.184 6.892,11.035L11.219,7.5L9.533,7.5L9.487,7.498C9.441,7.491 9.397,7.483 9.353,7.466C9.223,7.416 9.118,7.311 9.067,7.181C9.05,7.137 9.042,7.093 9.035,7.046C8.957,5.357 9.069,3.663 9.033,1.972C9.021,1.793 8.941,1.581 8.757,1.516C8.732,1.507 8.707,1.503 8.68,1.501C7.235,1.46 5.789,1.5 4.343,1.5Z" style="fill:rgb(206,206,206);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
30
src/skins/vector/img/icon_context_low_on.svg
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
|
||||
<g transform="matrix(1,0,0,1,-20,-60)">
|
||||
<g id="icon_context_fave_on" transform="matrix(0.600982,0,0,0.600982,20,60)">
|
||||
<clipPath id="_clip1">
|
||||
<rect x="0" y="0" width="25" height="25"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip1)">
|
||||
<g transform="matrix(1.66394,0,0,1.66394,1.68116,1.96327)">
|
||||
<clipPath id="_clip2">
|
||||
<rect x="-1" y="-1" width="15" height="15"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip2)">
|
||||
<rect x="-6" y="-6" width="25" height="25" style="fill:rgb(74,74,74);fill-opacity:0;fill-rule:nonzero;"/>
|
||||
<clipPath id="_clip3">
|
||||
<path d="M11.76,7C12.241,7 12.307,7.257 11.919,7.574L7.204,11.426C6.813,11.745 6.187,11.743 5.8,11.426L1.084,7.574C0.694,7.255 0.767,7 1.243,7L3.467,7L3.467,2.003C3.467,1.449 3.846,1 4.336,1L8.664,1C9.144,1 9.533,1.438 9.533,2.003L9.533,7L11.76,7Z"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip3)">
|
||||
<rect x="-4.167" y="-4" width="21.338" height="20.665" style="fill:rgb(74,74,74);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1.66394,0,0,1.66394,1.68116,1.96327)">
|
||||
<path d="M8.737,0.502C8.882,0.514 9.02,0.542 9.155,0.598C9.544,0.759 9.832,1.105 9.958,1.503C10.008,1.664 10.03,1.829 10.033,1.998L10.033,6.5C10.63,6.5 11.226,6.491 11.822,6.501C11.882,6.504 11.882,6.504 11.942,6.51C12.067,6.527 12.188,6.556 12.301,6.614C12.494,6.715 12.636,6.904 12.665,7.122C12.682,7.246 12.662,7.376 12.613,7.492C12.541,7.662 12.419,7.799 12.282,7.921C10.713,9.244 9.104,10.519 7.515,11.818C7.423,11.889 7.328,11.952 7.223,12.003C6.836,12.19 6.376,12.215 5.969,12.079C5.814,12.028 5.673,11.951 5.539,11.857C3.901,10.585 2.306,9.258 0.72,7.921C0.583,7.798 0.46,7.66 0.389,7.488C0.284,7.235 0.332,6.938 0.528,6.743C0.596,6.676 0.678,6.622 0.766,6.585C0.915,6.521 1.077,6.503 1.238,6.5L2.967,6.5L2.967,1.998C2.968,1.927 2.968,1.928 2.973,1.858C2.991,1.692 3.025,1.532 3.088,1.378C3.229,1.035 3.495,0.744 3.84,0.6C3.975,0.543 4.116,0.515 4.262,0.502C5.753,0.459 7.246,0.46 8.737,0.502ZM4.343,1.5C4.313,1.501 4.285,1.503 4.256,1.511C4.096,1.559 4.003,1.732 3.977,1.886C3.972,1.915 3.969,1.944 3.967,1.973C3.932,3.648 3.967,5.324 3.967,7C3.964,7.047 3.96,7.091 3.948,7.137C3.905,7.286 3.792,7.41 3.647,7.466C3.588,7.489 3.529,7.497 3.467,7.5L1.784,7.5C3.234,8.685 4.656,9.904 6.134,11.053C6.16,11.071 6.187,11.087 6.215,11.102C6.433,11.202 6.7,11.184 6.892,11.035L11.219,7.5L9.533,7.5L9.487,7.498C9.441,7.491 9.397,7.483 9.353,7.466C9.223,7.416 9.118,7.311 9.067,7.181C9.05,7.137 9.042,7.093 9.035,7.046C8.957,5.357 9.069,3.663 9.033,1.972C9.021,1.793 8.941,1.581 8.757,1.516C8.732,1.507 8.707,1.503 8.68,1.501C7.235,1.46 5.789,1.5 4.343,1.5Z" style="fill:rgb(74,74,74);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -1,20 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: sketchtool 3.5.1 (25234) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>icons_create_room</title>
|
||||
<svg width="25px" height="25px" viewBox="0 0 25 25" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 3.8.3 (29802) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>0F9BCC43-B3A7-4C9F-8E34-1F38194362C2</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="03-Input" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="03_4-Uploading" sketch:type="MSArtboardGroup" transform="translate(-20.000000, -726.000000)">
|
||||
<g id="Room-list" sketch:type="MSLayerGroup">
|
||||
<g id="Room-list/Footer" transform="translate(0.000000, 708.000000)" sketch:type="MSShapeGroup">
|
||||
<g id="icons_create_room" transform="translate(20.000000, 18.000000)">
|
||||
<circle id="Oval-1-Copy-7" fill="#76CFA6" cx="12" cy="12" r="12"></circle>
|
||||
<path d="M7,12 L17,12" id="Line" stroke="#FFFFFF" stroke-width="2" stroke-linecap="round"></path>
|
||||
<path d="M12,7 L12,17" id="Line" stroke="#FFFFFF" stroke-width="2" stroke-linecap="round"></path>
|
||||
</g>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Room-list-Copy-3" transform="translate(-21.000000, -726.000000)">
|
||||
<g id="icons_create_room" transform="translate(21.000000, 726.000000)">
|
||||
<path d="M12.5,25 C19.4035594,25 25,19.4035594 25,12.5 C25,5.59644063 19.4035594,0 12.5,0 C5.59644063,0 0,5.59644063 0,12.5 C0,19.4035594 5.59644063,25 12.5,25 Z" id="Oval-1-Copy-7" fill="#76CFA6"></path>
|
||||
<g id="Group-3" opacity="0.8" transform="translate(6.000000, 6.000000)" stroke="#FFFFFF" stroke-linecap="round">
|
||||
<path d="M0,6.5 L13,6.5" id="Line"></path>
|
||||
<path d="M6.5,0 L6.5,13" id="Line"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -1,21 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: sketchtool 3.5.1 (25234) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>icons_directory</title>
|
||||
<svg width="25px" height="25px" viewBox="0 0 25 25" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 3.8.3 (29802) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>E34C64ED-EBD7-49B6-BDD9-CB729162705A</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="03-Input" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="03_4-Uploading" sketch:type="MSArtboardGroup" transform="translate(-54.000000, -726.000000)">
|
||||
<g id="Room-list" sketch:type="MSLayerGroup">
|
||||
<g id="Room-list/Footer" transform="translate(0.000000, 708.000000)" sketch:type="MSShapeGroup">
|
||||
<g id="icons_directory" transform="translate(54.000000, 18.000000)">
|
||||
<ellipse id="Oval-1-Copy-7" fill="#76CFA6" cx="12.48" cy="12" rx="11.52" ry="12"></ellipse>
|
||||
<path d="M10.919715,8.29307518 C10.8407601,8.29307518 10.7883135,8.12984737 10.7170546,7.88143019 C10.616152,7.53041266 10.4645131,7 9.9312114,7 L7.38327791,7 C7.02270784,7 6.73168646,7.30842284 6.72057007,7.70887507 L6.72,17.2758903 C6.72,17.6754098 7.01786223,18 7.38327791,18 L17.5770071,18 C17.9424228,18 18.24,17.6754098 18.24,17.2758903 L18.24,9.01687394 C18.24,8.61766535 17.9424228,8.29307518 17.5770071,8.29307518 L10.919715,8.29307518 Z M17.28,16.7470688 C17.28,16.8865013 17.1755713,17 17.0471522,17 L6.95341227,17 C6.82499318,17 6.72,16.8865013 6.72,16.7470688 L6.72056448,10 L17.28,10 L17.28,16.7470688 L17.28,16.7470688 Z M17.28,9 L6.72,9 L6.72,7.20209147 C6.72395157,7.0886985 6.82641007,7 6.95286024,7 L9.47593617,7 C9.67210328,7 9.74040895,7.13682752 9.84964157,7.44903616 C9.93826959,7.70177649 10.0596392,8.04800302 10.4547959,8.04800302 L17.0471398,8.04800302 C17.1755657,8.04800302 17.28,8.14148923 17.28,8.25664609 L17.28,9 L17.28,9 Z" id="Fill-137"></path>
|
||||
<path d="M18,17 C18,16.8865013 17.8912201,17 18,17 L7,17 C7.1093679,17 7,16.8865013 7,17 L7,10 L18,10 L18,17 L18,17 Z" id="Path-Copy-2" fill="#FFFFFF"></path>
|
||||
<path d="M7,9 L7,7 C7.00411622,7.0886985 7.11084382,7 7,7 L10,7 C10.0751076,7 10.1462593,7.13682752 10,7 C10.3523642,7.70177649 10.4787908,8.04800302 11,8 L18,8 C17.8912143,8.04800302 18,8.14148923 18,8 L18,9 L7,9 Z" id="Path-Copy" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<rect id="path-1" x="6" y="10" width="13" height="8" rx="1"></rect>
|
||||
<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="13" height="8" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Room-list-Copy-3" transform="translate(-58.000000, -726.000000)">
|
||||
<g id="icons_directory" transform="translate(58.000000, 726.000000)">
|
||||
<path d="M12.5,25 C19.4035594,25 25,19.4035594 25,12.5 C25,5.59644063 19.4035594,0 12.5,0 C5.59644063,0 0,5.59644063 0,12.5 C0,19.4035594 5.59644063,25 12.5,25 Z" id="Oval-1-Copy-7" fill="#76CFA6"></path>
|
||||
<use id="Rectangle-9" stroke="#FFFFFF" mask="url(#mask-2)" stroke-width="2" opacity="0.8" xlink:href="#path-1"></use>
|
||||
<path d="M6,9 L6,6.99895656 C6,6.44724809 6.45097518,6 6.99077797,6 L11.009222,6 C11.5564136,6 12,6.44386482 12,7 L12,8 L17.9970707,8 C18.5509732,8 19,8.45318604 19,9 L19,9 L6,9 Z" id="Path-Copy" fill="#FFFFFF" opacity="0.6"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.5 KiB |
9
src/skins/vector/img/icons-people.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="25" height="25" viewBox="0, 0, 25, 25">
|
||||
<g id="Symbols">
|
||||
<path d="M12.5,25 C19.404,25 25,19.404 25,12.5 C25,5.596 19.404,0 12.5,0 C5.596,0 0,5.596 0,12.5 C0,19.404 5.596,25 12.5,25 z" fill="#76CFA6" id="Oval-1-Copy-7"/>
|
||||
<path d="M12.5,11.439 C13.881,11.439 15,10.32 15,8.939 C15,7.558 13.881,6.439 12.5,6.439 C11.119,6.439 10,7.558 10,8.939 C10,10.32 11.119,11.439 12.5,11.439 z" fill-opacity="0" stroke="#FFFFFF" stroke-width="1" id="path-1" opacity="0.8"/>
|
||||
<path d="M17.89,19 C17.89,15.134 17.89,12 12.445,12 C6.999,12 6.999,15.134 6.999,19 C10.785,19 13.067,19 17.89,19 z" fill-opacity="0" stroke="#FFFFFF" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" id="path-3" opacity="0.8"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 984 B |
10
src/skins/vector/img/icons-search-copy.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="13" height="13" viewBox="0, 0, 13, 13">
|
||||
<g id="Symbols">
|
||||
<g>
|
||||
<path d="M10.229,5.547 C10.229,8.133 8.133,10.229 5.547,10.229 C2.961,10.229 0.865,8.133 0.865,5.547 C0.865,2.961 2.961,0.865 5.547,0.865 C8.133,0.865 10.229,2.961 10.229,5.547 z" fill-opacity="0" stroke="#76CFA6" stroke-width="1" stroke-linecap="round" id="path-1" opacity="0.7"/>
|
||||
<path d="M8.824,8.824 L12.135,12.135" fill-opacity="0" stroke="#76CFA6" stroke-width="1" stroke-linecap="round" id="Line" opacity="0.7"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 776 B |
9
src/skins/vector/img/icons-search.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="35" height="35" viewBox="0, 0, 35, 35">
|
||||
<g id="Symbols">
|
||||
<path d="M17.5,35 C27.165,35 35,27.165 35,17.5 C35,7.835 27.165,0 17.5,0 C7.835,0 0,7.835 0,17.5 C0,27.165 7.835,35 17.5,35 z" fill="#EAF5F0" id="Oval-1-Copy-7"/>
|
||||
<path d="M22.4,15.4 C22.4,19.266 19.266,22.4 15.4,22.4 C11.534,22.4 8.4,19.266 8.4,15.4 C8.4,11.534 11.534,8.4 15.4,8.4 C19.266,8.4 22.4,11.534 22.4,15.4 z" fill-opacity="0" stroke="#76CFA6" stroke-width="1" stroke-linecap="round" id="path-1" opacity="0.7"/>
|
||||
<path d="M20.3,20.3 L25.25,25.25" fill-opacity="0" stroke="#76CFA6" stroke-width="1" stroke-linecap="round" id="Line" opacity="0.7"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 895 B |
15
src/skins/vector/img/icons-settings-room.svg
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
@@ -1,17 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: sketchtool 3.5.1 (25234) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>icons_settings</title>
|
||||
<svg width="25px" height="25px" viewBox="0 0 25 25" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 3.8.3 (29802) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>4D42A2A7-7430-4D4F-A0A2-E19278CF66E3</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="09-Invitations-and-joining" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="09_1-Invite-members" sketch:type="MSArtboardGroup" transform="translate(-886.000000, -25.000000)">
|
||||
<g id="Room-header" sketch:type="MSLayerGroup" transform="translate(210.000000, 0.000000)">
|
||||
<g id="icons_settings" transform="translate(676.000000, 25.000000)" sketch:type="MSShapeGroup">
|
||||
<circle id="Oval-1-Copy-7" fill="#76CFA6" cx="12" cy="12" r="12"></circle>
|
||||
<path d="M15,12 C15,11.1718709 14.7070342,10.4648467 14.1210938,9.87890625 C13.5351533,9.29296582 12.8281291,9 12,9 C11.1718709,9 10.4648467,9.29296582 9.87890625,9.87890625 C9.29296582,10.4648467 9,11.1718709 9,12 C9,12.8281291 9.29296582,13.5351533 9.87890625,14.1210938 C10.4648467,14.7070342 11.1718709,15 12,15 C12.8281291,15 13.5351533,14.7070342 14.1210938,14.1210938 C14.7070342,13.5351533 15,12.8281291 15,12 L15,12 Z M19,11.0065104 L19,13.0299479 C19,13.1028649 18.9756947,13.1727427 18.9270833,13.2395833 C18.878472,13.3064239 18.8177087,13.3459201 18.7447917,13.3580729 L17.0585938,13.6132812 C16.9431418,13.9414079 16.8246534,14.2178808 16.703125,14.4427083 C16.9157997,14.7465293 17.2408832,15.1657959 17.6783854,15.7005208 C17.7391496,15.7734379 17.7695312,15.849392 17.7695312,15.9283854 C17.7695312,16.0073789 17.7421878,16.0772566 17.6875,16.1380208 C17.5234367,16.3628483 17.2226584,16.6909701 16.7851562,17.1223958 C16.3476541,17.5538216 16.0620666,17.7695312 15.9283854,17.7695312 C15.8554684,17.7695312 15.7764761,17.7421878 15.6914062,17.6875 L14.4335938,16.703125 C14.1662313,16.8428826 13.8897584,16.9583329 13.6041667,17.0494792 C13.506944,17.8758722 13.4188372,18.4409707 13.3398438,18.7447917 C13.2973088,18.9149314 13.1879349,19 13.0117188,19 L10.9882812,19 C10.9032114,19 10.8287764,18.9741756 10.764974,18.922526 C10.7011716,18.8708765 10.6662327,18.805556 10.6601562,18.7265625 L10.4049479,17.0494792 C10.1072034,16.9522565 9.83376861,16.8398444 9.58463542,16.7122396 L8.29947917,17.6875 C8.23871497,17.7421878 8.16276087,17.7695312 8.07161458,17.7695312 C7.98654471,17.7695312 7.91059061,17.7361114 7.84375,17.6692708 C7.07812117,16.976559 6.5768241,16.4661475 6.33984375,16.1380208 C6.29730882,16.0772566 6.27604167,16.0073789 6.27604167,15.9283854 C6.27604167,15.8554684 6.30034698,15.7855906 6.34895833,15.71875 C6.44010462,15.5911452 6.59505099,15.3891073 6.81380208,15.1126302 C7.03255318,14.8361531 7.19661404,14.6219626 7.30598958,14.4700521 C7.14192626,14.1662311 7.01736154,13.8654529 6.93229167,13.5677083 L5.26432292,13.3216146 C5.18532947,13.3094617 5.12152802,13.2714847 5.07291667,13.2076823 C5.02430531,13.1438799 5,13.072483 5,12.9934896 L5,10.9700521 C5,10.8971351 5.02430531,10.8272573 5.07291667,10.7604167 C5.12152802,10.6935761 5.17925314,10.6540799 5.24609375,10.6419271 L6.94140625,10.3867188 C7.02647612,10.1072035 7.14496452,9.82769237 7.296875,9.54817708 C7.05381823,9.20182118 6.72873467,8.78255454 6.32161458,8.29036458 C6.26085039,8.21744755 6.23046875,8.14453161 6.23046875,8.07161458 C6.23046875,8.01085039 6.25781223,7.94097262 6.3125,7.86197917 C6.4704869,7.64322807 6.76974606,7.31662544 7.21028646,6.88216146 C7.65082686,6.44769748 7.93793336,6.23046875 8.07161458,6.23046875 C8.15060803,6.23046875 8.2296003,6.26085039 8.30859375,6.32161458 L9.56640625,7.296875 C9.8337687,7.15711736 10.1102416,7.04166712 10.3958333,6.95052083 C10.493056,6.12412781 10.5811628,5.5590293 10.6601562,5.25520833 C10.7026912,5.08506859 10.8120651,5 10.9882812,5 L13.0117188,5 C13.0967886,5 13.1712236,5.02582439 13.235026,5.07747396 C13.2988284,5.12912352 13.3337673,5.19444405 13.3398438,5.2734375 L13.5950521,6.95052083 C13.8927966,7.04774354 14.1662314,7.16015561 14.4153646,7.28776042 L15.7096354,6.3125 C15.7643232,6.25781223 15.8372391,6.23046875 15.9283854,6.23046875 C16.0073789,6.23046875 16.083333,6.26085039 16.15625,6.32161458 C16.9401081,7.04470848 17.4414052,7.56119637 17.6601562,7.87109375 C17.7026912,7.9197051 17.7239583,7.98654471 17.7239583,8.07161458 C17.7239583,8.14453161 17.699653,8.21440939 17.6510417,8.28125 C17.5598954,8.4088548 17.404949,8.61089271 17.1861979,8.88736979 C16.9674468,9.16384687 16.803386,9.37803743 16.6940104,9.52994792 C16.8519973,9.83376888 16.976562,10.131509 17.0677083,10.4231771 L18.7356771,10.6783854 C18.8146705,10.6905383 18.878472,10.7285153 18.9270833,10.7923177 C18.9756947,10.8561201 19,10.927517 19,11.0065104 L19,11.0065104 Z" id="icons_settings-copy" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Room-list-Copy-3" transform="translate(-165.000000, -726.000000)">
|
||||
<g id="icons_settings" transform="translate(165.000000, 726.000000)">
|
||||
<path d="M12.5,25 C19.4035594,25 25,19.4035594 25,12.5 C25,5.59644063 19.4035594,0 12.5,0 C5.59644063,0 0,5.59644063 0,12.5 C0,19.4035594 5.59644063,25 12.5,25 Z" id="Oval-1-Copy-7" fill="#76CFA6"></path>
|
||||
<path d="M15.625,12.5 C15.625,11.6373655 15.3198273,10.900882 14.7094727,10.2905273 C14.099118,9.68017273 13.3626345,9.375 12.5,9.375 C11.6373655,9.375 10.900882,9.68017273 10.2905273,10.2905273 C9.68017273,10.900882 9.375,11.6373655 9.375,12.5 C9.375,13.3626345 9.68017273,14.099118 10.2905273,14.7094727 C10.900882,15.3198273 11.6373655,15.625 12.5,15.625 C13.3626345,15.625 14.099118,15.3198273 14.7094727,14.7094727 C15.3198273,14.099118 15.625,13.3626345 15.625,12.5 L15.625,12.5 Z M19.7916667,11.465115 L19.7916667,13.5728624 C19.7916667,13.6488177 19.7663486,13.721607 19.7157118,13.7912326 C19.665075,13.8608583 19.6017799,13.9020001 19.5258247,13.9146593 L17.7693685,14.1805013 C17.649106,14.5222999 17.5256806,14.8102925 17.3990885,15.0444878 C17.6206247,15.360968 17.9592534,15.7977041 18.4149848,16.3547092 C18.4782808,16.4306644 18.5099284,16.5097833 18.5099284,16.5920681 C18.5099284,16.674353 18.4814456,16.7471423 18.4244792,16.8104384 C18.2535799,17.0446337 17.9402692,17.3864272 17.4845378,17.835829 C17.0288063,18.2852308 16.7313194,18.5099284 16.5920681,18.5099284 C16.5161129,18.5099284 16.4338293,18.4814456 16.3452148,18.4244792 L15.0349935,17.3990885 C14.7564909,17.5446694 14.4684983,17.6649301 14.1710069,17.7598741 C14.0697333,18.6207002 13.9779554,19.2093445 13.8956706,19.5258247 C13.8513633,19.7030535 13.7374322,19.7916667 13.5538737,19.7916667 L11.4461263,19.7916667 C11.3575119,19.7916667 11.2799754,19.7647663 11.2135145,19.7109646 C11.1470537,19.657163 11.110659,19.5891208 11.1043294,19.5068359 L10.8384874,17.7598741 C10.5283368,17.6586005 10.243509,17.5415046 9.98399523,17.4085829 L8.6452908,18.4244792 C8.58199476,18.4814456 8.50287591,18.5099284 8.40793186,18.5099284 C8.31931741,18.5099284 8.24019855,18.4751161 8.17057292,18.4054905 C7.37304289,17.6839157 6.85085844,17.152237 6.60400391,16.8104384 C6.55969668,16.7471423 6.5375434,16.674353 6.5375434,16.5920681 C6.5375434,16.5161129 6.56286144,16.4433236 6.61349826,16.3736979 C6.70844231,16.2407762 6.86984478,16.0303201 7.0977105,15.7423231 C7.32557623,15.4543262 7.49647295,15.231211 7.61040582,15.0729709 C7.43950652,14.7564907 7.3097516,14.4431801 7.22113715,14.1330295 L5.4836697,13.8766819 C5.40138486,13.8640227 5.33492502,13.8244632 5.28428819,13.7580024 C5.23365137,13.6915416 5.20833333,13.6171698 5.20833333,13.534885 L5.20833333,11.4271376 C5.20833333,11.3511823 5.23365137,11.278393 5.28428819,11.2087674 C5.33492502,11.1391417 5.39505535,11.0979999 5.46468099,11.0853407 L7.23063151,10.8194987 C7.31924596,10.5283369 7.44267137,10.2371796 7.60091146,9.9460178 C7.34772732,9.5852304 7.00909862,9.14849432 6.58501519,8.63579644 C6.52171916,8.5598412 6.49007161,8.4838871 6.49007161,8.40793186 C6.49007161,8.34463582 6.5185544,8.27184648 6.57552083,8.18956163 C6.74009052,7.96169591 7.05181881,7.62148483 7.51071506,7.16891819 C7.96961131,6.71635154 8.26868058,6.49007161 8.40793186,6.49007161 C8.4902167,6.49007161 8.57250031,6.52171916 8.65478516,6.58501519 L9.96500651,7.60091146 C10.2435091,7.45533058 10.5315017,7.33506992 10.8289931,7.24012587 C10.9302667,6.3792998 11.0220446,5.79065552 11.1043294,5.47417535 C11.1486367,5.29694645 11.2625678,5.20833333 11.4461263,5.20833333 L13.5538737,5.20833333 C13.6424881,5.20833333 13.7200246,5.23523374 13.7864855,5.28903537 C13.8529463,5.342837 13.889341,5.41087922 13.8956706,5.49316406 L14.1615126,7.24012587 C14.4716632,7.34139952 14.756491,7.45849543 15.0160048,7.5914171 L16.3642036,6.57552083 C16.42117,6.5185544 16.4971241,6.49007161 16.5920681,6.49007161 C16.674353,6.49007161 16.7534718,6.52171916 16.8294271,6.58501519 C17.6459459,7.338238 18.1681304,7.87624622 18.3959961,8.19905599 C18.4403033,8.24969282 18.4624566,8.31931741 18.4624566,8.40793186 C18.4624566,8.4838871 18.4371386,8.55667645 18.3865017,8.62630208 C18.2915577,8.75922375 18.1301552,8.96967991 17.9022895,9.25767687 C17.6744238,9.54567382 17.503527,9.76878899 17.3895942,9.92702908 C17.5541639,10.2435093 17.6839188,10.5536552 17.7788628,10.8574761 L19.5163303,11.1233181 C19.5986151,11.1359773 19.665075,11.1755368 19.7157118,11.2419976 C19.7663486,11.3084584 19.7916667,11.3828302 19.7916667,11.465115 L19.7916667,11.465115 Z" id="icons_settings-copy" stroke="#FFFFFF" opacity="0.8"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 5.0 KiB |
12
src/skins/vector/img/icons-upload.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="35" height="35" viewBox="0, 0, 35, 35">
|
||||
<g id="Symbols">
|
||||
<path d="M17.5,35 C27.165,35 35,27.165 35,17.5 C35,7.835 27.165,0 17.5,0 C7.835,0 0,7.835 0,17.5 C0,27.165 7.835,35 17.5,35 z" fill="#EAF5F0" id="Oval-109-Copy"/>
|
||||
<g id="file">
|
||||
<path d="M10,10.01 C10,7.795 11.782,6 14.004,6 L18.402,6 C18.402,6 25,12.492 25,12.492 L25,24.006 C25,26.212 23.206,28 21,28 L14,28 C11.791,28 10,26.2 10,23.99 L10,10.01 z" fill-opacity="0" stroke="#76CFA6" stroke-width="1" id="path-1"/>
|
||||
<path d="M25,13 L20.157,13 C18.966,13 18,12.034 18,10.843 L18,6" fill-opacity="0" stroke="#76CFA6" stroke-width="1" id="path-3"/>
|
||||
</g>
|
||||
<path d="M21.479,19.066 C21.612,19.066 21.746,19.015 21.848,18.912 C22.051,18.706 22.051,18.374 21.848,18.168 L17.871,14.154 C17.668,13.948 17.338,13.949 17.135,14.153 L13.153,18.162 C12.95,18.367 12.949,18.701 13.152,18.906 C13.355,19.113 13.685,19.113 13.888,18.908 L16.987,15.788 L16.988,24.474 C16.988,24.764 17.222,25 17.509,25 C17.798,25 18.03,24.764 18.03,24.474 L18.029,15.801 L21.111,18.912 C21.212,19.015 21.345,19.066 21.479,19.066 L21.479,19.066 z" fill="#76CFA6" id="Fill-75"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
20
src/skins/vector/img/icons-video.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>05D354CE-86A7-4B6F-B9BE-F1CEBBD81B21</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="Extra-icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Extra-icons-sheet" transform="translate(-542.000000, -366.000000)">
|
||||
<g id="icons_video" transform="translate(542.000000, 366.000000)">
|
||||
<path d="M17.5,35 C27.1649831,35 35,27.1649831 35,17.5 C35,7.83501688 27.1649831,0 17.5,0 C7.83501688,0 0,7.83501688 0,17.5 C0,27.1649831 7.83501688,35 17.5,35 Z" id="Oval-109-Copy-2" fill="#EAF5F0"></path>
|
||||
<g transform="translate(9.000000, 9.000000)" id="Rectangle-20-+-Path-16" stroke="#76CFA6">
|
||||
<g>
|
||||
<rect id="Rectangle-20" x="0" y="0" width="13" height="17" rx="4"></rect>
|
||||
<path d="M13,8.50795206 C13,11.2533934 15.8192656,12.6412404 15.8192656,12.6412404 C16.8995921,13.391019 17.7753697,12.9258617 17.7753697,11.6159552 L17.7753697,5.39994895 C17.7753697,4.08392094 16.8771592,3.5920349 15.8192656,4.37466376 C15.8192656,4.37466376 13,5.76251076 13,8.50795206 Z" id="Path-16"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
1
src/skins/vector/img/icons_ellipsis.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 25 25" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"><path d="M7.831,13.382c0.504,0 0.826,-0.378 0.826,-0.882c0,-0.518 -0.322,-0.882 -0.826,-0.882c-0.49,0 -0.826,0.364 -0.826,0.882c-0.014,0.504 0.336,0.882 0.826,0.882ZM12.493,13.382c0.504,0 0.84,-0.378 0.84,-0.882c-0.014,-0.518 -0.336,-0.882 -0.826,-0.882c-0.49,0 -0.84,0.364 -0.84,0.882c-0.014,0.504 0.336,0.882 0.826,0.882ZM17.155,13.382c0.518,0 0.84,-0.378 0.84,-0.882c0,-0.518 -0.336,-0.882 -0.826,-0.882c-0.49,0 -0.84,0.364 -0.84,0.882c0,0.504 0.336,0.882 0.826,0.882Z" style="fill:#fff;"/></svg>
|
||||
|
After Width: | Height: | Size: 910 B |
|
Before Width: | Height: | Size: 729 B |
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="17px" height="22px" viewBox="0 0 17 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: bin/sketchtool 1.4 (305) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>icons_people</title>
|
||||
<desc>Created with bin/sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="02-Chat" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="02_13-Chat-member-profile" sketch:type="MSArtboardGroup" transform="translate(-978.000000, -32.000000)" fill="#76CFA6">
|
||||
<g id="icons_people" sketch:type="MSLayerGroup" transform="translate(978.000000, 32.000000)">
|
||||
<path d="M7.79396172,11.1845854 C10.8910264,11.1845854 13.4110283,8.6755122 13.4110283,5.59121951 C13.4110283,2.50853659 10.8910264,0 7.79396172,0 C4.69851351,0 2.18012797,2.50853659 2.18012797,5.59121951 C2.18012797,8.6755122 4.69851351,11.1845854 7.79396172,11.1845854 L7.79396172,11.1845854 Z M7.79396172,0.804878049 C10.4454327,0.804878049 12.6028173,2.95229268 12.6028173,5.59121951 C12.6028173,8.2317561 10.4454327,10.3797073 7.79396172,10.3797073 C5.14410719,10.3797073 2.98833899,8.2317561 2.98833899,5.59121951 C2.98833899,2.95229268 5.14410719,0.804878049 7.79396172,0.804878049 L7.79396172,0.804878049 Z M0.885806936,21.4634146 C1.33849039,19.4978231 2.46183493,15.4298815 3.13651101,14.4663415 C4.32835286,12.76 6.45287023,12.8072195 6.48358225,12.8034634 L9.03699027,12.8013171 C9.06393064,12.7980976 11.7369539,12.5421463 12.9228689,14.5377073 C12.9320286,14.5532683 12.9422659,14.5682927 12.9535809,14.5827805 C13.6376414,15.4425239 14.755176,19.1307382 15.2598605,21.1908293 L15.2598605,21.1908293 L14.9096797,21.1908293 L1.53746094,21.1908293 L1.15172387,21.1908293 L1.15172387,21.9957073 L1.53746094,21.9957073 L14.9096797,21.9957073 L15.2954167,21.9957073 L15.2954167,21.3375005 C15.3143567,21.416496 15.3322794,21.4927245 15.3491183,21.5659024 C15.3922229,21.7520976 15.5587144,21.8781951 15.7429865,21.8781951 C15.7726209,21.8781951 15.8027941,21.8749756 15.8335061,21.8685366 C16.0506455,21.8186341 16.1869638,21.6029268 16.1368547,21.3856098 C15.7844747,19.8558049 14.5355192,15.312 13.6044602,14.1052195 C12.144831,11.6825366 9.08063366,11.9857073 8.99388568,11.9985854 L6.49759124,11.9985854 C6.38767454,11.996439 3.92209212,11.9320488 2.47323917,14.0059512 C1.66987741,15.1531707 0.489889321,19.5553171 0.0750076642,21.3872195 C0.0254373883,21.6045366 0.162294454,21.8197073 0.379972623,21.8685366 C0.460649718,21.8870317 0.541104777,21.8798767 0.61291652,21.8524806 L0.61291652,22 L1.15172387,22 L1.15172387,21.4634146 L0.885804128,21.4634146 Z" id="Fill-92" sketch:type="MSShapeGroup"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.8 KiB |
20
src/skins/vector/img/notif-active.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="13px" height="13px" viewBox="0 0 13 13" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>E15782FC-B5FA-472A-AE12-CFFF484E7253</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="Screens-revised" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Left-Panel-mention-states" transform="translate(-221.000000, -165.000000)">
|
||||
<g id="notification-shortcuts" transform="translate(206.000000, 119.000000)">
|
||||
<g id="slider" transform="translate(16.000000, 16.000000)">
|
||||
<g id="notif_active" transform="translate(0.000000, 31.000000)">
|
||||
<circle id="Oval-190" stroke="#62A887" fill="#76CFA6" cx="5.5" cy="5.5" r="5.5"></circle>
|
||||
<path d="M2.5,6.5 L4,8" id="Line" stroke="#FFFFFF" stroke-linecap="round"></path>
|
||||
<path d="M4,2.97753906 L8.30664062,8" id="Line-Copy" stroke="#FFFFFF" stroke-linecap="round" transform="translate(6.153320, 5.488770) scale(-1, 1) translate(-6.153320, -5.488770) "></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
22
src/skins/vector/img/notif-slider.svg
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="7px" height="109px" viewBox="0 0 7 109" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>16CB4618-0BD3-4568-BB20-FC56EBC46046</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="Screens-revised" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.2">
|
||||
<g id="Left-Panel-mention-states" transform="translate(-224.000000, -134.000000)" stroke="#000000">
|
||||
<g id="notification-shortcuts" transform="translate(206.000000, 119.000000)">
|
||||
<g id="slider" transform="translate(16.000000, 16.000000)">
|
||||
<g id="notif_slider" transform="translate(3.000000, 0.000000)">
|
||||
<path d="M2.5,3.49505001 L2.5,104.507355" id="Line" stroke-linecap="square"></path>
|
||||
<circle id="Oval-187" fill="#F7F7F7" cx="2.5" cy="36.5" r="2.5"></circle>
|
||||
<path d="M2.5,73 C3.88071187,73 5,71.8807119 5,70.5 C5,69.1192881 3.88071187,68 2.5,68 C1.11928813,68 0,69.1192881 0,70.5 C0,71.8807119 1.11928813,73 2.5,73 Z" id="Oval-187-Copy" fill="#F7F7F7"></path>
|
||||
<path d="M2.5,5 C3.88071187,5 5,3.88071187 5,2.5 C5,1.11928813 3.88071187,0 2.5,0 C1.11928813,0 0,1.11928813 0,2.5 C0,3.88071187 1.11928813,5 2.5,5 Z" id="Oval-187-Copy-3" fill="#F7F7F7"></path>
|
||||
<circle id="Oval-187-Copy-2" fill="#F7F7F7" cx="2.5" cy="104.5" r="2.5"></circle>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -26,6 +26,7 @@ require('../../vector/components.css');
|
||||
require('gemini-scrollbar/gemini-scrollbar.css');
|
||||
require('gfm.css/gfm.css');
|
||||
require('highlight.js/styles/github.css');
|
||||
require('draft-js/dist/Draft.css');
|
||||
|
||||
|
||||
// add React and ReactPerf to the global namespace, to make them easier to
|
||||
@@ -40,10 +41,12 @@ var ReactDOM = require("react-dom");
|
||||
var sdk = require("matrix-react-sdk");
|
||||
sdk.loadSkin(require('../component-index'));
|
||||
var VectorConferenceHandler = require('../VectorConferenceHandler');
|
||||
var configJson = require("../../config.json");
|
||||
var UpdateChecker = require("./updater");
|
||||
var q = require('q');
|
||||
var request = require('browser-request');
|
||||
import url from 'url';
|
||||
|
||||
var qs = require("querystring");
|
||||
import {parseQs, parseQsFromFragment} from './url_utils';
|
||||
|
||||
var lastLocationHashSet = null;
|
||||
|
||||
@@ -79,46 +82,12 @@ var validBrowser = checkBrowserFeatures([
|
||||
"objectfit"
|
||||
]);
|
||||
|
||||
// We want to support some name / value pairs in the fragment
|
||||
// so we're re-using query string like format
|
||||
//
|
||||
// returns {location, params}
|
||||
function parseQsFromFragment(location) {
|
||||
// if we have a fragment, it will start with '#', which we need to drop.
|
||||
// (if we don't, this will return '').
|
||||
var fragment = location.hash.substring(1);
|
||||
|
||||
// our fragment may contain a query-param-like section. we need to fish
|
||||
// this out *before* URI-decoding because the params may contain ? and &
|
||||
// characters which are only URI-encoded once.
|
||||
var hashparts = fragment.split('?');
|
||||
|
||||
var result = {
|
||||
location: decodeURIComponent(hashparts[0]),
|
||||
params: {}
|
||||
};
|
||||
|
||||
if (hashparts.length > 1) {
|
||||
result.params = qs.parse(hashparts[1]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseQs(location) {
|
||||
return qs.parse(location.search.substring(1));
|
||||
}
|
||||
|
||||
// Here, we do some crude URL analysis to allow
|
||||
// deep-linking.
|
||||
function routeUrl(location) {
|
||||
console.log("Routing URL "+window.location);
|
||||
var params = parseQs(location);
|
||||
var loginToken = params.loginToken;
|
||||
if (loginToken) {
|
||||
window.matrixChat.showScreen('token_login', params);
|
||||
return;
|
||||
}
|
||||
if (!window.matrixChat) return;
|
||||
|
||||
console.log("Routing URL "+location);
|
||||
var fragparts = parseQsFromFragment(location);
|
||||
window.matrixChat.showScreen(fragparts.location.substring(1),
|
||||
fragparts.params);
|
||||
@@ -181,32 +150,95 @@ window.onload = function() {
|
||||
}
|
||||
}
|
||||
|
||||
function loadApp() {
|
||||
if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
|
||||
if (confirm("Vector runs much better as an app on iOS. Get the app?")) {
|
||||
window.location = "https://itunes.apple.com/us/app/vector.im/id1083446067";
|
||||
return;
|
||||
function getConfig() {
|
||||
let deferred = q.defer();
|
||||
|
||||
request(
|
||||
{ method: "GET", url: "config.json", json: true },
|
||||
(err, response, body) => {
|
||||
if (err || response.status < 200 || response.status >= 300) {
|
||||
deferred.reject({err: err, response: response});
|
||||
return;
|
||||
}
|
||||
|
||||
deferred.resolve(body);
|
||||
}
|
||||
);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function onLoadCompleted() {
|
||||
// if we did a token login, we're now left with the token, hs and is
|
||||
// url as query params in the url; a little nasty but let's redirect to
|
||||
// clear them.
|
||||
if (window.location.search) {
|
||||
var parsedUrl = url.parse(window.location.href);
|
||||
parsedUrl.search = "";
|
||||
var formatted = url.format(parsedUrl);
|
||||
console.log("Redirecting to " + formatted + " to drop loginToken " +
|
||||
"from queryparams");
|
||||
window.location.href = formatted;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function loadApp() {
|
||||
const fragparts = parseQsFromFragment(window.location);
|
||||
const params = parseQs(window.location);
|
||||
|
||||
// don't try to redirect to the native apps if we're
|
||||
// verifying a 3pid
|
||||
const preventRedirect = Boolean(fragparts.params.client_secret);
|
||||
|
||||
if (!preventRedirect) {
|
||||
if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
|
||||
if (confirm("Vector is not supported on mobile web. Install the app?")) {
|
||||
window.location = "https://itunes.apple.com/us/app/vector.im/id1083446067";
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (/Android/.test(navigator.userAgent)) {
|
||||
if (confirm("Vector is not supported on mobile web. Install the app?")) {
|
||||
window.location = "https://play.google.com/store/apps/details?id=im.vector.alpha";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (/Android/.test(navigator.userAgent)) {
|
||||
if (confirm("Vector runs much better as an app on Vector. Get the app?")) {
|
||||
window.location = "https://play.google.com/store/apps/details?id=im.vector.alpha";
|
||||
return;
|
||||
|
||||
let configJson;
|
||||
let configError;
|
||||
try {
|
||||
configJson = await getConfig();
|
||||
} catch (e) {
|
||||
// On 404 errors, carry on without a config,
|
||||
// but on other errors, fail, otherwise it will
|
||||
// lead to subtle errors where the app runs with
|
||||
// the default config if it fails to fetch config.json.
|
||||
if (e.response.status != 404) {
|
||||
configError = e;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Vector starting at "+window.location);
|
||||
if (validBrowser) {
|
||||
if (configError) {
|
||||
window.matrixChat = ReactDOM.render(<div className="error">
|
||||
Unable to load config file: please refresh the page to try again.
|
||||
</div>, document.getElementById('matrixchat'));
|
||||
} else if (validBrowser) {
|
||||
var MatrixChat = sdk.getComponent('structures.MatrixChat');
|
||||
var fragParts = parseQsFromFragment(window.location);
|
||||
|
||||
window.matrixChat = ReactDOM.render(
|
||||
<MatrixChat
|
||||
onNewScreen={onNewScreen}
|
||||
registrationUrl={makeRegistrationUrl()}
|
||||
ConferenceHandler={VectorConferenceHandler}
|
||||
config={configJson}
|
||||
startingQueryParams={fragParts.params}
|
||||
enableGuest={true} />,
|
||||
realQueryParams={params}
|
||||
startingFragmentQueryParams={fragparts.params}
|
||||
enableGuest={true}
|
||||
onLoadCompleted={onLoadCompleted}
|
||||
/>,
|
||||
document.getElementById('matrixchat')
|
||||
);
|
||||
}
|
||||
|
||||
30
src/vector/url_utils.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import qs from 'querystring';
|
||||
|
||||
// We want to support some name / value pairs in the fragment
|
||||
// so we're re-using query string like format
|
||||
//
|
||||
// returns {location, params}
|
||||
export function parseQsFromFragment(location) {
|
||||
// if we have a fragment, it will start with '#', which we need to drop.
|
||||
// (if we don't, this will return '').
|
||||
var fragment = location.hash.substring(1);
|
||||
|
||||
// our fragment may contain a query-param-like section. we need to fish
|
||||
// this out *before* URI-decoding because the params may contain ? and &
|
||||
// characters which are only URI-encoded once.
|
||||
var hashparts = fragment.split('?');
|
||||
|
||||
var result = {
|
||||
location: decodeURIComponent(hashparts[0]),
|
||||
params: {}
|
||||
};
|
||||
|
||||
if (hashparts.length > 1) {
|
||||
result.params = qs.parse(hashparts[1]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function parseQs(location) {
|
||||
return qs.parse(location.search.substring(1));
|
||||
}
|
||||
@@ -47,7 +47,7 @@ describe('joining a room', function () {
|
||||
var parentDiv;
|
||||
var httpBackend;
|
||||
var matrixChat;
|
||||
|
||||
|
||||
beforeEach(function() {
|
||||
test_utils.beforeEach(this);
|
||||
httpBackend = new MockHttpBackend();
|
||||
@@ -66,21 +66,25 @@ describe('joining a room', function () {
|
||||
parentDiv = null;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it('should not get stuck at a spinner', function(done) {
|
||||
var ROOM_ALIAS = '#alias:localhost';
|
||||
var ROOM_ID = '!id:localhost';
|
||||
|
||||
|
||||
httpBackend.when('PUT', '/presence/'+encodeURIComponent(USER_ID)+'/status')
|
||||
.respond(200, {});
|
||||
httpBackend.when('GET', '/pushrules').respond(200, {});
|
||||
httpBackend.when('POST', '/filter').respond(200, { filter_id: 'fid' });
|
||||
httpBackend.when('GET', '/sync').respond(200, {});
|
||||
httpBackend.when('GET', '/publicRooms').respond(200, {chunk: []});
|
||||
httpBackend.when('GET', '/directory/room/'+encodeURIComponent(ROOM_ALIAS)).respond(200, { room_id: ROOM_ID });
|
||||
|
||||
// start with a logged-in client
|
||||
peg.replaceUsingAccessToken(HS_URL, IS_URL, USER_ID, ACCESS_TOKEN);
|
||||
|
||||
localStorage.setItem("mx_hs_url", HS_URL );
|
||||
localStorage.setItem("mx_is_url", IS_URL );
|
||||
localStorage.setItem("mx_access_token", ACCESS_TOKEN );
|
||||
localStorage.setItem("mx_user_id", USER_ID);
|
||||
|
||||
var mc = <MatrixChat config={{}}/>;
|
||||
matrixChat = ReactDOM.render(mc, parentDiv);
|
||||
|
||||
@@ -102,7 +106,7 @@ describe('joining a room', function () {
|
||||
|
||||
// that should create a roomview which will start a peek; wait
|
||||
// for the peek.
|
||||
httpBackend.when('GET', '/rooms/'+encodeURIComponent(ROOM_ALIAS)+"/initialSync")
|
||||
httpBackend.when('GET', '/rooms/'+encodeURIComponent(ROOM_ID)+"/initialSync")
|
||||
.respond(401, {errcode: 'M_GUEST_ACCESS_FORBIDDEN'});
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
|
||||
434
test/app-tests/loading.js
Normal file
@@ -0,0 +1,434 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/* loading.js: test the myriad paths we have for loading the application */
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ReactTestUtils from 'react-addons-test-utils';
|
||||
import expect from 'expect';
|
||||
import q from 'q';
|
||||
|
||||
import jssdk from 'matrix-js-sdk';
|
||||
|
||||
import sdk from 'matrix-react-sdk';
|
||||
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
|
||||
|
||||
import test_utils from '../test-utils';
|
||||
import MockHttpBackend from '../mock-request';
|
||||
import {parseQs, parseQsFromFragment} from '../../src/vector/url_utils';
|
||||
|
||||
var DEFAULT_HS_URL='http://my_server';
|
||||
var DEFAULT_IS_URL='http://my_is';
|
||||
|
||||
describe('loading:', function () {
|
||||
let parentDiv;
|
||||
let httpBackend;
|
||||
|
||||
// an Object simulating the window.location
|
||||
let windowLocation;
|
||||
|
||||
// the mounted MatrixChat
|
||||
let matrixChat;
|
||||
|
||||
// a promise which resolves when the MatrixChat calls onLoadCompleted
|
||||
let loadCompletePromise;
|
||||
|
||||
beforeEach(function() {
|
||||
test_utils.beforeEach(this);
|
||||
httpBackend = new MockHttpBackend();
|
||||
jssdk.request(httpBackend.requestFn);
|
||||
parentDiv = document.createElement('div');
|
||||
|
||||
// uncomment this to actually add the div to the UI, to help with
|
||||
// debugging (but slow things down)
|
||||
// document.body.appendChild(parentDiv);
|
||||
|
||||
windowLocation = null;
|
||||
matrixChat = null;
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
if (parentDiv) {
|
||||
ReactDOM.unmountComponentAtNode(parentDiv);
|
||||
parentDiv.remove();
|
||||
parentDiv = null;
|
||||
}
|
||||
});
|
||||
|
||||
/* simulate the load process done by index.js
|
||||
*
|
||||
* TODO: it would be nice to factor some of this stuff out of index.js so
|
||||
* that we can test it rather than our own implementation of it.
|
||||
*/
|
||||
function loadApp(opts) {
|
||||
opts = opts || {};
|
||||
const queryString = opts.queryString || "";
|
||||
const uriFragment = opts.uriFragment || "";
|
||||
|
||||
windowLocation = {
|
||||
search: queryString,
|
||||
hash: uriFragment,
|
||||
toString: function() { return this.search + this.hash; },
|
||||
};
|
||||
|
||||
let lastLoadedScreen = null;
|
||||
let appLoaded = false;
|
||||
|
||||
let loadCompleteDefer = q.defer();
|
||||
loadCompletePromise = loadCompleteDefer.promise;
|
||||
|
||||
function onNewScreen(screen) {
|
||||
console.log("newscreen "+screen);
|
||||
if (!appLoaded) {
|
||||
lastLoadedScreen = screen;
|
||||
} else {
|
||||
var hash = '#/' + screen;
|
||||
windowLocation.hash = hash;
|
||||
console.log("browser URI now "+ windowLocation);
|
||||
}
|
||||
}
|
||||
|
||||
const MatrixChat = sdk.getComponent('structures.MatrixChat');
|
||||
const fragParts = parseQsFromFragment(windowLocation);
|
||||
var params = parseQs(windowLocation);
|
||||
matrixChat = ReactDOM.render(
|
||||
<MatrixChat
|
||||
onNewScreen={onNewScreen}
|
||||
config={{
|
||||
default_hs_url: DEFAULT_HS_URL,
|
||||
default_is_url: DEFAULT_IS_URL,
|
||||
}}
|
||||
realQueryParams={params}
|
||||
startingFragmentQueryParams={fragParts.params}
|
||||
enableGuest={true}
|
||||
onLoadCompleted={loadCompleteDefer.resolve}
|
||||
/>, parentDiv
|
||||
);
|
||||
|
||||
function routeUrl(location, matrixChat) {
|
||||
console.log("Routing URL "+location);
|
||||
var fragparts = parseQsFromFragment(location);
|
||||
matrixChat.showScreen(fragparts.location.substring(1),
|
||||
fragparts.params);
|
||||
}
|
||||
|
||||
// pause for a cycle, then simulate the window.onload handler
|
||||
q.delay(0).then(() => {
|
||||
console.log("simulating window.onload");
|
||||
routeUrl(windowLocation, matrixChat);
|
||||
appLoaded = true;
|
||||
if (lastLoadedScreen) {
|
||||
onNewScreen(lastLoadedScreen);
|
||||
lastLoadedScreen = null;
|
||||
}
|
||||
}).done();
|
||||
}
|
||||
|
||||
describe("Clean load with no stored credentials:", function() {
|
||||
it('gives a login panel by default', function (done) {
|
||||
loadApp();
|
||||
|
||||
q.delay(1).then(() => {
|
||||
// at this point, we're trying to do a guest registration;
|
||||
// we expect a spinner
|
||||
assertAtLoadingSpinner(matrixChat);
|
||||
|
||||
httpBackend.when('POST', '/register').check(function(req) {
|
||||
expect(req.queryParams.kind).toEqual('guest');
|
||||
}).respond(403, "Guest access is disabled");
|
||||
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// we expect a single <Login> component
|
||||
ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('structures.login.Login'));
|
||||
expect(windowLocation.hash).toEqual("");
|
||||
}).done(done, done);
|
||||
});
|
||||
|
||||
it('should follow the original link after successful login', function(done) {
|
||||
loadApp({
|
||||
uriFragment: "#/room/!room:id",
|
||||
});
|
||||
|
||||
q.delay(1).then(() => {
|
||||
// at this point, we're trying to do a guest registration;
|
||||
// we expect a spinner
|
||||
assertAtLoadingSpinner(matrixChat);
|
||||
|
||||
httpBackend.when('POST', '/register').check(function(req) {
|
||||
expect(req.queryParams.kind).toEqual('guest');
|
||||
}).respond(403, "Guest access is disabled");
|
||||
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// we expect a single <Login> component
|
||||
let login = ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('structures.login.Login'));
|
||||
httpBackend.when('POST', '/login').check(function(req) {
|
||||
expect(req.data.type).toEqual('m.login.password');
|
||||
expect(req.data.user).toEqual('user');
|
||||
expect(req.data.password).toEqual('pass');
|
||||
}).respond(200, {
|
||||
user_id: '@user:id',
|
||||
access_token: 'access_token',
|
||||
});
|
||||
login.onPasswordLogin("user", "pass")
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// we expect a spinner
|
||||
ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('elements.Spinner'));
|
||||
|
||||
httpBackend.when('GET', '/pushrules').respond(200, {});
|
||||
httpBackend.when('POST', '/filter').respond(200, { filter_id: 'fid' });
|
||||
httpBackend.when('GET', '/sync').respond(200, {});
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// once the sync completes, we should have a room view
|
||||
httpBackend.verifyNoOutstandingExpectation();
|
||||
ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('structures.RoomView'));
|
||||
expect(windowLocation.hash).toEqual("#/room/!room:id");
|
||||
|
||||
// and the localstorage should have been updated
|
||||
expect(localStorage.getItem('mx_user_id')).toEqual('@user:id');
|
||||
expect(localStorage.getItem('mx_access_token')).toEqual('access_token');
|
||||
expect(localStorage.getItem('mx_hs_url')).toEqual(DEFAULT_HS_URL);
|
||||
expect(localStorage.getItem('mx_is_url')).toEqual(DEFAULT_IS_URL);
|
||||
}).done(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe("MatrixClient rehydrated from stored credentials:", function() {
|
||||
beforeEach(function() {
|
||||
localStorage.setItem("mx_hs_url", "http://localhost" );
|
||||
localStorage.setItem("mx_is_url", "http://localhost" );
|
||||
localStorage.setItem("mx_access_token", "access_token");
|
||||
localStorage.setItem("mx_user_id", "@me:localhost");
|
||||
});
|
||||
|
||||
it('shows a directory by default if we have no joined rooms', function(done) {
|
||||
httpBackend.when('GET', '/pushrules').respond(200, {});
|
||||
httpBackend.when('POST', '/filter').respond(200, { filter_id: 'fid' });
|
||||
httpBackend.when('GET', '/sync').respond(200, {});
|
||||
|
||||
loadApp();
|
||||
|
||||
q.delay(1).then(() => {
|
||||
// we expect a spinner
|
||||
assertAtSyncingSpinner(matrixChat);
|
||||
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// once the sync completes, we should have a directory
|
||||
httpBackend.verifyNoOutstandingExpectation();
|
||||
ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('structures.RoomDirectory'));
|
||||
expect(windowLocation.hash).toEqual("#/directory");
|
||||
}).done(done, done);
|
||||
});
|
||||
|
||||
it('shows a room view if we followed a room link', function(done) {
|
||||
httpBackend.when('GET', '/pushrules').respond(200, {});
|
||||
httpBackend.when('POST', '/filter').respond(200, { filter_id: 'fid' });
|
||||
httpBackend.when('GET', '/sync').respond(200, {});
|
||||
|
||||
loadApp({
|
||||
uriFragment: "#/room/!room:id",
|
||||
});
|
||||
|
||||
q.delay(1).then(() => {
|
||||
// we expect a spinner
|
||||
assertAtSyncingSpinner(matrixChat);
|
||||
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// once the sync completes, we should have a room view
|
||||
httpBackend.verifyNoOutstandingExpectation();
|
||||
ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('structures.RoomView'));
|
||||
expect(windowLocation.hash).toEqual("#/room/!room:id");
|
||||
}).done(done, done);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('Guest auto-registration:', function() {
|
||||
it('shows a directory by default', function (done) {
|
||||
loadApp();
|
||||
|
||||
q.delay(1).then(() => {
|
||||
// at this point, we're trying to do a guest registration;
|
||||
// we expect a spinner
|
||||
assertAtLoadingSpinner(matrixChat);
|
||||
|
||||
httpBackend.when('POST', '/register').check(function(req) {
|
||||
expect(req.queryParams.kind).toEqual('guest');
|
||||
}).respond(200, {
|
||||
user_id: "@guest:localhost",
|
||||
access_token: "secret_token",
|
||||
});
|
||||
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// now we should have a spinner with a logout link
|
||||
assertAtSyncingSpinner(matrixChat);
|
||||
|
||||
httpBackend.when('GET', '/sync').respond(200, {});
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// once the sync completes, we should have a directory
|
||||
httpBackend.verifyNoOutstandingExpectation();
|
||||
ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('structures.RoomDirectory'));
|
||||
expect(windowLocation.hash).toEqual("#/directory");
|
||||
}).done(done, done);
|
||||
});
|
||||
|
||||
it('uses the last known homeserver to register with', function (done) {
|
||||
localStorage.setItem("mx_hs_url", "https://homeserver" );
|
||||
localStorage.setItem("mx_is_url", "https://idserver" );
|
||||
|
||||
loadApp();
|
||||
|
||||
q.delay(1).then(() => {
|
||||
// at this point, we're trying to do a guest registration;
|
||||
// we expect a spinner
|
||||
assertAtLoadingSpinner(matrixChat);
|
||||
|
||||
httpBackend.when('POST', '/register').check(function(req) {
|
||||
expect(req.path).toMatch(new RegExp("^https://homeserver/"));
|
||||
expect(req.queryParams.kind).toEqual('guest');
|
||||
}).respond(200, {
|
||||
user_id: "@guest:localhost",
|
||||
access_token: "secret_token",
|
||||
});
|
||||
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// now we should have a spinner with a logout link
|
||||
assertAtSyncingSpinner(matrixChat);
|
||||
|
||||
httpBackend.when('GET', '/sync').check(function(req) {
|
||||
expect(req.path).toMatch(new RegExp("^https://homeserver/"));
|
||||
}).respond(200, {});
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// once the sync completes, we should have a directory
|
||||
httpBackend.verifyNoOutstandingExpectation();
|
||||
ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('structures.RoomDirectory'));
|
||||
expect(windowLocation.hash).toEqual("#/directory");
|
||||
expect(MatrixClientPeg.get().baseUrl).toEqual("https://homeserver");
|
||||
expect(MatrixClientPeg.get().idBaseUrl).toEqual("https://idserver");
|
||||
}).done(done, done);
|
||||
});
|
||||
|
||||
it('shows a room view if we followed a room link', function(done) {
|
||||
loadApp({
|
||||
uriFragment: "#/room/!room:id"
|
||||
});
|
||||
q.delay(1).then(() => {
|
||||
// at this point, we're trying to do a guest registration;
|
||||
// we expect a spinner
|
||||
assertAtLoadingSpinner(matrixChat);
|
||||
|
||||
httpBackend.when('POST', '/register').check(function(req) {
|
||||
expect(req.queryParams.kind).toEqual('guest');
|
||||
}).respond(200, {
|
||||
user_id: "@guest:localhost",
|
||||
access_token: "secret_token",
|
||||
});
|
||||
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// now we should have a spinner with a logout link
|
||||
assertAtSyncingSpinner(matrixChat);
|
||||
|
||||
httpBackend.when('GET', '/sync').respond(200, {});
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// once the sync completes, we should have a room view
|
||||
httpBackend.verifyNoOutstandingExpectation();
|
||||
ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('structures.RoomView'));
|
||||
expect(windowLocation.hash).toEqual("#/room/!room:id");
|
||||
}).done(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Token login:', function() {
|
||||
it('logs in successfully', function (done) {
|
||||
loadApp({
|
||||
queryString: "?loginToken=secretToken&homeserver=https%3A%2F%2Fhomeserver&identityServer=https%3A%2F%2Fidserver",
|
||||
});
|
||||
|
||||
q.delay(1).then(() => {
|
||||
// we expect a spinner while we're logging in
|
||||
assertAtLoadingSpinner(matrixChat);
|
||||
|
||||
httpBackend.when('POST', '/login').check(function(req) {
|
||||
expect(req.path).toMatch(new RegExp("^https://homeserver/"));
|
||||
expect(req.data.type).toEqual("m.login.token");
|
||||
expect(req.data.token).toEqual("secretToken");
|
||||
}).respond(200, {
|
||||
user_id: "@user:localhost",
|
||||
access_token: "access_token",
|
||||
});
|
||||
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// at this point, MatrixChat should fire onLoadCompleted, which
|
||||
// makes index.js reload the app. We're not going to attempt to
|
||||
// simulate the reload - just check that things are left in the
|
||||
// right state for the reloaded app.
|
||||
|
||||
return loadCompletePromise;
|
||||
}).then(() => {
|
||||
// check that the localstorage has been set up in such a way that
|
||||
// the reloaded app can pick up where we leave off.
|
||||
expect(localStorage.getItem('mx_user_id')).toEqual('@user:localhost');
|
||||
expect(localStorage.getItem('mx_access_token')).toEqual('access_token');
|
||||
expect(localStorage.getItem('mx_hs_url')).toEqual('https://homeserver');
|
||||
expect(localStorage.getItem('mx_is_url')).toEqual('https://idserver');
|
||||
}).done(done, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// assert that we are on the loading page
|
||||
function assertAtLoadingSpinner(matrixChat) {
|
||||
var domComponent = ReactDOM.findDOMNode(matrixChat);
|
||||
expect(domComponent.className).toEqual("mx_MatrixChat_splash");
|
||||
|
||||
// just the spinner
|
||||
expect(domComponent.children.length).toEqual(1);
|
||||
}
|
||||
|
||||
// we've got login creds, and are waiting for the sync to finish.
|
||||
// the page includes a logout link.
|
||||
function assertAtSyncingSpinner(matrixChat) {
|
||||
var domComponent = ReactDOM.findDOMNode(matrixChat);
|
||||
expect(domComponent.className).toEqual("mx_MatrixChat_splash");
|
||||
|
||||
ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('elements.Spinner'));
|
||||
var logoutLink = ReactTestUtils.findRenderedDOMComponentWithTag(
|
||||
matrixChat, 'a');
|
||||
expect(logoutLink.text).toEqual("Logout");
|
||||
}
|
||||
@@ -12,6 +12,10 @@ module.exports.beforeEach = function(context) {
|
||||
console.log();
|
||||
console.log(desc);
|
||||
console.log(new Array(1 + desc.length).join("="));
|
||||
|
||||
// some tests store things in localstorage. Improve independence of tests
|
||||
// by making sure that they don't inherit any old state.
|
||||
window.localStorage.clear();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
8
vector/config.sample.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"default_hs_url": "https://matrix.org",
|
||||
"default_is_url": "https://vector.im",
|
||||
"brand": "Vector",
|
||||
"integrations_ui_url": "http://localhost:8081/",
|
||||
"integrations_rest_url": "http://localhost:5050",
|
||||
"enableLabs": true
|
||||
}
|
||||
@@ -24,6 +24,8 @@
|
||||
</head>
|
||||
<body style="height: 100%;">
|
||||
<section id="matrixchat" style="height: 100%;"></section>
|
||||
<!-- load olm, if possible. -->
|
||||
<script src="olm.js"></script>
|
||||
<script src="bundle.js"></script>
|
||||
<noscript>Sorry, Vector requires JavaScript to be enabled.</noscript>
|
||||
<link rel="stylesheet" href="bundle.css">
|
||||
|
||||
@@ -2,8 +2,6 @@ var path = require('path');
|
||||
var webpack = require('webpack');
|
||||
var ExtractTextPlugin = require("extract-text-webpack-plugin");
|
||||
|
||||
var olm_path = path.resolve('./node_modules/olm');
|
||||
|
||||
module.exports = {
|
||||
module: {
|
||||
preLoaders: [
|
||||
@@ -45,13 +43,16 @@ module.exports = {
|
||||
|
||||
// same goes for js-sdk
|
||||
"matrix-js-sdk": path.resolve('./node_modules/matrix-js-sdk'),
|
||||
|
||||
// matrix-js-sdk will use olm if it is available,
|
||||
// but does not explicitly depend on it. Pull it
|
||||
// in from node_modules if it's there.
|
||||
olm: olm_path,
|
||||
},
|
||||
},
|
||||
externals: {
|
||||
// olm takes ages for webpack to process, and it's already heavily
|
||||
// optimised, so there is little to gain by us uglifying it. We
|
||||
// therefore use it via a separate <script/> tag in index.html (which
|
||||
// loads it into the browser global `Olm`), and reference it as an
|
||||
// external here.
|
||||
"olm": "Olm",
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
@@ -62,23 +63,6 @@ module.exports = {
|
||||
new ExtractTextPlugin("bundle.css", {
|
||||
allChunks: true
|
||||
}),
|
||||
|
||||
// olm.js includes "require 'fs'", which is never
|
||||
// executed in the browser. Ignore it.
|
||||
new webpack.IgnorePlugin(/^fs$/, /node_modules\/olm$/)
|
||||
],
|
||||
devtool: 'source-map'
|
||||
};
|
||||
|
||||
// ignore olm.js if it's not installed.
|
||||
(function() {
|
||||
var fs = require('fs');
|
||||
try {
|
||||
fs.lstatSync(olm_path);
|
||||
console.log("Olm is installed; including it in webpack bundle");
|
||||
} catch (e) {
|
||||
module.exports.plugins.push(
|
||||
new webpack.IgnorePlugin(/^olm$/)
|
||||
);
|
||||
}
|
||||
}) ();
|
||||
|
||||