Compare commits

..

944 Commits

Author SHA1 Message Date
Matthew Hodgson
c672919d1e 0.7.3 2016-06-03 12:20:05 +01:00
Matthew Hodgson
7ab2449ac1 Prepare changelog for v0.7.3 2016-06-03 12:20:04 +01:00
Matthew Hodgson
e68a2b5e1d pin to react sdk 0.6.3 for release 2016-06-03 12:19:04 +01:00
Matthew Hodgson
ddc4ac187c dep on react-sdk develop 2016-06-02 23:32:47 +01:00
Matthew Hodgson
ded66bbdfc 0.7.2 2016-06-02 19:05:50 +01:00
Matthew Hodgson
1a11c402fa Prepare changelog for v0.7.2 2016-06-02 19:05:50 +01:00
Matthew Hodgson
4ec77eeca7 correctly bump dep on js-sdk and react-sdk 2016-06-02 19:04:22 +01:00
Matthew Hodgson
635fd927cd 0.7.1 2016-06-02 18:41:20 +01:00
Matthew Hodgson
481a7b160d Prepare changelog for v0.7.1 2016-06-02 18:41:20 +01:00
David Baker
cadedd2919 Revert presumably accidentally comitted config.json 2016-06-02 14:24:36 +01:00
Richard van der Hoff
e0bf23fa7c 0.7.0 2016-06-02 13:42:25 +01:00
Richard van der Hoff
a53acb3b58 Prepare changelog for v0.7.0 2016-06-02 13:42:24 +01:00
Richard van der Hoff
f6ec858ac9 Bump js-sdk and react-sdk for new releases
js-sdk 0.5.3
react-sdk 0.6.0
2016-06-02 13:40:15 +01:00
Matthew Hodgson
d976046e6a set email branding whenever emails are added from vector 2016-06-02 13:15:13 +01:00
Matthew Hodgson
1902b631c7 add default branding parameter for email notifs 2016-06-02 11:45:23 +01:00
Matthew Hodgson
dda2129354 Merge pull request #1557 from aviraldg/feature-style-selection
Style selection color.
2016-05-28 16:30:53 +01:00
Aviral Dasgupta
12157edd62 Style selection color 2016-05-28 12:20:21 +05:30
Matthew Hodgson
bede9a814b remove spurious top border; fix #1472 2016-05-24 00:30:36 +01:00
Matthew Hodgson
d70842c3c7 fix padding of badges 2016-05-24 00:29:48 +01:00
Matthew Hodgson
d8c32db14b typos 2016-05-17 20:24:01 +01:00
Matthew Hodgson
2b3606d44d switch to lozenges, and improve overlap behaviour 2016-05-17 19:52:56 +01:00
Matthew Hodgson
5feb31911a better collapsed look & feel 2016-05-17 11:19:04 +01:00
Matthew Hodgson
9483e42508 switch from dots to per-room badges 2016-05-17 11:14:30 +01:00
Matthew Hodgson
e640f65640 add close button to room search filter 2016-05-16 23:36:52 +01:00
Matthew Hodgson
8a9c85c97d fix wording 2016-05-16 23:00:17 +01:00
David Baker
bbae809012 Merge pull request #1518 from vector-im/kegan/threepids-npe
Fix NPE when loading the Settings page which infini-spinnered
2016-05-16 16:09:43 +01:00
Kegan Dougal
bc166f19b7 Fix NPE when loading the Settings page which infini-spinnered 2016-05-16 16:04:06 +01:00
Matthew Hodgson
8fb521c83c 302 android to play store 2016-05-13 17:14:01 +01:00
Matthew Hodgson
d9077584cd Merge branch 'dbkr/email_notifs' into develop 2016-05-13 15:16:35 +01:00
Matthew Hodgson
8467d5d760 302 to iTunes if you don't have the app installed 2016-05-11 01:48:02 +02:00
David Baker
d96e5a55e1 Merge branch 'develop' of github.com:vector-im/vector-web into develop 2016-05-10 17:36:02 +02:00
David Baker
4f64f70a12 Use react-sdk develop as email notifs needs it 2016-05-10 17:35:35 +02:00
Matthew Hodgson
9cd8f7c7f3 Merge pull request #1469 from vector-im/dbkr/email_notifs
Add option to enable email notifications
2016-05-10 16:39:50 +02:00
Matthew Hodgson
c64f71a3cb refine memberlist cosmetics 2016-05-05 00:35:47 +01:00
Matthew Hodgson
af9838408b s/devices/notification targets/ 2016-05-04 11:58:37 +01:00
Matthew Hodgson
974a187e74 fix annoying bug where URL previews with very long lines (e.g. vector permalinks) would get clipped 2016-05-03 17:49:42 +01:00
David Baker
efe1c767f0 Un-inline onChange 2016-05-03 11:36:44 +01:00
David Baker
4bfefa9396 Merge remote-tracking branch 'origin/develop' into dbkr/email_notifs 2016-04-22 16:25:18 +01:00
Richard van der Hoff
4cddda67d9 0.6.1 2016-04-22 11:35:51 +01:00
Richard van der Hoff
c2d4409241 Prepare changelog for v0.6.1 2016-04-22 11:35:50 +01:00
Richard van der Hoff
ee88fe55c1 Bump to react-sdk 0.5.2 2016-04-22 11:30:33 +01:00
David Baker
a72d0c5b7f Merge remote-tracking branch 'origin/develop' into dbkr/email_notifs 2016-04-21 10:17:15 +01:00
David Baker
3cb092051e Merge branch 'develop' into dbkr/email_notifs 2016-04-21 10:11:55 +01:00
Richard van der Hoff
b8018942fc Bump react-gemini-scrollbar
(to pick up a non-broken version)
2016-04-20 13:46:59 +01:00
Richard van der Hoff
3136eb0962 Merge pull request #1438 from vector-im/rav/update_gemini
Don't relayout scrollpanels every time something changes
2016-04-20 12:32:57 +01:00
Richard van der Hoff
02f58ef9e3 Don't relayout scrollpanels every time something changes
Gemini's habit of reflowing everything everytime anything changes at all makes
for an unresponsive app. Turn it off everywhere we use gemini.
2016-04-20 12:29:32 +01:00
Richard van der Hoff
b5f029d10e Turn react consistency checks off in develop builds
For now at least, turn off the consistency checks in build:dev, and hence in
/develop. This will allow us to more meaningfully compare performance between
/beta and /develop.
2016-04-19 20:28:29 +01:00
Richard van der Hoff
caff20cbb3 Merge pull request #1431 from vector-im/rav/reactperf
Include react-addons-perf for non-production builds
2016-04-19 19:28:15 +01:00
Richard van der Hoff
e71ca328e7 Switch back to dev builds of the react-sdk and js-sdk 2016-04-19 18:32:35 +01:00
Richard van der Hoff
a0b460b084 Include react-addons-perf for non-production builds
This makes it possible to gather a few performance stats
2016-04-19 15:01:24 +01:00
Richard van der Hoff
abca28c80b 0.6.0 2016-04-19 13:39:40 +01:00
Richard van der Hoff
5627089a2a Prepare changelog for v0.6.0 2016-04-19 13:39:40 +01:00
Richard van der Hoff
da7909f1ce Bump to release versions of js-sdk and react-sdk
... in preparation for vector release.
2016-04-19 13:36:25 +01:00
Richard van der Hoff
210cb31852 Upgrade to react 15.0
(which also requires upgrades to react-gemini-scrollbar and react-dnd)
2016-04-17 21:41:50 +01:00
Matthew Hodgson
aeb438dc62 fix tbody & keying warnings 2016-04-17 17:44:04 +01:00
Matthew Hodgson
10a053019d fix thinkos - thanks @richvdh for posthoc review 2016-04-17 17:35:17 +01:00
Matthew Hodgson
58c431abc2 fix spinner layout bouncing when changing notifs
all-important s/done/then/ on pushRulesPromise to ensure that the refresh completes before relaying-out the page
s/Loud/Highlight & sound/
2016-04-17 14:00:20 +01:00
Matthew Hodgson
d512e25cca persist search filter over being hidden 2016-04-17 00:28:33 +01:00
Matthew Hodgson
65d9333104 pointer on roomsublist 2016-04-16 23:49:21 +01:00
Matthew Hodgson
fbd974df55 fix bottomleft bug in chrome canary 2016-04-16 23:49:16 +01:00
Matthew Hodgson
fdf83a5ad5 fix tooltip offset 2016-04-15 22:24:20 +01:00
Matthew Hodgson
c98e06e1aa add cancelButton to simpleHeader 2016-04-15 22:16:06 +01:00
Matthew Hodgson
b58265a69c fix comedy FontAwesome bug 2016-04-15 21:48:09 +01:00
Matthew Hodgson
37fbad0dbe fix LeftPanel width in FF 2016-04-15 21:37:52 +01:00
Matthew Hodgson
756da03b9a fix wrapping of RoomTile when selected 2016-04-15 20:50:22 +01:00
Matthew Hodgson
48e082e124 Merge pull request #1402 from vector-im/matthew/design_tweaks
Matthew/design tweaks
2016-04-15 18:48:30 +01:00
Matthew Hodgson
c606912a8d fix topic font size 2016-04-15 18:45:52 +01:00
Matthew Hodgson
7cd24e7dbd commented out fading for RoomDirectory 2016-04-15 18:29:57 +01:00
Matthew Hodgson
c7d717f0a4 fix RightPanel 2016-04-15 18:29:49 +01:00
Matthew Hodgson
cf3cdaccf3 fix up UserSettings a bit 2016-04-15 18:23:47 +01:00
Matthew Hodgson
d0d4760ddc align highlight with droptarget RHS 2016-04-15 18:09:10 +01:00
Matthew Hodgson
51bc18aef0 prettier icon 2016-04-15 18:05:57 +01:00
Matthew Hodgson
26d12bebe4 wire up searchbox filtering, and some minor overall tweaks 2016-04-15 17:54:48 +01:00
Matthew Hodgson
90ae024a4e tidy up rightpanel and searchbox 2016-04-15 15:53:27 +01:00
David Baker
57c7d81f43 Merge pull request #1399 from vector-im/rav/fix_unparsable_notifications
Improve handling of notification rules we can't parse
2016-04-15 13:00:04 +01:00
Richard van der Hoff
eab206c3bd Improve handling of notification rules we can't parse
* An absent rule is the same as a rule with 'enabled == false', and is not
necessarily 'OFF' (particularly in the case of the bot rule, which is
inverted).

* If we don't understand the rule, then don't tick any of the radio buttons,
and instead show it in the 'external' section.
2016-04-15 12:42:03 +01:00
Matthew Hodgson
72745b05dc forgotten CSS 2016-04-15 10:49:25 +01:00
Matthew Hodgson
f8d5101dbc add lost SVGs and implement SearchBox skeleton 2016-04-15 02:23:12 +01:00
Matthew Hodgson
cc1e30c963 dinkier topic 2016-04-15 01:42:44 +01:00
Richard van der Hoff
121fe34180 Improve parsing of keyword notification rules
For notification rules, the absence of a value on a 'highlight' tweak means
that the highlight should happen; this was previously confusing us.

Use the action parser from NotificationUtils to simplify the code.

Fixes https://github.com/vector-im/vector-web/issues/1330
2016-04-14 22:45:00 +01:00
Richard van der Hoff
5450223cc7 More notifications fixes
Fix another thing I broke during the refactor
2016-04-14 22:31:40 +01:00
Matthew Hodgson
25b5c14527 fix new bottomleft menu 2016-04-14 22:26:48 +01:00
Matthew Hodgson
6bc4c87ce4 update to new bottomleftmenu. update header and composer heights 2016-04-14 21:43:49 +01:00
Richard van der Hoff
0f0c3d0ca1 Merge branch 'rav/more_refactor_notifications' into develop 2016-04-14 21:27:34 +01:00
Matthew Hodgson
96c4a24d3d skin RoomSubList chevrons, horizontal rules and selected room 2016-04-14 21:10:55 +01:00
Richard van der Hoff
c6b501811f Move more stuff out of Notifications.js 2016-04-14 19:54:03 +01:00
Richard van der Hoff
0996a0b140 Fixes to refactored notifications
A few things I managed to break in the recent refactor
2016-04-14 19:54:03 +01:00
Matthew Hodgson
8557a3b70e fix vertical alignment within status bar 2016-04-14 19:15:35 +01:00
Matthew Hodgson
8b6cf1fc41 change badge look & feel; change status bar sizing 2016-04-14 19:11:58 +01:00
Matthew Hodgson
4eb762d52b spell out that images are clickable 2016-04-14 18:16:03 +01:00
Matthew Hodgson
4d221c6099 spell out that images are clickable 2016-04-14 18:15:51 +01:00
Richard van der Hoff
314bfbd541 Merge pull request #1391 from vector-im/rav/unoptimize_develop
Do less mangling of jenkins builds
2016-04-14 15:55:13 +01:00
Richard van der Hoff
5cdd234bf2 Do less mangling of jenkins builds
This turns off uglification, and turns on the react sanity checks.
2016-04-14 15:05:36 +01:00
Richard van der Hoff
b6d5849bec Merge pull request #1386 from vector-im/rav/refactor_notifications
Start Notifications component refactor
2016-04-14 14:29:11 +01:00
Richard van der Hoff
035b15f330 Moar debug for ff session restore issue 2016-04-13 22:18:26 +01:00
Richard van der Hoff
77355cbeb4 Add some debug to help with FF restore bug
(https://github.com/vector-im/vector-web/issues/1354)
2016-04-13 21:01:24 +01:00
Richard van der Hoff
ff5dff45f5 Start Notifications component refactor
Factor some things out of the mega Notifications component, and add a dummy
unit test to show willing
2016-04-13 18:44:41 +01:00
Richard van der Hoff
0deb52ac5e Merge branch 'rav/karma' into develop
Run test suite under karma as part of build
2016-04-13 18:23:52 +01:00
Richard van der Hoff
29ff9c11a8 Final karma tweaks
* fix a comment
* drop redundant import
2016-04-13 18:22:05 +01:00
Richard van der Hoff
cb3ae0e069 Disable autoWatch for npm test
... we're only going to run the tests once, so there is no need to tell webpack
to watch the sources. This saves a spurious repack.
2016-04-13 18:13:57 +01:00
Richard van der Hoff
bf31d6d5fa Karma test tweaks
* Make sure we only get one js-sdk (and update runtime config to match)
* Don't verifyNoOutstandingRequests (since it is hard to be certain which we
  will get, and makes the tests too dependent on implementation-specifics).
* Disable color for npm test, to avoid confusing Jenkins
2016-04-13 17:41:23 +01:00
Richard van der Hoff
181a6a61ff tests: Don't add the div to the DOM 2016-04-13 17:20:06 +01:00
Richard van der Hoff
322af6513d Run some tests under karma
Including a regression test for
https://github.com/vector-im/vector-web/issues/1314
2016-04-13 17:20:06 +01:00
Richard van der Hoff
69ce3c43cf Revert "Merge branch 'develop' into rav/karma"
The karma tests don't pass yet, and aren't ready to land on develop.

This reverts commit 438453e61a, reversing
changes made to 50f94eb040.
2016-04-13 17:17:45 +01:00
Richard van der Hoff
438453e61a Merge branch 'develop' into rav/karma 2016-04-13 16:16:26 +01:00
Matthew Hodgson
50f94eb040 stop guests rom trying to blunder into non-guest rooms 2016-04-13 13:33:23 +01:00
David Baker
5794c30def Devices should be below 'advanced' 2016-04-13 11:35:53 +01:00
Richard van der Hoff
a512e600a7 tests: Don't add the div to the DOM 2016-04-13 11:16:38 +01:00
Richard van der Hoff
429d110212 Run some tests under karma
Including a regression test for
https://github.com/vector-im/vector-web/issues/1314
2016-04-13 10:15:04 +01:00
Matthew Hodgson
b5248c06a7 fix https://github.com/vector-im/vector-web/issues/987 for once and for all 2016-04-13 00:34:32 +01:00
Matthew Hodgson
18bd1058d3 Merge pull request #1376 from vector-im/matthew/fadable
make the UI fadable to help with decluttering
2016-04-12 18:04:47 +01:00
Matthew Hodgson
b18fcf7f9e spinner on saving room settings 2016-04-12 18:02:31 +01:00
Matthew Hodgson
05e963d1e2 make the UI fadable to help with decluttering 2016-04-12 17:17:08 +01:00
David Baker
5d9c8f3726 Support config for email notifs
Add support to notif settings for adding an email pusher, only for the first email address for now.
2016-04-12 16:19:20 +01:00
David Baker
be55882f46 Merge pull request #1374 from vector-im/dbkr/get_pushers
Get and display a user's pushers in settings
2016-04-12 14:41:45 +01:00
David Baker
356a4a4392 Typo and use CSS rather than <i> 2016-04-12 14:10:17 +01:00
Matthew Hodgson
34bdd40953 timestamps are permalinks 2016-04-12 13:34:10 +01:00
David Baker
c5524851f3 Comment future possibility for deleting pushers 2016-04-12 13:22:58 +01:00
David Baker
cff1c3010b Get & display pushers in settings
Really this is so (in a subsequent PR) we can show whether a user has an email pusher, but we can basically display the list of pushers for free, so adding this too.
2016-04-12 13:18:57 +01:00
Matthew Hodgson
46572ae793 click on group call thumbnail should return you to the group call, not the 1:1 2016-04-12 02:27:35 +01:00
Matthew Hodgson
b1ba69fd00 fix lightbox overscroll 2016-04-12 00:35:00 +01:00
Matthew Hodgson
8c619fedeb Merge pull request #1343 from vector-im/matthew/preview_urls
URL previewing support
2016-04-11 23:55:18 +01:00
Matthew Hodgson
efd01d6929 move localstorage crap entirely to TextualBody 2016-04-11 23:54:00 +01:00
Matthew Hodgson
a1b78f93fe Fix wrap on view source 2016-04-10 14:18:57 +01:00
Matthew Hodgson
cdc89c0623 add the concept of eventTileOps for managing widget visibility based on vdh's PR feedback 2016-04-08 21:42:42 +01:00
Matthew Hodgson
d107151f8a rename size prop as fileSize, add comments, and honour explicit properties rather than mxEvent fields 2016-04-07 18:10:15 +01:00
Matthew Hodgson
48abc75665 Merge branch 'develop' into matthew/preview_Urls 2016-04-07 17:25:17 +01:00
Matthew Hodgson
41373f30f7 oops, name LinkPreviewWidget correctly 2016-04-04 00:33:15 +01:00
Matthew Hodgson
ad9d032f82 fix typo introduced in #1340 2016-04-04 00:17:50 +01:00
Matthew Hodgson
d7eb23db53 specify sizes and hyperlinks for non-event images 2016-04-04 00:16:52 +01:00
Matthew Hodgson
333f1e46ca document properties and remove spurious 'view full screen' button 2016-04-03 23:57:44 +01:00
Matthew Hodgson
d414127f80 track whether widget should be hidden on the event, as well as persisting it in localStorage 2016-04-03 23:31:42 +01:00
Matthew Hodgson
ff2885087d support cancelling and uncancelling previews 2016-04-03 02:50:51 +01:00
Matthew Hodgson
a5258978d6 Merge branch 'develop' into matthew/preview_urls 2016-04-03 02:07:03 +01:00
Matthew Hodgson
8c0a23dd8b fix widget layout 2016-04-03 02:06:24 +01:00
Matthew Hodgson
d434ea55a8 Merge pull request #1332 from aviraldg/feature-emoji
😄 Emoji autocomplete and unicode emoji to image conversion using emojione.
2016-04-02 23:21:31 +01:00
Matthew Hodgson
4331fbf422 Merge pull request #1340 from aviraldg/fix-65
Show full-size avatar on MemberInfo avatar click
2016-04-02 23:20:39 +01:00
Aviral Dasgupta
cf17ea6254 Show full-size avatar on MemberInfo avatar click
fixes vector-im/vector-web#65
2016-04-03 00:53:17 +05:30
Matthew Hodgson
8247bb4a76 match style for markdown quotes 2016-04-02 00:36:53 +01:00
Matthew Hodgson
08a41bf093 improve layout for LinkPreviewWidget 2016-04-01 02:16:29 +01:00
Aviral Dasgupta
d7157696f4 styling for emojione emojis 😄 2016-04-01 06:22:13 +05:30
Richard van der Hoff
bf055688b7 Switch js-sdk and react-sdk back to develop 2016-03-31 16:35:38 +01:00
Matthew Hodgson
28b9892486 burndown generator 2016-03-30 21:25:18 +01:00
Matthew Hodgson
512a9125bf fix zalgos in SenderProfile again, whilst maintaining limited-width name via inline-block. and without doubling emote vertical space... 2016-03-30 19:47:06 +01:00
Richard van der Hoff
00a92452e8 0.5.0 2016-03-30 13:31:09 +01:00
Richard van der Hoff
32576e97d5 Prepare changelog for v0.5.0 2016-03-30 13:31:09 +01:00
Richard van der Hoff
20f93e761b Bump to react-sdk 0.4.0 and js-sdk 0.5.1. 2016-03-30 13:27:55 +01:00
Matthew Hodgson
bdf8f655fb tweak animation and comment it out for now as it maxes out a whole core on my top-of-the-line MBP... 2016-03-30 01:36:44 +01:00
Matthew Hodgson
8603dd4bb4 Merge pull request #1292 from aviraldg/feature-pretty-placeholder
Prettier, animated placeholder :D
2016-03-30 01:28:34 +01:00
Matthew Hodgson
212a070a02 add a github issues graphing script 2016-03-30 01:23:44 +01:00
Richard van der Hoff
e15358f77e Merge pull request #1307 from vector-im/rav/SimpleRoomHeader
RoomDirectory: use SimpleRoomHeader instead of RoomHeader
2016-03-29 23:26:09 +01:00
Richard van der Hoff
851b601d2c Pass SimpleRoomHeader topic in as a named prop 2016-03-29 23:25:26 +01:00
Richard van der Hoff
f52a1cf311 Merge pull request #1277 from vector-im/rav/no_parse_languages
Tell webpack not to parse the highlight.js languages
2016-03-29 22:48:58 +01:00
Matthew Hodgson
0ddb2cf183 fix action vertical spacing 2016-03-29 17:10:11 +01:00
Richard van der Hoff
cf0340c1c7 RoomDirectory: use SimpleRoomHeader instead of RoomHeader
SimpleRoomHeader and RoomHeader are now separate things
(https://github.com/matrix-org/matrix-react-sdk/pull/252), so update Vector
accordingly.
2016-03-29 16:45:24 +01:00
Aviral Dasgupta
6c5b4a298b Prettier, animated placeholder :D 2016-03-28 19:32:04 +05:30
Richard van der Hoff
c5c5e6d811 Tell webpack not to parse the highlight.js languages
Hopefully, this fixes https://github.com/vector-im/vector-web/issues/1046
without any side-effects.

It relies on the fact that the languages files are pretty simple - in
particular, they don't require any other modules. So we can tell webpack just
to suck them in as they are, rather than parsing them and causing an explosm.
2016-03-24 22:51:50 +00:00
Richard van der Hoff
2462ede539 Switch to dev versions of react-sdk and js-sdk 2016-03-24 17:39:49 +00:00
Richard van der Hoff
b6e4c59877 Merge pull request #1249 from vector-im/dbkr/disable_composer_if_no_permission
CSS for https://github.com/matrix-org/matrix-react-sdk/pull/247
2016-03-24 11:44:16 +00:00
Matthew Hodgson
0bc1624d4e make senderprofile smaller 2016-03-24 01:19:55 +00:00
Matthew Hodgson
f81f7db6cd fix layout problems exposed by #cats 2016-03-24 01:12:27 +00:00
Matthew Hodgson
9e95d2e4ac make image event bodies display as blocks to avoid auto sizing, so we can measure their width to explicitly set their height 2016-03-24 00:13:03 +00:00
Richard van der Hoff
95a46ae201 Merge pull request #1254 from vector-im/rav/uridecode_fragment
URI-decode the hash-fragment
2016-03-23 22:59:46 +00:00
David Baker
8764b44325 Un-commit config change 2016-03-23 16:41:17 +00:00
Richard van der Hoff
090db5490b URI-decode the hash-fragment
It looks like % characters in the hash-fragment are meant to be interpreted as
a URI-encoding, so we should decode them.
2016-03-23 15:58:00 +00:00
David Baker
cfcb050822 Add composer controls wrapper to set correct width on the composer controls wrapper div 2016-03-23 15:21:37 +00:00
David Baker
66e36e9d40 CSS for https://github.com/matrix-org/matrix-react-sdk/pull/247 2016-03-23 15:15:38 +00:00
Richard van der Hoff
4507117f89 0.4.1 2016-03-23 14:58:30 +00:00
Richard van der Hoff
cad48b62e4 Prepare changelog for v0.4.1 2016-03-23 14:58:30 +00:00
Richard van der Hoff
5138dc9fd8 Bump to react-sdk 0.3.1
Disables ScrollPanel debug.
2016-03-23 14:56:22 +00:00
Richard van der Hoff
c12a77bc15 0.4.0 2016-03-23 14:40:16 +00:00
Richard van der Hoff
695b5d950c Prepare changelog for 0.4.0 2016-03-23 14:39:30 +00:00
Richard van der Hoff
17b2d14ffc Release script for vector-web 2016-03-23 14:15:22 +00:00
Richard van der Hoff
752f8363a7 Bump to release versions of react-sdk and js-sdk 2016-03-23 14:14:07 +00:00
Matthew Hodgson
a3a4ff569e stop scrollbars overlaying on the count 2016-03-23 13:51:38 +00:00
Richard van der Hoff
948b862c31 Bump gemini-scrollbar to latest version
RoomDirectory uses react-gemini-scrollbar directly, so make sure we are using a
consistent version.
2016-03-23 12:24:25 +00:00
Matthew Hodgson
27ab79fd38 handle unaliased room naming more sanely 2016-03-23 11:50:38 +00:00
Matthew Hodgson
8cbc8db1cb oops 2016-03-23 11:38:17 +00:00
Matthew Hodgson
e32299a50c fix enable notifs text 2016-03-23 11:32:47 +00:00
Matthew Hodgson
c843ee3157 handle canonical aliases correctly; search on names; support rooms with no aliases 2016-03-23 11:26:18 +00:00
Matthew Hodgson
490cbbd05f fix horiz pre scrollbars https://github.com/vector-im/vector-web/issues/754 2016-03-22 15:13:36 +00:00
Matthew Hodgson
e4aa43944f crude lipstick for warnings 2016-03-22 12:11:19 +00:00
Matthew Hodgson
827f891ae7 warning prompt for roomsettings 2016-03-22 00:56:38 +00:00
Matthew Hodgson
54c34ab8d5 improve previewbar look & feel 2016-03-21 22:06:06 +00:00
Matthew Hodgson
3339fa2a39 Merge pull request #1232 from vector-im/matthew/permalink
permalink button
2016-03-21 15:39:03 +00:00
Matthew Hodgson
d4a36f5081 permalink button 2016-03-19 23:26:04 +00:00
Matthew Hodgson
19cb06d040 prop fix 2016-03-18 20:08:31 +00:00
Richard van der Hoff
a5e0aa763b Bump gemini-scrollbar version
To fix scrollbar fail thanks to npm's lack of dependency-version conflict
resolution.
2016-03-18 16:34:20 +00:00
Matthew Hodgson
a1e3cf76e1 top-align search results 2016-03-18 16:24:48 +00:00
Matthew Hodgson
866bd55bc3 give notif bar a pointer cursor 2016-03-18 16:16:13 +00:00
Matthew Hodgson
a6257a1148 show right panel if needed when viewing users 2016-03-18 16:09:00 +00:00
Matthew Hodgson
92e187da64 fix ugly spinner on MemberList 2016-03-17 18:44:53 +00:00
Matthew Hodgson
f950b675bd workaround to avoid accidental click-throughs on narrow vertical scrollbars 2016-03-17 18:26:00 +00:00
Matthew Hodgson
aca4457a89 apparently we don't need a default onClick 2016-03-17 17:00:58 +00:00
Matthew Hodgson
725b9a6619 Merge pull request #1191 from vector-im/matthew/insert-displayname
make senderprofiles clickable
2016-03-17 16:59:03 +00:00
Matthew Hodgson
d7a851a353 make senderprofiles clickable 2016-03-17 16:28:49 +00:00
Matthew Hodgson
c6f95dfb3b Merge pull request #1180 from vector-im/matthew/fix-notif-spam
fix notif spam when logging in from a guest session by correctly logging out first.
2016-03-17 14:37:21 +00:00
Matthew Hodgson
4164688c24 add pointer to EventTile 2016-03-17 13:09:28 +00:00
Matthew Hodgson
cddfa62e27 reorder the push settings as off, on, loud - fixes https://github.com/vector-im/vector-web/issues/1117 2016-03-17 02:24:48 +00:00
Matthew Hodgson
a6e3b39f16 fix notif spam on launch by correctly logging out again. reverts start_login_from_guest stuff 2016-03-17 02:08:05 +00:00
Matthew Hodgson
f8fb3a7fe1 fix aspect ratio of roomavatar preview 2016-03-16 20:00:50 +00:00
Matthew Hodgson
50d18ac771 Merge pull request #1165 from vector-im/matthew/cancellable-upgrade
use new start_login_from_guest dispatch for cancellable logins from guest accounts
2016-03-16 14:37:50 +00:00
Mark Haines
1e0c4d8797 Merge pull request #1171 from vector-im/markjh/cleanup_promise
Use then() chaining rather than manual callbacks
2016-03-16 11:16:06 +00:00
Mark Haines
05e479a76c Use then() chaining rather than manual callbacks 2016-03-16 10:59:40 +00:00
Mark Haines
fe9816abf5 Merge pull request #1163 from vector-im/markjh/cleanup
Remove trailing whitespace
2016-03-16 10:52:12 +00:00
Matthew Hodgson
29815b1d13 try a new message tone 2016-03-16 00:54:43 +00:00
Matthew Hodgson
cb45db36c2 use new start_login_from_guest dispatch for cancellable logins from guest accounts 2016-03-15 21:02:25 +00:00
Mark Haines
31915db6f6 Remove trailing whitespace 2016-03-15 18:38:24 +00:00
Mark Haines
eb01cb9cba Merge pull request #1037 from vector-im/markjh/change_push_actions
Update the actions of default rules instead of overriding.
2016-03-15 18:10:04 +00:00
Matthew Hodgson
2a8afd49fb mx_Login_fieldLabel CSS 2016-03-15 18:09:54 +00:00
Mark Haines
9b85d88036 s/somme/some/ 2016-03-15 15:23:18 +00:00
Matthew Hodgson
c2049e991b padding for radio buttons on login pages 2016-03-15 13:37:07 +00:00
Mark Haines
3224a4e49e Add helper functions for decoding and encoding lists of push actions 2016-03-15 11:26:32 +00:00
Matthew Hodgson
cfc4b89225 fix https://github.com/vector-im/vector-web/issues/1154 2016-03-15 10:56:54 +00:00
Mark Haines
8b1444c954 Port the legacy im.vector rules to the new format on startup 2016-03-15 10:49:10 +00:00
Richard van der Hoff
d4d2ef326e Bump to dev branch of js-sdk 2016-03-14 15:54:56 +00:00
Richard van der Hoff
2a62fdb652 Switch back to dev version of react-sdk 2016-03-14 14:08:47 +00:00
Richard van der Hoff
6215326f8e Merge pull request #1137 from vector-im/rav/update_README
Update README to include `npm install` in react-sdk
2016-03-14 12:48:58 +00:00
Richard van der Hoff
da7e9840f3 reinstate npm 3 warning 2016-03-11 15:12:28 +00:00
Richard van der Hoff
cc18458bec Update README to include npm install in react-sdk
Casual users of /develop shouldn't need to do the whole
clone-three-repositories thing.
2016-03-11 15:09:29 +00:00
Richard van der Hoff
928915873b Use npm to fetch react-sdk and js-sdk
After some discussion, we've agreed it's less evil to have package.json point
to git develop, even if you then have to do a manual build step. That avoids
any future problems where (for example) js-sdk develop gains experimental
changes which would break for users using a build process which involves a
manual git checkout.
2016-03-11 14:30:53 +00:00
Richard van der Hoff
8fa059fc4b Prep 0.3.0 2016-03-11 13:00:31 +00:00
Richard van der Hoff
33b7e2046d Merge pull request #1123 from vector-im/rav/mute_desktop_notifs
Add setting for audio notifications
2016-03-10 14:19:05 +00:00
Richard van der Hoff
e777db3fc4 Add setting for audio notifications
Expose the enableAudioNotifications setting in the user settings panel.
2016-03-10 11:01:29 +00:00
Matthew Hodgson
a4d22ffe8c improve IS warning 2016-03-06 17:11:08 -05:00
Matthew Hodgson
622a4b0e4c improve cosmetics of login prompts slightly 2016-03-06 13:46:27 -05:00
Matthew Hodgson
7433f50c8c make settings button always visible 2016-03-04 23:16:36 +00:00
David Baker
9c82938b35 Merge pull request #1100 from vector-im/audio_notifications
Add audio tag for message notifications
2016-03-04 17:54:57 +00:00
David Baker
4e3985d446 Merge pull request #1102 from vector-im/dbkr/reenable_upgrade_registration
Re-enable upgrade registration.
2016-03-04 17:54:47 +00:00
David Baker
d732927dba Re-enable upgrade registration.
Revert https://github.com/vector-im/vector-web/issues/818 now that https://github.com/vector-im/vector-web/issues/759 is fixed.
2016-03-04 15:42:22 +00:00
David Baker
0343bd1022 Merge pull request #1098 from ajohnson23/audio_notifications
Added audio/source tags for message notifications.
2016-03-04 15:27:54 +00:00
Andrew Johnson
b75cb3c6cb Added audio/source tags for message notifications.
Signed-off-by: Andrew Johnson <ajohnson@draster.com>
2016-03-04 10:23:13 -05:00
Matthew Hodgson
2586280f2c add opera 2016-03-03 15:31:08 +00:00
Matthew Hodgson
516647ad04 fix placeholder opacity on moz 2016-03-03 15:31:02 +00:00
Matthew Hodgson
04fb8f9a81 de-kegan the CompatibilityPage :( 2016-03-03 15:22:12 +00:00
Matthew Hodgson
52f259ccfa explicit fg color for MessageComposer 2016-03-03 15:08:13 +00:00
Matthew Hodgson
f89fe4fff8 when we set an explicit form foreground colour, set an explicit background one too to prevent system-level dark themes on Linux etc making the foreground text unreadable 2016-03-03 14:37:11 +00:00
David Baker
adb6ab311c Merge pull request #1069 from vector-im/dbkr/directory_room_metadata
Display room metadata from room previews when we come from the public room directory
2016-03-02 14:35:29 +00:00
David Baker
b03e6a8d73 add comment explaining data passing hack 2016-03-02 14:34:31 +00:00
David Baker
2271ec7634 Display room metadata from room previews when we come from the public room directory (more hacks to work around the fact that we can't get this data from the HS) 2016-03-02 14:24:00 +00:00
David Baker
332354e5b6 Uncommit 71cb04c50a (I failed to branch) 2016-03-02 14:23:20 +00:00
David Baker
71cb04c50a Display room metadata from room previews when we come from the public room directory (more hacks to work around the fact that we can't get this data from the HS) 2016-03-02 14:21:32 +00:00
Mark Haines
3b2d0a6c01 Fix up reading the push rules 2016-02-29 16:56:33 +00:00
Mark Haines
731d94eea4 Update the actions of default rules instead of overriding.
The Matrix CS API, and synapse now supports setting the actions for default
rules. Doing that makes managing the rules much simpler from a vector
persepctive since the ON/LOUD/OFF toggle buttons can be implemented by
setting the actions and enabling/disabling the default rules rather than
overidding them.

Overriding the default rules was difficult because it was not possible
to intermingle the evaluation of user-specified rules with the default
rules. So even though you could add a rule with the same conditions as a
default rule, it would evaluate before *all* the other default rules.

Also creating new rules under a im.vector namespace creates challenges
if we want vector to cooperate with other matrix clients that want to
provide a similar set of toggle switches for the push rules.
2016-02-26 20:51:16 +00:00
Matthew Hodgson
c3b819b4da fix the version and improve changelog 2016-02-25 20:12:57 +01:00
Richard van der Hoff
c4b4f5a44a Merge remote-tracking branch 'origin/master' into develop 2016-02-25 17:32:59 +00:00
Richard van der Hoff
21410354ab Merge branch 'rav/jenkins_build' into develop 2016-02-25 16:59:44 +00:00
Richard van der Hoff
de50518282 s/version.txt/git-revision.txt/ 2016-02-25 16:57:34 +00:00
Richard van der Hoff
025a026f45 Use js-sdk and react-sdk from jenkins artifacts 2016-02-25 15:31:04 +00:00
David Baker
49525f22c2 Changelog 2016-02-25 12:10:30 +00:00
David Baker
642c33e8d9 Mention package script in readme 2016-02-25 10:47:09 +00:00
David Baker
fa322e8488 Auto-create a sensible version file. Copy the vector dir so we can put it in there rather than creating files in the main vector dir. 2016-02-24 18:59:33 +00:00
David Baker
874123bbfa Move package script out and make it tar into a versioned top level directory. It may as well be a shell script since it's unix specific anyway, and maintaining it inside package.json is now impractical. 2016-02-24 18:41:30 +00:00
David Baker
b088651211 Use the --tags option so it works with non-annoated tags (seriously, git?) 2016-02-24 15:05:13 +00:00
David Baker
a69c63cc60 Master is no longer stale. 2016-02-24 14:25:34 +00:00
David Baker
04b51f6f0f Merge branch 'develop' 2016-02-24 14:24:57 +00:00
David Baker
ebd5399626 Bump to version 0.2.0 2016-02-24 14:24:15 +00:00
David Baker
5d63d2269e Use newly released versions of js-sdk & react-sdk 2016-02-24 14:21:53 +00:00
David Baker
ef00bc6d56 Manually merge relevant remaining parts of https://github.com/vector-im/vector-web/pull/790 that aren't covered by @richvdh's PR. 2016-02-24 11:59:29 +00:00
David Baker
8e25a4ca36 Merge pull request #999 from vector-im/dbkr/more_readme_foolproofing
Make the README more idiot-proof
2016-02-24 11:50:13 +00:00
David Baker
1ecedd2769 Add back deployment info 2016-02-24 11:48:51 +00:00
David Baker
9c9e260410 Make the README more idiot-proof 2016-02-24 11:36:57 +00:00
David Baker
3f9f3e9d92 Merge pull request #998 from vector-im/rav/fix_the_sodding_deployment_instructions
Update the README to give clearer dev instructions
2016-02-24 11:24:48 +00:00
Richard van der Hoff
ca89c09e73 formatting 2016-02-23 21:00:27 +00:00
Richard van der Hoff
10f6277de2 Update the README to make the development instructions clearer 2016-02-23 20:55:37 +00:00
David Baker
acb443537a Merge pull request #997 from vector-im/dbkr/fix_new_room_crash
Sender can be null, so null check.
2016-02-23 18:12:42 +00:00
David Baker
55c7c08ac2 Sender can be null, so null check. 2016-02-23 17:59:13 +00:00
Richard van der Hoff
72393bf75f Merge branch 'rav/read_marker' into develop 2016-02-23 17:57:50 +00:00
David Baker
497cb8bc9c Merge pull request #993 from vector-im/dbkr/keypair_3pid_invites
Pass through params for other URLs
2016-02-23 11:08:28 +00:00
David Baker
a063efe250 Remove no-longer accurate comment. 2016-02-23 10:57:50 +00:00
David Baker
45c8500f28 Pass through params for other URLs (in this case, for keypair invite signing urls) 2016-02-23 10:22:22 +00:00
Richard van der Hoff
b04ce6a376 Fix default hs url after it was broken in 77b45e72 2016-02-22 17:07:26 +00:00
Matthew Hodgson
f2fc4a88ae gemini up roomdirectory 2016-02-22 09:35:11 +00:00
Matthew Hodgson
77b45e7231 oooooooops - remember opensans v13 2016-02-22 09:18:56 +00:00
Matthew Hodgson
484736bf57 oops, add sanitize-html 2016-02-21 00:05:44 +00:00
Matthew Hodgson
e91a108738 Merge pull request #972 from vector-im/matthew/room-directory
Skin RoomDirectory almost as per design
2016-02-20 23:59:02 +00:00
Matthew Hodgson
2ca5529faa support hyperlinked topics 2016-02-20 23:54:47 +00:00
Matthew Hodgson
a35ab6bcef tart up room directory 2016-02-20 13:36:48 +00:00
Matthew Hodgson
e33e9b5d4a upgrade OpenSans and add semibold 2016-02-20 13:36:33 +00:00
Matthew Hodgson
3910877f8f ensure local activity bumps rooms up the roomlist 2016-02-19 02:09:04 +00:00
Matthew Hodgson
f538a0d5de scale local video feed to fit on the page properly 2016-02-19 01:16:55 +00:00
Matthew Hodgson
4e5b971d3a accomodate 800px wide thumbs 2016-02-18 19:09:32 +00:00
Matthew Hodgson
ffb1584e10 horizontally scale images properly 2016-02-18 18:59:45 +00:00
Matthew Hodgson
dbf3439e35 fix statusbar layout some more 2016-02-18 18:13:23 +00:00
Matthew Hodgson
11ac6defed tint searchbar 2016-02-18 17:32:15 +00:00
Richard van der Hoff
718c1cbe6f Merge branch 'rav/update_status_bar' into develop 2016-02-17 21:16:22 +00:00
Matthew Hodgson
27222a54c7 somewhat cryptic hack to make empty RoomStatusBars not take up 41px rather than 36px of height 2016-02-17 18:54:46 +00:00
Matthew Hodgson
3263076ea6 Merge branch 'develop' into rav/update_status_bar 2016-02-17 18:37:40 +00:00
Matthew Hodgson
3c659dcf57 experimental fix for https://github.com/vector-im/vector-web/issues/947 and https://github.com/vector-im/vector-web/issues/946. may well introduce more problems 2016-02-17 12:43:42 +00:00
Matthew Hodgson
2cd3150c56 tart up mx_EventTile_selected 2016-02-15 20:22:45 +00:00
Matthew Hodgson
cdc1447804 fix search highlight css 2016-02-15 20:19:30 +00:00
Matthew Hodgson
11c9aff69a fix radiobutton css 2016-02-15 22:06:16 +02:00
Matthew Hodgson
58959d014a show vaguely accurate default avatar 2016-02-15 22:01:30 +02:00
Richard van der Hoff
1a9125a886 Fix horizontal alignment of top unread-messages bar 2016-02-15 18:10:11 +00:00
Matthew Hodgson
8e008572e5 CSS for setting display name prompt 2016-02-15 19:37:19 +02:00
Richard van der Hoff
18c6aa38e4 Styling and imgs to support new read_marker semantics
Support for adding a new 'Scroll up' bar in react-sdk
2016-02-15 17:22:55 +00:00
Matthew Hodgson
177fba360d shrink 3pid invite placeholder text 2016-02-15 11:13:24 +02:00
Matthew Hodgson
ad9935739c proper fix for https://github.com/vector-im/vector-web/issues/917 and resolve https://github.com/vector-im/vector-web/issues/928 2016-02-15 09:56:52 +02:00
Matthew Hodgson
a2193d61b0 show the leave button by default for now as it causes too much pain otherwise 2016-02-14 21:34:32 +02:00
Matthew Hodgson
0ca6efdfca fix the nightmarish https://github.com/vector-im/vector-web/issues/917 2016-02-14 21:28:01 +02:00
Matthew Hodgson
f3df0d07f8 filter room directory case insensitively 2016-02-14 13:32:15 +02:00
David Baker
95a3354b90 Merge pull request #914 from vector-im/dbkr/package_use_tar
Use tar for packaging because zip can't traverse directory symlinks
2016-02-11 15:09:49 +00:00
David Baker
82b498017d Bumb webpack micro version (although it would have installed the latest micro version anyway) to maybe get a webpack that doesn't throw stack depth errors. 2016-02-11 15:01:32 +00:00
David Baker
b929f80be8 Use tar for packaging because zip can't traverse directory symlinks, hence ditch windows support for packaging. 2016-02-11 14:59:22 +00:00
David Baker
05a30e7c68 Merge pull request #902 from vector-im/dbkr/add_package_script
Add 'package' script to build a webapp bundle
2016-02-11 14:18:06 +00:00
David Baker
3c75c43d37 Bail if build step fails 2016-02-11 13:59:40 +00:00
David Baker
369e357742 We expect the mkdir to fail when the dir exists, so use ; not && 2016-02-11 13:40:26 +00:00
David Baker
93f8fcbacc Add 'package' script to build a webapp bundle for straight unzipping on a production server. 2016-02-10 15:35:06 +00:00
Matthew Hodgson
155728b136 make babel actually do full ES6 emulation for Safari 8 2016-02-10 14:54:55 +00:00
David Baker
98551c3f9a Merge pull request #900 from vector-im/dbkr/parse_queries_in_hash
Always parse the hash of a URL as we do elsewhere
2016-02-10 13:51:36 +00:00
David Baker
1732805f31 Always parse the hash of a URL as we do elsewhere by looking for a query string part, otherwise we end up passing the query into showscreen which then spreads havok. 2016-02-10 13:45:24 +00:00
Matthew Hodgson
562a1d8836 USE DEVELOP! 2016-02-09 18:10:57 +00:00
Richard van der Hoff
bab9de1899 CSS fixes to match matrix-org/matrix-react-sdk#30b4b91.
This mostly works, but there is some weirdness with the status bar being too
high by default, and getting smaller when it has content in it.
2016-02-09 14:44:59 +00:00
Kegan Dougal
27791c06ee Cache-bust on /version request 2016-02-05 15:53:33 +00:00
David Baker
01bfb67b5b Merge branch 'dbkr/rate_limit_funcs' into develop 2016-02-05 10:58:18 +00:00
David Baker
485343864c semicolon 2016-02-05 10:57:49 +00:00
David Baker
842584177f Merge pull request #864 from vector-im/dbkr/rate_limit_funcs
Rate limit UI updates to avoid browser death
2016-02-05 10:16:03 +00:00
David Baker
ab9dfd185c Add note to not use npm start in production 2016-02-04 18:43:23 +00:00
David Baker
f035b8c50e Rate limit UI updates to avoid browser death 2016-02-04 18:09:24 +00:00
David Baker
15fec7f27c Merge pull request #862 from vector-im/dbkr/style_dialog_submit_button
Style submit input controls in dialogs the way we style buttons.
2016-02-04 15:07:44 +00:00
David Baker
c0c7ae1596 Style submit input controls in dialogs the way we style buttons. 2016-02-04 11:50:29 +00:00
Kegsay
6c5a00162c Merge pull request #856 from vector-im/kegan/version-stamp
Add a version update checker and NewVersionBar to show on the UI.
2016-02-03 17:09:24 +00:00
Kegan Dougal
b307a6d64e Invoke onVersion when we know the current version even if there is no new version (for settings) 2016-02-03 16:50:05 +00:00
Kegan Dougal
4628cf82a7 Split out response text to its own var to prevent trim() messing up comparisons 2016-02-03 16:23:17 +00:00
Kegan Dougal
5eed734325 Add a version update checker and NewVersionBar to show on the UI. 2016-02-03 16:16:14 +00:00
David Baker
f0a1f6d926 Merge pull request #846 from vector-im/dbkr/no_auto_join
Don't trigger room join from room directory: always peek / show join prompt bar
2016-02-03 15:52:05 +00:00
Kegan Dougal
deb1aa468f Listen on 0.0.0.0 and not localhost 2016-02-03 13:20:07 +00:00
Kegan Dougal
c76b1e7479 Actually listen on the right port 2016-02-03 13:11:51 +00:00
Kegan Dougal
4129c9bc24 Allow --symlink 2016-02-03 12:00:17 +00:00
Kegan Dougal
e22d36fc08 Add deploy directory with redeploy script 2016-02-03 11:26:24 +00:00
Kegan Dougal
043f6991a4 Dump vector/react/jssdk SHAs in filename 2016-02-02 17:03:48 +00:00
Kegan Dougal
2b0f4d5db1 Be more specific about the git dir 2016-02-02 16:29:25 +00:00
Kegan Dougal
1c267c69ac Include react SDK SHA in filename 2016-02-02 16:20:02 +00:00
Kegan Dougal
2a7b24e969 Update jenkins.sh to include the git commit 2016-02-02 16:09:33 +00:00
David Baker
d132c75263 Remove the autoPeek stuff and always either peek or show the join prompt bar 2016-02-02 15:51:23 +00:00
Kegan Dougal
b363eafbc8 Make jenkins.sh executable 2016-02-02 15:45:30 +00:00
Kegan Dougal
2986b241c4 Add jenkins.sh for builds 2016-02-02 15:44:41 +00:00
David Baker
d1dc082489 Remove empty if block 2016-02-01 18:02:52 +00:00
Richard van der Hoff
f94272c539 Add some crude CSS for highlighting the selected event
(To be useful, this needs functionality which hasn't yet landed in react-sdk).
2016-01-30 00:43:47 +00:00
David Baker
3b18b9b54b Fix connection lost bar CSS 2016-01-29 10:07:22 +00:00
David Baker
3585437af9 Merge pull request #800 from vector-im/dbkr/guest_warning_bar
CSS that changes the connection lost bar into a more general 'warning bar'
2016-01-28 13:44:09 +00:00
David Baker
6a36b022e4 New style guest warning bar 2016-01-28 13:00:44 +00:00
David Baker
35600f11ad CSS that changes the connection lost bar into a more general 'warning bar' so we can use it for a guest access warning 2016-01-28 09:19:28 +00:00
Matthew Hodgson
75886c4143 make badges scale with size of RoomTile 2016-01-24 14:50:24 -05:00
Matthew Hodgson
cd853ab5b4 try for a simpler invite placeholder look & feel 2016-01-24 19:02:49 +00:00
Matthew Hodgson
292af1e59c improve settings layout and fix FF bugs 2016-01-24 18:14:52 +00:00
Matthew Hodgson
d3bc0feb83 fix ugly wrapping bug 2016-01-24 17:54:01 +00:00
Matthew Hodgson
19bfd829d0 add scrollToBottomBar and fix spacing for status bars in general 2016-01-24 01:52:21 +00:00
Matthew Hodgson
759b318bb5 fix safari 2016-01-23 01:24:04 +00:00
Matthew Hodgson
dd19d2aaee red bar for highlights even if there's a unreadNotify too 2016-01-22 18:04:54 +00:00
Matthew Hodgson
e0ecde6760 put a black badge on unread notifications, and a red one for unread highlights 2016-01-22 17:23:04 +00:00
Matthew Hodgson
5e21059144 Merge pull request #729 from vector-im/matthew/truncateroomlist
truncate room list
2016-01-22 16:09:28 +00:00
Matthew Hodgson
0a32874b39 oops, reset truncate state on hide, not collapse 2016-01-22 16:09:06 +00:00
Kegan Dougal
302c63058b Invoke onShowMoreRooms to allow parents to kick their scrollbars.. 2016-01-22 15:46:58 +00:00
Matthew Hodgson
0ee1892a0b truncate room list 2016-01-22 15:31:42 +00:00
David Baker
12afbcbc45 Merge pull request #727 from vector-im/dbkr/rule_kinds
Add vector rules with the appropriate kind
2016-01-22 14:15:49 +00:00
David Baker
e11ae99a9f Add vector rules with the appropriate kind, otherwise the room_message rule takes precedence over content / display name rules etc and prevents bings. 2016-01-22 14:12:29 +00:00
Kegan Dougal
0752c3a6d5 Add start:prod - same as 'npm run start' but with NODE_ENV=production 2016-01-22 13:17:09 +00:00
manuroe
87f3603047 Merge pull request #721 from vector-im/push-rules-dont-notify
Push settings: Use a dont_notify rule when 1:1 or group chat rooms are set to OFF
2016-01-22 11:37:58 +01:00
manuroe
ce45f0b1e6 Push settings: Use a dont_notify rule when 1:1 or group chat rooms are set to OFF 2016-01-22 09:30:31 +01:00
Matthew Hodgson
a76167d175 correct layout for truncated lists 2016-01-21 17:38:46 +00:00
manuroe
3a23189435 Merge pull request #716 from vector-im/push-rules-add-bot-rule
Added notif settings for "Messages sent by bot" (#692)
2016-01-21 16:39:19 +01:00
manuroe
f3064a2994 Put back removing of "When people join or leave a room" settings push rule 2016-01-21 16:37:17 +01:00
manuroe
029cf754ee Added notif settings for "Messages sent by bot" (https://github.com/vector-im/vector-web/issues/692)
In order to do that, the rules definitions have been update to support "dont_notify" hs default push rules
2016-01-21 16:16:44 +01:00
David Baker
1a248c8e5c Merge pull request #710 from vector-im/unread_sync
Use read receipts to calculate unread room status
2016-01-21 13:29:49 +00:00
David Baker
568f9bb19d Merge pull request #713 from vector-im/dbkr/remove_member_event_rule
Remove member event rule as per SYN-607
2016-01-21 12:30:03 +00:00
David Baker
b913e72735 Remove member event rule as per SYN-607 2016-01-21 12:01:28 +00:00
David Baker
4d4c6e06ec Merge remote-tracking branch 'origin/develop' into unread_sync 2016-01-21 10:39:35 +00:00
David Baker
2d917910da Merge pull request #556 from vector-im/notif_sync
Use unread count for room highlight state
2016-01-21 10:31:46 +00:00
David Baker
0a70fe2bd1 Argh, revert accidental config commit 2016-01-21 10:30:52 +00:00
David Baker
a08d00c672 Apply patch to the right branch: update for new count format 2016-01-21 10:20:45 +00:00
Matthew Hodgson
bd75234a2f make CSS work on FF 2016-01-21 00:39:26 +00:00
Matthew Hodgson
6573ba8c20 fix up Start Chat behaviour as per Amandine's feedback 2016-01-21 00:16:26 +00:00
Matthew Hodgson
f4a2b6ab7e Merge pull request #697 from vector-im/matthew/roompreview
Lots of CSS bugfixes and polishing
2016-01-20 22:32:08 +00:00
Matthew Hodgson
6117e09a3f implement the correct design for memberlist 2016-01-20 22:04:32 +00:00
Matthew Hodgson
1fd60f1e44 revert read marker css 2016-01-20 17:23:33 +00:00
David Baker
d979511696 Re-remove extra icons as they break favico 2016-01-20 17:20:34 +00:00
David Baker
ac2e69ba28 Use new unread count methods 2016-01-20 17:20:19 +00:00
Matthew Hodgson
48052415b7 usersettings button layout 2016-01-20 17:09:53 +00:00
Matthew Hodgson
e87e22a438 rhsbutton 2016-01-20 17:06:13 +00:00
Matthew Hodgson
5b2f921190 Fix bold avatar letters 2016-01-20 17:01:19 +00:00
Matthew Hodgson
b830f43371 remove RoomAvatar; stale border-radius; fix aliases table 2016-01-20 16:59:53 +00:00
Matthew Hodgson
6332e3908e roomsettings css fixes 2016-01-20 16:39:14 +00:00
Matthew Hodgson
82742f9f13 oops, fix tinted read up to marker correctly 2016-01-20 16:06:35 +00:00
manuroe
39eb0f9c8f Merge pull request #687 from vector-im/push-rules-call-settings-fix
Fixed call push notifications settings that always stayed OFF
2016-01-20 17:06:01 +01:00
manuroe
888fde0f53 Fixed call push notifications settings that always stayed OFF 2016-01-20 17:01:09 +01:00
David Baker
eb62456007 Update for new unread count format 2016-01-20 15:58:21 +00:00
Matthew Hodgson
60d2d45255 readd in the .mx_EntityTile_power class. don't understand why it was killed :'( 2016-01-20 15:39:42 +00:00
Matthew Hodgson
6ecdb02e81 sanitize avatar border radii 2016-01-20 15:26:48 +00:00
Matthew Hodgson
4d3918109a skin new invite UI CSS 2016-01-20 14:58:27 +00:00
Matthew Hodgson
9a9db53e0a fix tinting of read marker again 2016-01-20 14:58:17 +00:00
Kegsay
ad6a19a0df Merge pull request #668 from vector-im/matthew/roompreview
Support non-guest peeking
2016-01-19 16:09:36 +00:00
Matthew Hodgson
3e8c6a42d3 roomsettings layout tweaks 2016-01-18 19:58:02 +00:00
Matthew Hodgson
3b8e5073b5 improve layout 2016-01-18 19:57:32 +00:00
Matthew Hodgson
a775086e81 wording from amandine 2016-01-18 19:57:17 +00:00
Matthew Hodgson
d5c291ae62 Merge branch 'kegan/invite-search' into matthew/roompreview 2016-01-18 18:00:58 +00:00
Matthew Hodgson
d6f6f32c74 WIP to support non-guest peeking, and slightly improve roomdirectory look & feel for now 2016-01-18 17:37:13 +00:00
Kegan Dougal
317e1fb9cd Merge branch 'develop' into kegan/invite-search 2016-01-18 17:33:26 +00:00
manuroe
37e8a35967 Merge pull request #641 from vector-im/push-rules-settings
Push rules settings
2016-01-18 18:25:31 +01:00
manuroe
6182c983ab PushRules settings: Applied review remarks (2/2) 2016-01-18 18:24:53 +01:00
Kegan Dougal
ac4b221690 More CSS fun for border bottom 2016-01-18 17:22:02 +00:00
manuroe
fdf5b0a4fc Merge branch 'develop' into push-rules-settings
# Conflicts:
#	src/skins/vector/css/matrix-react-sdk/structures/UserSettings.css
2016-01-18 18:14:20 +01:00
manuroe
7c0fffa79b PushRules settings: Applied easy review remarks 2016-01-18 18:07:33 +01:00
Kegan Dougal
fef02f2fd1 s/MemberTile/EntityTile/ 2016-01-18 16:43:00 +00:00
manuroe
bdcf683942 PushRules settings: Create a dedicated rule for "Messages sent to group".
The default fallback rule cannot be used because it matches with too much events.
2016-01-18 16:41:48 +01:00
manuroe
ae14210763 PushRules settings: Put keywords in the right position 2016-01-18 16:31:18 +01:00
manuroe
830160f074 PushRules settings: Enabled all radio buttons of the table.
Each rule is described in the code so that if the server does not have it in its default rules or if the user wants to use actions different from the hs one, the code will create a new rule that will override the hs one.
2016-01-18 16:24:06 +01:00
Matthew Hodgson
0ef03c5ca4 Merge pull request #653 from vector-im/matthew/roomsettings2
Finish off RoomSettings (part 2)
2016-01-18 13:39:55 +00:00
Matthew Hodgson
5a1b0a1dab Merge pull request #657 from vector-im/matthew/memberlist
Fix up MemberList and MemberInfo cosmetics a bit
2016-01-18 13:39:42 +00:00
Kegan Dougal
77621fe035 Add missing CSS from #638 2016-01-18 12:06:46 +00:00
Kegsay
7e40d81a44 Merge pull request #638 from vector-im/kegan/base-avatar
CSS for BaseAvatar
2016-01-18 10:17:57 +00:00
Matthew Hodgson
8792be4db2 moar space 2016-01-18 01:25:57 +00:00
Matthew Hodgson
1fef91b82c MemberInfo lipstick 2016-01-18 01:18:11 +00:00
Matthew Hodgson
b2a1c89e83 bring back power badges 2016-01-18 00:16:04 +00:00
Matthew Hodgson
40d2018c17 fix checkbox css 2016-01-17 12:26:54 +00:00
Matthew Hodgson
a61afa0f31 fix css thinko 2016-01-17 02:46:22 +00:00
Matthew Hodgson
4e7c58e242 fix broken icon 2016-01-17 02:46:15 +00:00
Matthew Hodgson
8771369937 more layout 2016-01-15 20:29:44 +00:00
Matthew Hodgson
394fb2373b more layout tweaks for RoomSettings 2016-01-15 16:50:12 +00:00
Matthew Hodgson
eb8064f961 fix cursors for changeavatar 2016-01-15 16:32:39 +00:00
Matthew Hodgson
531aa153bb no more textarea in roomsettings 2016-01-15 16:32:23 +00:00
manuroe
d7ffe70d44 PushRules settings: Applied Amandine's review comments 2016-01-15 17:28:57 +01:00
Kegan Dougal
17489ae350 s/MemberAvatar/BaseAvatar/ and rename classes 2016-01-15 16:12:28 +00:00
Matthew Hodgson
762dd69f0a more bottom margin on editable roomheader 2016-01-15 15:48:29 +00:00
manuroe
cb8b052dc0 PushRules settings: Show unmanaged rules into an "advanced section" 2016-01-15 16:45:27 +01:00
Matthew Hodgson
1fcb4ba94f droptarget and usersettings and roomsettings layout tweaks 2016-01-15 15:26:00 +00:00
David Baker
ea6ed81517 Merge pull request #630 from vector-im/read_marker_position
Shift read marker down by 5px
2016-01-15 13:57:25 +00:00
manuroe
2dd2acd4e0 PushRules settings: BF adding a keyword when the keywords rule is OFF 2016-01-15 14:28:50 +01:00
Matthew Hodgson
41ae851df4 fix up user settings CSS somewhat 2016-01-15 12:34:01 +00:00
manuroe
c3469b5b51 PushRules settings: coding: separate UI and data management 2016-01-15 11:33:54 +01:00
manuroe
7412fc7f97 PushRules settings: changed wordings 2016-01-15 10:51:42 +01:00
Matthew Hodgson
d1f26e3911 camera icon 2016-01-14 17:26:16 +00:00
Matthew Hodgson
c1aac1aaca roomsetting icons 2016-01-14 17:25:21 +00:00
Matthew Hodgson
f2fa9fe398 Merge branch 'develop' into matthew/roomsettings2 2016-01-14 16:49:48 +00:00
David Baker
a65a15e9bb Shift read marker down by 5px 2016-01-14 16:45:13 +00:00
Matthew Hodgson
9ada5f7ddd CSS for tab complete slashcommands 2016-01-14 16:29:03 +00:00
Matthew Hodgson
17e540d372 fix line wrapping of code blocks in multiline msgs 2016-01-14 11:57:07 +00:00
Kegsay
db2d7fdbff Merge pull request #622 from vector-im/kegan/3pid-invite-memberlist
CSS for email invite memberlist fix
2016-01-14 10:45:50 +00:00
Kegan Dougal
927ac5fe64 2016 only 2016-01-14 10:45:38 +00:00
manuroe
378f4bb85c PushRules settings: Display keywords in alphabetical order 2016-01-14 11:15:59 +01:00
manuroe
0577edb055 PushRules settings: Added master push rule 2016-01-14 11:03:51 +01:00
David Baker
513c7e3b73 Uncommit unintentional config change 2016-01-13 17:59:13 +00:00
Matthew Hodgson
56718650b9 fix comedy double-margin caused by killing off MessageTiles 2016-01-13 17:39:57 +00:00
Matthew Hodgson
e3eef45684 fix comedy double-margin caused by killing off MessageTiles 2016-01-13 17:39:49 +00:00
Matthew Hodgson
68f846e129 Merge branch 'develop' into matthew/roomsettings2 2016-01-13 17:33:32 +00:00
Matthew Hodgson
ad434cb82e GA bugfix 2016-01-13 17:33:06 +00:00
Matthew Hodgson
f2171c11f0 uncommitted WIP roomsetting CSS 2016-01-13 17:33:03 +00:00
manuroe
629883731e PushRules settings: BF when adding a new keyword with the keywords rule in Off 2016-01-13 17:56:59 +01:00
manuroe
0475bcd9de PushRules settings: BF when changing state of the keywords rule with such a sequence: on -> off -> loud. 2016-01-13 17:10:26 +01:00
Kegan Dougal
1d5e661bd0 Split out css for new PresenceLabel 2016-01-13 15:56:44 +00:00
manuroe
ac87830e4e PushRules settings: Applied new wordings: On, Loud, Off 2016-01-13 16:48:22 +01:00
manuroe
7fc5ab3c6e PushRules settings: Use the new TextInputDialog to display keywords list. We earn the focus at the end of the keywords list and the management of enter and esc keys 2016-01-13 16:36:57 +01:00
manuroe
c4cb37606b PushRules settings: Added sanity checks on new keywords 2016-01-13 15:47:00 +01:00
manuroe
e5b7a47fee PushRules settings: if a newly typed keyword was part of a push rule not managed by the Vector UI, delete the rule and create it compliant with Vector parameters 2016-01-13 12:00:04 +01:00
manuroe
1c03c208e1 PushRules settings: update keywords list hs side 2016-01-13 11:46:13 +01:00
Kegsay
7232659195 Merge pull request #612 from vector-im/kegan/guest-peek-then-join
Add css for room preview bar.
2016-01-13 10:37:13 +00:00
manuroe
10d3076d6b PushRules settings: Display keywords modal dialog 2016-01-13 09:11:56 +01:00
David Baker
cae3ab410f Merge pull request #603 from vector-im/read_marker_animate
New CSS for read markers
2016-01-12 17:58:36 +00:00
Kegan Dougal
2bada93fdc CSS for forgot password link 2016-01-12 16:39:29 +00:00
manuroe
9fb8c9f67a PushRules settings: Use a workaround for SYN-590 (Push rule update fails) 2016-01-12 17:33:57 +01:00
manuroe
b9080c770d PushRules settings: Fixed triage of matrix content rules into the unique Vector rule 2016-01-12 16:46:27 +01:00
David Baker
977b223929 Hopefully working CSS that doesn't cause the messages to jump about when a read marker disappears. 2016-01-12 14:20:05 +00:00
manuroe
7f95362dd2 PushRules settings: Translate matrix per-word rules into the global Vector rule for a list of keywords 2016-01-12 15:12:58 +01:00
Kegan Dougal
f706f75a6e Add css for room preview bar. 2016-01-12 14:11:00 +00:00
Matthew Hodgson
fc3f356dc0 GA 2016-01-12 01:23:39 +00:00
manuroe
6d510db2db PPushRules settings: Fixed React warnings 2016-01-11 17:32:37 +01:00
manuroe
ee13dd7b6c PushRules settings: Added a dedicated component to display them 2016-01-11 17:24:04 +01:00
Kegsay
f898986c73 Merge pull request #594 from vector-im/kegan/guest-access
Enable guest access
2016-01-11 15:21:57 +00:00
David Baker
6cd0aeb607 Revert 4px offset: it ends up in the middle of the line above 2016-01-11 10:56:08 +00:00
David Baker
1e57aa8c78 Make read up to line 2px and position relative so we can shift it up a little 2016-01-11 10:52:29 +00:00
Matthew Hodgson
93c4fc8785 switch EditableText to contentEditable; fix auxPanel layout bug in the general case (not just for video) 2016-01-10 13:04:15 +00:00
Matthew Hodgson
8a156dcac8 Merge pull request #605 from vector-im/matthew/roomsettings
fix leave.svg so that it can be tinted
2016-01-09 21:25:50 +00:00
Matthew Hodgson
d49f8721ce fix leave.svg so that it can be tinted 2016-01-09 00:56:10 +00:00
David Baker
c02d9890c5 New CSS for read markers 2016-01-09 00:09:11 +00:00
Matthew Hodgson
dfcc923c91 Merge pull request #599 from vector-im/matthew/roomsettings
CSS and imagery for fixed up RoomSettings
2016-01-08 11:26:34 +00:00
Matthew Hodgson
ccd518cc4c CSS and imagery for fixed up RoomSettings 2016-01-08 03:26:07 +00:00
Kegan Dougal
a369c862a0 Hit MatrixClient.peekInRoom on rooms we can only peek into. 2016-01-07 14:57:26 +00:00
Kegan Dougal
1a8a4728cd Enable guest access. Show r/w icons on room directory. 2016-01-07 14:43:12 +00:00
Matthew Hodgson
d2635373f0 Merge pull request #585 from vector-im/matthew/dynamic-svg
Make SVGs and CSS dynamically recolourable
2016-01-07 11:41:46 +00:00
David Baker
5b4457d33c Merge pull request #591 from vector-im/green_line
Add CSS for the green read-up-to marker.
2016-01-07 11:40:11 +00:00
David Baker
36e5ac3d7f Add CSS for the green read-up-to marker. 2016-01-07 11:22:41 +00:00
Matthew Hodgson
df111223fc copyrights for 2016 2016-01-07 04:17:56 +00:00
David Baker
c0f1ae0133 Use Unread to compute unread status of a room (which uses read receipts). 2016-01-06 18:29:27 +00:00
David Baker
c96ce482bc Remove the extra icons as they break the js favicon library, and should be unnecessary because the additional sizes are muxed into the ico file. 2016-01-06 17:36:30 +00:00
Matthew Hodgson
eacadbff40 remove stale onSvgLoad 2016-01-06 02:29:20 +00:00
Matthew Hodgson
cb29a04674 use factored out TintableSvg component for dynamic SVGs 2016-01-06 02:11:34 +00:00
Matthew Hodgson
f9a34d21c8 Merge branch 'develop' into matthew/dynamic-svg 2016-01-06 01:11:47 +00:00
Matthew Hodgson
bb313d1f3c vertical-align room messages to the bottom of the page 2016-01-05 18:49:47 +00:00
Matthew Hodgson
a1bdfaa8a2 vertical-align room messages to the bottom of the page 2016-01-05 18:49:21 +00:00
Matthew Hodgson
1df4f2d556 fix hyperlink position for image downloads 2016-01-05 03:38:53 +00:00
Matthew Hodgson
b996022db2 fix up dynamically loaded svgs, and fix bottomleftmenu 2016-01-05 03:34:25 +00:00
Matthew Hodgson
bbf08d99cc tinterize more svg 2016-01-05 00:47:26 +00:00
Matthew Hodgson
17b8982c75 move title attributes to the div 2016-01-03 22:35:07 +00:00
Matthew Hodgson
3abdcbf806 switch SVGs from imgs to objects, fixing CSS to make onClicks work 2016-01-03 22:30:14 +00:00
Matthew Hodgson
a78a693903 Merge pull request #581 from vector-im/matthew/css-refactor
shuffle around all the CSS to de-atomify it and make it match react components
2016-01-03 00:14:52 +00:00
Matthew Hodgson
b9a0b82537 shuffle around all the CSS to de-atomify it and make it match the react components 2016-01-03 00:10:17 +00:00
Matthew Hodgson
10e481a8d5 noscript 2015-12-28 03:25:26 +00:00
Matthew Hodgson
fa4bd09f0c fix room header height 2015-12-28 02:27:47 +00:00
Matthew Hodgson
8dd90980d8 add cancel button for lightbox and pare down pointer-events stuff a bit 2015-12-28 02:15:23 +00:00
Matthew Hodgson
e9db7b1dcc doh 2015-12-28 01:41:51 +00:00
Matthew Hodgson
388eb1ff4c use Open Sans, and fix duplication 2015-12-28 01:38:14 +00:00
Matthew Hodgson
647c01fe2a where did this img symlink go? all iamges break without it... 2015-12-28 01:34:28 +00:00
Matthew Hodgson
0ab8466a3b make tabcomplete items clickable 2015-12-24 15:12:24 +00:00
Kegan Dougal
94609db3a6 Wrangle CSS to get avatar on UserSettings in the right place 2015-12-24 09:21:02 +00:00
Kegan Dougal
f9f85ec542 More user settings CSS 2015-12-23 16:53:19 +00:00
Kegan Dougal
d3938220cf Duplicate css for applying to mx_EditableText classes so it works with ChangeDisplayName 2015-12-23 14:13:24 +00:00
Kegsay
73d9ef54c3 Merge pull request #384 from vector-im/matthew/settings
WIP experiment of turning UserSettings into a controller-less component
2015-12-23 10:23:39 +00:00
David Baker
755ea0dfb8 Merge remote-tracking branch 'origin/develop' into notif_sync 2015-12-22 14:46:57 +00:00
Matthew Hodgson
f681ce5cdb add CSS for TabCompleteBar 2015-12-22 00:47:33 +00:00
Matthew Hodgson
ceadfef942 fix missing webkit prefixes for flexbox 2015-12-21 23:20:44 +00:00
Matthew Hodgson
f665848c5e speed up search anim 2015-12-21 23:20:10 +00:00
Matthew Hodgson
031b048c07 fix missing webkit prefixes for flexbox 2015-12-21 23:19:53 +00:00
Matthew Hodgson
d82c4c5ef3 fix safari flexbox bug 2015-12-21 23:16:44 +00:00
Matthew Hodgson
ae02d8d30a Merge branch 'develop' into matthew/settings 2015-12-21 13:10:34 +00:00
Matthew Hodgson
85db381153 Merge pull request #550 from vector-im/kegan/archived-rooms
Kegan/archived rooms
2015-12-21 12:39:48 +00:00
Matthew Hodgson
67aff6b9f2 adopt MacOS style chevrons 2015-12-21 12:37:51 +00:00
Matthew Hodgson
50aa988a34 fix layout 2015-12-21 12:37:50 +00:00
Matthew Hodgson
fdc94ccf98 ensure even hyperlinks are highlighted 2015-12-21 12:37:50 +00:00
David Baker
cb1fabc578 Highlight status is now the room's unread notif count 2015-12-18 17:53:31 +00:00
Kegsay
59f419b310 Merge pull request #541 from vector-im/kegan/archived-rooms
Add more props to RoomSubList
2015-12-18 17:36:16 +00:00
Kegan Dougal
dcea0dd601 Move min-height to RoomList; remove bottommost prop 2015-12-18 17:13:57 +00:00
Kegan Dougal
dc1e2010a6 Merge branch 'develop' into kegan/archived-rooms 2015-12-18 17:00:20 +00:00
Matthew Hodgson
d7b87743f3 Merge pull request #533 from vector-im/matthew/inbound-calls
position the inbound call box correctly
2015-12-18 15:59:05 +00:00
Kegan Dougal
7cc1573f33 Add startAsHidden and showSpinner props to RoomSubList
startAsHidden: Previously we never started in the hidden state and all was well.
But with archived rooms you DO want to start hidden as you haven't fetched the
room list yet. Without this, you need to click twice (close/open) before the
archived room list will load.

showSpinner: If true, will show a spinner iff there are 0 elements being displayed.
Used when fetching the archived room list in RoomList.
2015-12-18 15:17:18 +00:00
Kegan Dougal
f7c4cca675 Add TODO after spending 15 mins trying to figure out the difference between props.collapsed and state.hidden 2015-12-18 13:32:22 +00:00
Kegan Dougal
869c08a790 Add onHeaderClick and alwaysShowHeader props to RoomSubList for archived room clicking 2015-12-18 11:56:22 +00:00
Matthew Hodgson
a7b9e54594 Merge branch 'develop' into matthew/settings 2015-12-18 00:36:46 +00:00
Kegsay
5f3a1cb6e1 Merge pull request #537 from vector-im/kegan/3pid-inv
Pass through the starting query params from the URL
2015-12-17 16:43:13 +00:00
Kegan Dougal
63d0477223 Pass through the starting query params from the URL 2015-12-17 15:01:07 +00:00
Matthew Hodgson
1a90a2c426 position the inbound call box correctly, and fix various issues with when the video preview and callview are shown 2015-12-17 02:53:53 +00:00
Kegsay
856156ef5c Merge pull request #527 from vector-im/kegan/hide-fs-user
Pass a userId rather than a RoomMember to isConferenceUser
2015-12-16 13:56:50 +00:00
Kegan Dougal
c8ca1dd8d0 Pass a userId rather than a RoomMember to isConferenceUser
Because invites do not have RoomMembers because we don't have an m.room.member
event for them, just a user ID, and we want to detect conf users at invite
time.
2015-12-16 11:55:13 +00:00
Matthew Hodgson
d945050de6 fix typing notifs 2015-12-15 15:59:40 +00:00
Matthew Hodgson
d3ecce2d2e add fullscreen button 2015-12-15 00:01:32 +00:00
Matthew Hodgson
a495aecdd8 assets for VoIP and DnD file upload 2015-12-14 23:38:24 +00:00
Matthew Hodgson
c553258aff add dedicated leave button to header 2015-12-13 13:49:54 +00:00
Matthew Hodgson
9c8984b308 fix vertical alignment of voip buttons 2015-12-13 04:14:20 +00:00
Matthew Hodgson
c2061ed439 revert dd08f53756 - do this in JS instead 2015-12-13 04:08:35 +00:00
Matthew Hodgson
96cddc5ca8 fix layout for long room names & topics 2015-12-12 17:30:08 +00:00
Matthew Hodgson
dd08f53756 don't let auxpanel push out the height of the roomview 2015-12-12 17:15:45 +00:00
Matthew Hodgson
056017007a improve look and feel of upload cancel 2015-12-12 16:41:32 +00:00
Matthew Hodgson
7cfca3ff4d Merge pull request #499 from vector-im/rav/mute_icon
Add a 'muted' icon for voip calls
2015-12-11 15:32:08 +00:00
Richard van der Hoff
c36d1df417 Add a 'muted' icon for voip calls
... because even a crappy one is better than nothing
2015-12-11 15:00:25 +00:00
Matthew Hodgson
762281cd96 fix vertical spacing of roomheader 2015-12-11 03:39:13 +00:00
Matthew Hodgson
898cb399a3 show results 2015-12-11 02:58:47 +00:00
Matthew Hodgson
3fb0c9883b escape key to cancel search box 2015-12-11 02:32:30 +00:00
Matthew Hodgson
f2fb1836df only flash whilst searching 2015-12-11 02:25:51 +00:00
Matthew Hodgson
fea3fed460 animate the search button whilst searching 2015-12-11 02:24:58 +00:00
Matthew Hodgson
4c82d86092 nice green highlights 2015-12-11 01:35:05 +00:00
Matthew Hodgson
1c9d61d731 dedicated search button 2015-12-11 01:19:48 +00:00
Matthew Hodgson
7b702c4594 don't grey out invites randomly 2015-12-11 00:40:40 +00:00
Matthew Hodgson
d6bcf80431 make the settings button more discoverable by having the whole leftRow be a hover target 2015-12-10 19:48:05 +00:00
Matthew Hodgson
e26efd475c preload warning.svg - fixes bug https://github.com/vector-im/vector-web/issues/455 2015-12-09 13:52:04 +00:00
Matthew Hodgson
9d15bf2847 clean up broken renaming of /icons 2015-12-09 13:24:56 +00:00
Matthew Hodgson
8ecf70dda0 show images with unknown height - fixes issue 475 hopefully 2015-12-09 13:24:15 +00:00
Matthew Hodgson
4b8d7a612a make the mx_RoomView_statusAreaBox_line full width as per the ribot design 2015-12-08 19:45:30 +00:00
Richard van der Hoff
1d97a5f06b Merge pull request #470 from vector-im/rav/olm
HOWTO encryption
2015-12-08 16:03:54 +00:00
Richard van der Hoff
f8e5bbef0b Add a link to E2E bug in the README 2015-12-08 16:03:12 +00:00
Matthew Hodgson
b532fd046a actually use SVGs - oops 2015-12-08 10:28:00 +00:00
Matthew Hodgson
a8e24802ab rename icons to avoid namespace clash with /icons 2015-12-08 10:27:42 +00:00
Kegsay
862ab0c115 Merge pull request #477 from vector-im/kegan/resending
Make unsent messages behave better
2015-12-07 17:00:30 +00:00
Kegan Dougal
2f905e13e1 Invoke onFinished so the context menu doesn't hang around 2015-12-07 16:04:46 +00:00
Kegan Dougal
39778330b5 Also allow not_sent messages to be cancelled entirely. 2015-12-07 13:55:10 +00:00
Kegan Dougal
1af1297afc Allow queued events to be cancelled. Make not sent events appear differently to sending events. 2015-12-07 11:38:34 +00:00
Matthew Hodgson
da5c687320 svgize coloured icons 2015-12-06 22:06:21 +00:00
David Baker
25eeaaf1e5 Use UnreadStatus to determine whether an event affects a room;s unread status. Unify rooms going bold with their sort order and don't go bold for m.notify. 2015-12-04 16:24:17 +00:00
Kegan Dougal
ac8fcbb264 Force update the RightPanel when the member in MemberInfo is updated. 2015-12-04 16:16:41 +00:00
Richard van der Hoff
759e35003b Put some warnings on the crypto stuff 2015-12-04 15:39:39 +00:00
Richard van der Hoff
97dd4e2e6b Merge branch 'develop' into rav/olm
Conflicts:
	webpack.config.js
2015-12-03 18:28:50 +00:00
Richard van der Hoff
56b7b65920 Notes on building a crypto-enabled version 2015-12-03 18:25:20 +00:00
Richard van der Hoff
782174069c Include olm in the webpack if it's been installed
.. to make it easy to build a crypto-enabled vector
2015-12-03 18:24:34 +00:00
David Baker
db5d9e2f6e Merge pull request #465 from vector-im/file_uploads
Move upload bar CSS to new classes
2015-12-03 10:58:03 +00:00
David Baker
547f59b1bc Oops, don't re-add these. 2015-12-03 10:00:29 +00:00
David Baker
2d2386ace5 Move upload bar CSS to new classes, and move into new, temporary place (since there is no new-style structure yet). 2015-12-02 18:19:03 +00:00
Matthew Hodgson
c603c1e37f dezalgo typing notigs on chrome 2015-12-02 17:37:19 +00:00
Matthew Hodgson
de144cf4cd uh, actually include Open Sans webfont :-/ 2015-12-02 15:13:41 +00:00
David Baker
8df62e3b02 Merge pull request #454 from vector-im/require-css
Build CSS with webpack
2015-12-02 10:26:41 +00:00
David Baker
939733b736 Merge branch 'develop' into require-css 2015-12-02 10:26:26 +00:00
Kegsay
6db1151699 Merge pull request #453 from vector-im/kegan/vector-references
Add vector-specific branded components
2015-12-02 09:38:39 +00:00
Kegan Dougal
0210670e91 Merge branch 'develop' into kegan/vector-references
Conflicts:
	src/component-index.js
2015-12-02 09:37:28 +00:00
Kegan Dougal
d837d02ac9 Still add highlight.js as an import as we symlink directly to the node_module for github.css :/ - Fixes ENOENT 2015-12-02 09:26:12 +00:00
Matthew Hodgson
cba27a7488 erm, surely we need to actually run reskindex after all that? 2015-12-02 01:37:26 +00:00
Matthew Hodgson
349a88d640 stop clobbering our font colours 2015-12-01 21:44:22 +00:00
David Baker
95e71a531e Merge branch 'develop' into kegan/vector-references
Update having merged skindexing PR
2015-12-01 18:31:13 +00:00
David Baker
d2c6e2195e Merge pull request #447 from vector-im/skindex-nextgen
Update skindexing for new world order
2015-12-01 18:12:47 +00:00
David Baker
a63bf7cb35 Merge branch 'develop' into skindex-nextgen 2015-12-01 18:10:57 +00:00
David Baker
7ff5e42f3e Run the CSS through webpack so we can pull in CSS files from modules with require rather than symlinking into the node_module directory which is breaking people on different npm versions. 2015-12-01 18:05:43 +00:00
Matthew Hodgson
2c12b9128b highlight binged rooms more clearly 2015-12-01 16:57:49 +00:00
Kegan Dougal
e21d435d84 Remove debug logging 2015-12-01 16:57:40 +00:00
Kegan Dougal
a2b28b826c Add CustomServerDialog for vector 2015-12-01 16:48:51 +00:00
Kegan Dougal
8d31f72f83 Add VectorLoginHeader 2015-12-01 16:27:23 +00:00
Kegan Dougal
e304a1925d Add VectorLoginFooter with vector references 2015-12-01 16:12:38 +00:00
Kegsay
819b80d30f Merge pull request #450 from vector-im/kegan/vector-components
Move remaining Vector-only components to src/components
2015-12-01 15:58:55 +00:00
David Baker
c281fe785a Merge branch 'develop' into skindex-nextgen 2015-12-01 15:53:11 +00:00
Kegan Dougal
8083e7f118 Move vector-only components to src/components. 2015-12-01 15:45:38 +00:00
David Baker
5098c7d16f Merge branch 'develop' into skindex-nextgen 2015-12-01 15:44:45 +00:00
Kegan Dougal
e07c03a7bb Merge branch 'develop' into kegan/vector-components 2015-12-01 15:39:02 +00:00
Kegsay
e7f6e09def Merge pull request #448 from vector-im/kegan/controller-merging4
Phase 4 controller merging
2015-12-01 15:34:25 +00:00
Matthew Hodgson
075d2b508d fix highlights on markdown 2015-12-01 13:13:51 +00:00
Kegan Dougal
e55e2bdd0d Remove unused class 2015-12-01 11:22:19 +00:00
Kegan Dougal
2a025201b1 Move remaining vector molecules to be components in vector (for now) 2015-12-01 11:19:54 +00:00
Matthew Hodgson
f89dcacf07 fix bottomleftmenu layout a bit 2015-12-01 11:11:32 +00:00
Matthew Hodgson
99f47b8601 match design spacing correctly 2015-12-01 11:07:12 +00:00
Matthew Hodgson
1896ab67d1 fix room avatar offset 2015-12-01 11:05:11 +00:00
Matthew Hodgson
2bc3b665d2 Merge pull request #445 from vector-im/matthew/new-font
switch to Open Sans
2015-12-01 10:59:05 +00:00
Kegan Dougal
8f5f71ec80 Move MatrixChat to react-sdk. Move all login stuff to react SDK.
Removed Modulator stuff.
2015-11-30 18:10:09 +00:00
David Baker
021056cfd1 Move copyright header 2015-11-30 18:00:54 +00:00
David Baker
6a4038daeb Add 'replaces' tag to mark that the RoomDNDView is a RoomTile 2015-11-30 17:56:55 +00:00
David Baker
cadfbcbed3 Merge branch 'develop' into skindex-nextgen 2015-11-30 17:56:40 +00:00
David Baker
6f646260aa WIP of component indexing update 2015-11-30 17:31:32 +00:00
Matthew Hodgson
badfdb5e3e actually, seems FF is happy with this again now 2015-11-30 17:24:38 +00:00
Matthew Hodgson
2345624d31 switch to Open Sans, juggling font-size appropriately (as Open Sans is physically larger for the same point size as Myriad Pro, irritatingly), and fix some really weird baseline CSS bugs in read receipts that were introduced. Hopefully this doesn't re-introduce the intermittent baseline offset bug for the initials on Chrome & FF 2015-11-30 17:17:09 +00:00
Kegan Dougal
ddc4f30bb6 Remove RoomView and port it to react-sdk. Move Resend.js to react-sdk 2015-11-30 17:16:31 +00:00
Kegan Dougal
4e7aa78ed7 Move RoomList to react-sdk. Inject a ConferenceHandler. 2015-11-30 16:56:05 +00:00
Kegan Dougal
e792ebb837 Move and merge UserSettings to react-sdk 2015-11-30 15:53:13 +00:00
Matthew Hodgson
4409f07c2e oops, don't try to delete nonexistent tags when moving a room from conversations to favs or similar 2015-11-30 15:49:27 +00:00
Kegan Dougal
b89bd35cad Merge branch 'develop' into kegan/controller-merging4 2015-11-30 15:42:32 +00:00
Matthew Hodgson
4614017b8f Merge pull request #443 from vector-im/matthew/rename-message-components
Matthew/rename message components
2015-11-30 15:36:50 +00:00
Matthew Hodgson
7636645efc rename message components as per RL discussion this morning 2015-11-30 15:25:21 +00:00
Kegan Dougal
bd906cbc69 Move and merge LogoutPrompt to react-sdk 2015-11-30 15:23:37 +00:00
Kegan Dougal
cb30cbb09a Remove MemberList and put it in react-sdk 2015-11-30 15:14:04 +00:00
Kegan Dougal
2b37e5334a Remove Notifier and put it in react-sdk 2015-11-30 15:05:00 +00:00
Matthew Hodgson
f947400131 Open Sans 2015-11-30 14:17:33 +00:00
Kegan Dougal
fd4d7eba12 Remove ErrorDialog and QuestionDialog to react-sdk 2015-11-30 14:11:28 +00:00
Matthew Hodgson
8a00e71139 remove spurious Vector layer Avatar helper class 2015-11-30 13:56:53 +00:00
Kegan Dougal
83b3702769 Merge branch 'develop' into kegan/controller-merging4 2015-11-30 10:56:14 +00:00
Kegan Dougal
450b2d4d67 Move CreateRoom to react-sdk 2015-11-30 10:55:52 +00:00
Matthew Hodgson
cd040ae0dd fix zalgo properly! remove ugly regexp hacks for detecting combining diacritics and instead set the right font ordering, as Arial combines nicely with Myriad Pro whilst Helvetica doesn't. (Myriad Pro itself has no combining diacritic characters) 2015-11-30 01:13:59 +00:00
Matthew Hodgson
9a64dc27fc improve layout for search results, fix syntax highlighting quirks in sublime, and don't crash on zero results 2015-11-29 13:32:13 +00:00
Matthew Hodgson
af6bd53d38 revert 23d45d7f33 and apply a better fix which works for both chrome & FF 2015-11-29 13:18:37 +00:00
Matthew Hodgson
01f0e61d6e fix search ordering; add room labels; hide input areas if searching 2015-11-29 04:41:17 +00:00
Matthew Hodgson
fc02331cd3 fix CSS for search timestamps 2015-11-29 03:20:19 +00:00
Matthew Hodgson
e43edee9bb call highlighted search terms highlights, and uphold them if provided by synapse 2015-11-29 03:19:51 +00:00
Matthew Hodgson
8de94d45b1 swim like a salmon and manually update skindex for a generic TextualMessage type 2015-11-28 21:11:37 +00:00
Matthew Hodgson
9e97160c85 fix inline <code/> blocks 2015-11-27 16:20:37 +00:00
Kegsay
8a5828620c Merge pull request #425 from vector-im/kegan/controller-merging3
Phase 3 controller merging
2015-11-27 16:17:39 +00:00
Kegan Dougal
07001ae35e Remove unused files 2015-11-27 16:11:58 +00:00
Kegan Dougal
cd216e218c Merge branch 'develop' into kegan/controller-merging3 2015-11-27 15:44:52 +00:00
Kegsay
054836cd50 Merge pull request #421 from vector-im/kegan/controller-merging2
Phase 2 controller merging (all atoms)
2015-11-27 15:43:49 +00:00
Kegan Dougal
0ef7c8d16d Use the right name 2015-11-27 15:43:16 +00:00
Kegan Dougal
af30ef1f72 Remove unusued imports 2015-11-27 15:39:29 +00:00
Kegan Dougal
df86e85492 Move ContextualMenu to React SDK 2015-11-27 15:37:00 +00:00
Kegan Dougal
05c9b44b81 Move velocity stuff to react sdk 2015-11-27 15:34:26 +00:00
Kegan Dougal
0f3ea9f4ce Merge branch 'develop' into kegan/controller-merging2 2015-11-27 15:01:23 +00:00
Kegan Dougal
a5d00c73b2 Move HtmlUtils to react SDK 2015-11-27 15:01:06 +00:00
Kegsay
f9a5f4b61e Merge pull request #420 from vector-im/kegan/controller-merging
Phase 1 controller merging (general structure)
2015-11-27 14:59:38 +00:00
Kegan Dougal
40b974f22d Move all Event/Message Tiles to React SDK. 2015-11-27 14:35:16 +00:00
Kegan Dougal
f969ccb50c Move and merge RoomTile/MemberTile to react SDK. Keep DND stuff in vector as RoomDNDView. 2015-11-27 11:52:29 +00:00
Kegan Dougal
b007edca63 Merge and move RoomHeader/RoomSettings into React SDK 2015-11-27 10:42:25 +00:00
Kegan Dougal
3ce29622ed Move and merge MemberInfo to React SDK 2015-11-26 17:49:55 +00:00
Kegan Dougal
1a6afc2ef0 Move and merge UserSelector 2015-11-26 17:38:01 +00:00
Kegan Dougal
6dea8e7256 Move and merge MessageComposer 2015-11-26 17:31:37 +00:00
Kegan Dougal
7595071e6a Move and merge ProgressBar 2015-11-26 17:21:35 +00:00
Kegan Dougal
fdad00790e Move and merge Change* components to React SDK. Update references. 2015-11-26 17:11:26 +00:00
Kegan Dougal
9ecf5bed64 Nuke old CallView controller 2015-11-26 16:48:32 +00:00
Kegan Dougal
ff9608c914 Move and merge voip molecules. Inject the ConferenceHandler as a prop
This keeps the vector conf logic munge separate from react SDK.
2015-11-26 16:39:58 +00:00
Kegan Dougal
49e5f18f62 Move and merge create_room atoms to react SDK 2015-11-26 15:43:57 +00:00
Kegan Dougal
c5b0ea7e9f Move VideoFeed to React SDK 2015-11-26 15:24:32 +00:00
Kegan Dougal
83eae1b64a Move and merge EditableText into React SDK 2015-11-26 15:15:45 +00:00
Kegan Dougal
35ee9c9ddd Move and merge EnableNotificationsButton to react SDK 2015-11-26 15:10:49 +00:00
Kegan Dougal
0a8f5b6223 Move ImageView 2015-11-26 14:51:30 +00:00
Kegan Dougal
3f120c7027 Nuke LogoutButton; nothing used it. 2015-11-26 14:47:11 +00:00
Kegan Dougal
343670c5c4 Move MessageTimestamp 2015-11-26 14:38:48 +00:00
Kegan Dougal
f21b6203ed Merge branch 'kegan/controller-merging' into kegan/controller-merging2 2015-11-26 14:31:31 +00:00
Kegan Dougal
8517f9f2bf Missed one 2015-11-26 14:29:26 +00:00
Kegan Dougal
3c12191cb7 Move Spinner 2015-11-26 14:25:20 +00:00
Kegan Dougal
ab22ca6a28 Also move the existing login components to the new structure 2015-11-26 14:11:45 +00:00
Kegan Dougal
8898b444af Point things at the right places 2015-11-26 13:48:37 +00:00
Kegan Dougal
d079617ce2 Nuke MemberAvatar/RoomAvatar; moved to react SDK 2015-11-26 13:25:56 +00:00
Matthew Hodgson
93c67771af Merge pull request #324 from vector-im/erikj/video
Add basic m.video view support
2015-11-24 16:06:11 +00:00
Matthew Hodgson
f9040e08ce fix conflicts 2015-11-24 16:05:58 +00:00
Matthew Hodgson
fd8864d528 STOP PEOPLE SHOUTING 2015-11-22 22:35:34 +00:00
Matthew Hodgson
841c790337 naughty override to stop RoomList panel scrolling horizontally 2015-11-22 15:47:50 +00:00
Matthew Hodgson
324c3e7dcf override more GFM css 2015-11-22 15:47:10 +00:00
Matthew Hodgson
92728ff4e6 spell out npm run build 2015-11-22 01:13:08 +00:00
Matthew Hodgson
01641543da only try to syntax highlight html 2015-11-21 12:33:45 +00:00
Matthew Hodgson
9038b984ff fix css link 2015-11-21 12:15:38 +00:00
Matthew Hodgson
da97185fcd highlight <code/> blocks via highlight.js 2015-11-21 12:14:56 +00:00
Matthew Hodgson
b6e9c1eaab oops, forgot gfm.css 2015-11-20 20:20:30 +00:00
Matthew Hodgson
76c6d6d4d6 add target=_blank onto all HTML links, and apply GFM.css for CSS for markdown 2015-11-20 20:12:23 +00:00
Matthew Hodgson
4c11de787e make h2 layout specific to the list 2015-11-20 20:11:06 +00:00
Matthew Hodgson
96c825b89f wrap whitespace on notices 2015-11-20 20:10:49 +00:00
Matthew Hodgson
29af81e827 Refactor HTML markup stuff into its own class, and whitelist h1 and h2 2015-11-20 18:58:13 +00:00
David Baker
3cf9f5248b Fix the ref we keep to be the react element and make velociraptor correctly track what nodes it had at the start (c.key not c.props.key) 2015-11-20 18:22:38 +00:00
Kegsay
9ec10e2b43 Merge pull request #404 from vector-im/kegan/gif-on-enter
Add support for playing gifs on mouse enter/leave
2015-11-20 16:43:05 +00:00
Kegan Dougal
06427d663d Add support for playing gifs on mouse enter/leave 2015-11-20 16:36:58 +00:00
David Baker
2c51a5c199 Bugfix: don't cache the read avatar rect as it's relative to the viewport and it will move when we scroll! 2015-11-20 16:01:51 +00:00
Kegsay
6dc5dd4930 Merge pull request #403 from vector-im/kegan/post-register
Re-add in post registration steps
2015-11-20 15:06:19 +00:00
Kegan Dougal
29ee7d2b13 Remove useless logging 2015-11-20 14:34:26 +00:00
Kegan Dougal
2e376b1eb9 Clear the 'screen' to load the main left/middle/right panels, then show the settings after post-reg is done 2015-11-20 14:27:39 +00:00
Kegan Dougal
37254e6243 Add PostRegistration component 2015-11-20 12:02:37 +00:00
Kegan Dougal
1edea2a62c Add a PostRegistration component; hook it up to MatrixChat. 2015-11-20 12:02:23 +00:00
Kegsay
99ccff098c Merge pull request #399 from vector-im/kegan/reg-refactor
Refactor registration
2015-11-20 10:28:26 +00:00
Kegan Dougal
3075c97bae Set busy Spinner 2015-11-20 10:27:21 +00:00
Kegan Dougal
f62312fbf3 Remove old registration files. Move CaptchaForm to React SDK. 2015-11-20 10:18:04 +00:00
Matthew Hodgson
02d5154aaf more alt tags 2015-11-19 17:45:03 +00:00
Matthew Hodgson
41eaf18470 add hoverover test for edit button 2015-11-19 17:43:55 +00:00
Kegan Dougal
d372018e61 Minor tweaks 2015-11-19 16:47:14 +00:00
Kegan Dougal
bb6eeea0d8 Factor out div ID name to avoid tight coupling with logic class. 2015-11-19 16:08:25 +00:00
Kegan Dougal
3cf9f786aa Instantiate Signup.Register in Registration component
This has to be done rather than in MatrixChat because the render() calls
will create new instances otherwise. Pass in all the strings the logic class
requires to the Registration wire component. This isn't the "best" solution
because unloading/reloading the Registration component will lose registration
state which should be persisted. Ideally we'd DI from the top to ensure this
can't happen (as opposed to relying on module globals...)
2015-11-19 15:44:17 +00:00
Kegan Dougal
2d481a6302 Recheck registration state since we may be able to immediately do an HTTP hit if we've been given good QPs 2015-11-19 14:17:18 +00:00
Kegan Dougal
e700a5a219 Add TODO on post register logic 2015-11-19 13:58:52 +00:00
Matthew Hodgson
f7127ab701 Merge pull request #397 from vector-im/z_indices
Sort out dialog z index so read receipts avatars are behind the dialog background
2015-11-19 13:53:51 +00:00
Kegan Dougal
eaafc11064 Factor out Captcha UI 2015-11-19 13:44:11 +00:00
Richard van der Hoff
3a003341ad Merge pull request #387 from vector-im/rav/suppress_unread_on_memberchange
Don't mark rooms as unread on m.room.member changes
2015-11-19 13:22:37 +00:00
David Baker
f7fe871fee If read receipts avatar isn't on screen, animate it from the top of the screen. 2015-11-19 11:33:15 +00:00
David Baker
09b0d221df Kill the last getDOMNode() 2015-11-19 11:03:33 +00:00
David Baker
ed3d3a9e23 Shift css around a bit so it more closely matches DOM order 2015-11-19 10:49:24 +00:00
David Baker
eb1c6b347d Move z-index to the dialog wrapper because that's the shallowest positioned element in the DOM and therefore what creates the first stacking context 2015-11-19 10:46:49 +00:00
Kegan Dougal
5f57cd9559 Merge branch 'develop' into kegan/reg-refactor 2015-11-19 09:50:08 +00:00
David Baker
0dd85d9adf Hidden localstorage option to enable bouncy read receipts :p 2015-11-19 09:44:24 +00:00
Matthew Hodgson
23d45d7f33 fix initials behaviour on FF 2015-11-18 23:46:43 +00:00
Matthew Hodgson
69fdd485e6 general faff to make the new edit button position interact properly with dave's 'click to show all read receipts' 2015-11-18 23:41:38 +00:00
Matthew Hodgson
bf3e90bb47 dirty hack to fix the uneven spacing 2015-11-18 23:04:12 +00:00
Matthew Hodgson
68a005bf1f stop edit option from colliding with scrollbar again 2015-11-18 22:24:54 +00:00
Matthew Hodgson
884d0de90b s/React/ReactDOM/ to fix another 0.14 warning 2015-11-18 22:22:19 +00:00
Matthew Hodgson
6e3afcde53 dodgy fudge to put the edit button alongside the read receipts. in future I think we should turn it into a chevron next to the timestamp 2015-11-18 22:19:21 +00:00
Matthew Hodgson
d66006893a fix react 0.14 warning from getDOMNode() 2015-11-18 22:10:08 +00:00
Matthew Hodgson
8fed464cf6 and the new voice icon 2015-11-18 21:18:16 +00:00
Matthew Hodgson
08ba0457e8 add a temporary voice call button 2015-11-18 21:17:58 +00:00
Matthew Hodgson
098491e350 avoid hoverover artefacts on avatar initials 2015-11-18 20:56:43 +00:00
Matthew Hodgson
46541a3f2e logout button on splashscreen to avoid wedging users whose server has gone awol 2015-11-18 20:47:14 +00:00
Matthew Hodgson
c9fe0b96b7 fix whitespace 2015-11-18 20:46:39 +00:00
Matthew Hodgson
742ae354e5 clicking anywhere in the composer pane should focus on the textarea 2015-11-18 20:15:15 +00:00
Kegan Dougal
bc55959fad Load the Recaptcha script if we have a container for it
This is complex enough that the Registration component shouldn't have to
care about it, so it should probably be split into a pure UI component.
2015-11-18 17:46:17 +00:00
Kegan Dougal
5424567a66 Hook up onFormSubmit to make registration (dummy only) work again. 2015-11-18 17:15:20 +00:00
David Baker
f0df3f29b9 Show all read avatars on click 2015-11-18 17:12:17 +00:00
Kegan Dougal
b4c0625961 Show validation errors 2015-11-18 15:32:44 +00:00
David Baker
025b9e2fc8 depend on react sdk dev 2015-11-18 14:54:32 +00:00
David Baker
1099892784 Merge pull request #379 from vector-im/read_receipts
Read receipts
2015-11-18 14:53:29 +00:00
Richard van der Hoff
c42d4f901b Don't mark rooms as unread on m.room.member changes
A quick and hacky fix to issue #169.
2015-11-18 11:01:47 +00:00
Kegan Dougal
ed3527e243 Merge branch 'develop' into kegan/reg-refactor 2015-11-17 17:43:22 +00:00
Kegan Dougal
8e8b27c893 Add RegistrationForm UI component and new Registration wire component
Hook it up to MatrixChat instead of the existing logic (this breaks reg). WIP.
2015-11-17 17:40:31 +00:00
David Baker
c63dd376d8 Fix member avatar initials (I failed at git conflict merging) 2015-11-17 17:31:03 +00:00
David Baker
da55081c68 Add member name to avatars as the title since if displayed without accompanying text (as with read receipts) they can be somewhat unhelpful. May as well have them all the time I think. 2015-11-17 15:59:44 +00:00
David Baker
80c2bd0c7f Remove bouncing, set animation time to be constant (prevents temporary overalpping) and exclude ourselves. 2015-11-17 15:51:00 +00:00
Kegan Dougal
714c96283e Setting defaults from config.json got lost 2015-11-17 15:12:55 +00:00
Kegan Dougal
c57fb44c71 Fix path resolution 2015-11-17 13:26:23 +00:00
Kegan Dougal
8602e0665d PR feedback from #355 2015-11-17 10:57:44 +00:00
Kegsay
af1e3373ea Merge pull request #355 from vector-im/kegan/login-refactor
Refactor login page
2015-11-17 10:47:56 +00:00
Matthew Hodgson
79e39429b7 add todo 2015-11-17 02:40:19 +00:00
Matthew Hodgson
7b3eea0b58 experiment with trying to turn UserSettings into a controller-less 'wiring component' which wires together a series of smaller components (in this case, so small they're mainly <input/s> 2015-11-17 02:15:55 +00:00
Matthew Hodgson
88c5a5e074 missing copyright 2015-11-17 02:14:06 +00:00
David Baker
e23b90abd5 More s/messageWrapper/messagePanel/ 2015-11-16 16:52:07 +00:00
David Baker
7f61a0252f remove logging 2015-11-16 16:45:28 +00:00
David Baker
816f20e068 comma 2015-11-16 16:36:01 +00:00
David Baker
bb59e9276b Merge remote-tracking branch 'origin/develop' into read_receipts 2015-11-16 16:33:39 +00:00
David Baker
d6b86598e5 Bouncy bouncy! 2015-11-16 16:13:21 +00:00
Matthew Hodgson
bf91155e60 implement multiline input 2015-11-15 03:36:10 +00:00
Matthew Hodgson
ef181f55d5 make modal dialogs higher in z-index 2015-11-14 00:14:41 +00:00
Matthew Hodgson
1c7e7cd111 kill stale z-index param 2015-11-14 00:13:13 +00:00
Matthew Hodgson
063e387a65 turn off the placeholder drag & drop function to get an opinion from folks 2015-11-13 23:51:48 +00:00
Matthew Hodgson
ca07c8f429 Merge pull request #365 from vector-im/avatar_initial_a11y
Mark up the avatar initials so they're not read out by screen readers
2015-11-13 18:37:10 +00:00
Matthew Hodgson
2fd7196cdd also handle a11y on room avatars 2015-11-13 18:36:46 +00:00
Matthew Hodgson
ff59fc84c5 don't bold the selected room just because, as it bold = new msgs 2015-11-13 18:25:10 +00:00
David Baker
9d620dfb1d Hopefully now mostly complete animations: we iterate through zero or more start states and then settle on the final place. 2015-11-13 16:43:54 +00:00
David Baker
bc2c744bed more bits of read receipt animation implemented 2015-11-13 11:42:51 +00:00
David Baker
2fabf69ce3 Mark up the avatar initials so they're not read out by screen readers 2015-11-13 09:28:56 +00:00
Matthew Hodgson
f8d628d336 fix composer avatar 2015-11-13 02:44:46 +00:00
Matthew Hodgson
20f84ce322 override gemini-scrollbar CSS to stop the scrollview from pushing out the container, causing FF's flexbox to adapt and keep growing infinitely 2015-11-13 02:29:59 +00:00
Matthew Hodgson
2cf0ceb260 back out previous bodges to flexbox to make geminiscrollbar work in FF 2015-11-13 02:29:18 +00:00
Matthew Hodgson
36b7deac35 clear unread message count more aggressively (and revert previous thinko) 2015-11-13 01:42:09 +00:00
Matthew Hodgson
04305460db make firefox slightly happier 2015-11-13 01:19:40 +00:00
Matthew Hodgson
caa2fd97d1 sacrifice dead goats to make gemini-scrollbars work on firefox 42 and chrome 48 and later. the problem is that flexbox interacts badly with gemini-scrollbars, as gemini looks at the offsetWidth of the container in order to make the width of its enclosed scrollable view = width+scrollbarwidth. The problem is that flexbox then sees that the scrollable view has expanded, and unhelpfully flexes the container to fit it. This fixes the problem by providing more explicit widths for the containers to stop them flexing. I'm not sure I want to know why we don't also see the same problem with heights. 2015-11-13 00:46:50 +00:00
David Baker
e0efb6862e Merge pull request #354 from vector-im/ignore-non-mxc
Display some sensible UI for non-mxc content URLs.
2015-11-12 17:43:20 +00:00
David Baker
1ac47f32fe Fix scrolling on browsers where gemini scrollbars don't kick in. 2015-11-12 17:18:22 +00:00
Kegan Dougal
b1438355e2 Github and Sublime don't like this not being escaped. Displays fine though in React like this. 2015-11-12 15:58:12 +00:00
Kegan Dougal
021eaf5c29 Vector is the default IS in Vector 2015-11-12 15:54:07 +00:00
Kegan Dougal
726afd30bb Swap old login for new 2015-11-12 15:49:32 +00:00
Kegan Dougal
58472b8251 Move Cas/PasswordLogin to react-sdk. Use them as normal components. 2015-11-12 15:38:04 +00:00
Kegan Dougal
8826eb60cc Call through to password login 2015-11-12 15:16:29 +00:00
David Baker
c8a8306165 Display some sensible UI for non-mxc content URLs. 2015-11-12 14:16:57 +00:00
Matthew Hodgson
c12c716dc0 fix URLs on image 2015-11-12 13:34:00 +00:00
Kegan Dougal
05eda88ea2 Split out logic/UI for logging in
- Add 'PasswordLogin' UI component
- Add 'LoginPage' wire component which, along with Signup from react SDK,
  replaces the 'Login' page.
- Move UI code (state/props) from ServerConfig which was lobotomoised in the
  React SDK.

Unfinished.
2015-11-12 11:57:33 +00:00
Matthew Hodgson
2cae5e7a00 revert bad fix to managing history 2015-11-11 02:31:37 +01:00
Matthew Hodgson
2fff6f4d5f fix spinner layout yet more 2015-11-11 02:31:17 +01:00
Matthew Hodgson
81128ef06e hopefully fix https://github.com/vector-im/vector-web/issues/226 2015-11-11 02:07:41 +01:00
Matthew Hodgson
dd3427d8d0 remove unused component 2015-11-11 02:01:11 +01:00
Matthew Hodgson
2c9273a86c avoid the initial sync from clobbering the location bar 2015-11-11 02:00:51 +01:00
Matthew Hodgson
bc3ee949f5 fix warning about missing thead 2015-11-11 02:00:18 +01:00
Matthew Hodgson
5aa468f1e3 skin simpleheader 2015-11-11 01:59:56 +01:00
Matthew Hodgson
c2af09fbaa fix Spinner CSS a bit 2015-11-11 00:57:31 +01:00
Matthew Hodgson
bbd7124ac7 improve comment on how our dynamic height CSS works 2015-11-11 00:57:16 +01:00
Matthew Hodgson
adb7915b3e suppress warning 2015-11-11 00:56:51 +01:00
Matthew Hodgson
5c92b09da1 improve spacing on login screen 2015-11-11 00:56:44 +01:00
Matthew Hodgson
2e9e03bd45 oops, refresh the login options on mount. make autofocus work too. 2015-11-11 00:39:48 +01:00
Matthew Hodgson
19b31ff30d oops, make this actually work. 2015-11-11 00:06:49 +01:00
Matthew Hodgson
801154fd8a apply jsx 2015-11-11 00:05:35 +01:00
Matthew Hodgson
f628591e27 fix login page vertical scroll and centering 2015-11-10 19:19:23 +00:00
Matthew Hodgson
9cbd4ae2e4 fix raging typos 2015-11-10 19:15:14 +00:00
Matthew Hodgson
0825e0a2e2 retrieve last used HS/IS URL from local storage, and associated tweaks 2015-11-10 19:09:24 +00:00
Matthew Hodgson
68c1ddd5d2 replace react-loader with Spinner everywhere 2015-11-10 18:12:26 +00:00
David Baker
9a6624d1c7 Do read receipt avatars with absolute positioning: this should be a lot easier to animate. Also mess around with the MemberAvatar a bit so it's easier to style. 2015-11-10 17:44:59 +00:00
David Baker
c9823d07fd Limit number of read avatars, lay them out as per the design & order them. 2015-11-10 13:51:11 +00:00
David Baker
450036a6ed Merge remote-tracking branch 'origin/develop' into read_receipts 2015-11-10 11:26:42 +00:00
Matthew Hodgson
ef7a38e558 gemini scrollbar on the memberlist too 2015-11-10 02:26:46 +00:00
Matthew Hodgson
2ca64d9c15 add gemini-scrollbar to the main roomview 2015-11-10 02:04:21 +00:00
Matthew Hodgson
cb887c699e use gemini-scrollbar to provide fake scrollbars for the room list 2015-11-10 01:40:08 +00:00
Matthew Hodgson
2ccd881665 port to react 0.14, removing getDOMNode()s for DOM components and turning them into ReactDOM.findDOMNode()s for React components 2015-11-09 23:54:10 +00:00
Matthew Hodgson
87bb7c9b7b upgrade to react 0.14 2015-11-09 23:13:46 +00:00
Matthew Hodgson
6d9817e5e7 Merge pull request #342 from vector-im/matthew/orderable-roomlist
Implement reorderable rooms via room tagging.
2015-11-09 16:05:00 +00:00
Matthew Hodgson
23c93de82e Merge branch 'develop' into matthew/orderable-roomlist 2015-11-09 16:04:20 +00:00
Matthew Hodgson
bea64082a9 put the DragDropContext on LeftPanel rather than MatrixChat to allow index.js to continue to abuse MatrixChat by directly invoking the showScreen method on it 2015-11-09 15:44:08 +00:00
Kegsay
c3385d597a Merge pull request #332 from vector-im/kegan/syncing
Implement connection lost bar + resend all
2015-11-09 15:35:38 +00:00
Matthew Hodgson
752f8bdbb8 remove random bold initials 2015-11-09 14:04:43 +00:00
Matthew Hodgson
1f69760173 fix comedy scrolling parallax avatar initial bug 2015-11-09 12:41:23 +00:00
Matthew Hodgson
66add5673b de-hash rooms 2015-11-09 11:53:50 +00:00
Matthew Hodgson
a3082753ef shove initials onto default room & member avatars as per the design 2015-11-09 02:12:26 +00:00
Matthew Hodgson
eaa2f94327 warning png 2015-11-09 00:13:40 +00:00
Matthew Hodgson
615879ffdd skin to match CSS (spacing will need to be fixed once matthew/ordered-roomlist lands) 2015-11-09 00:13:25 +00:00
Matthew Hodgson
05d921256f re-skin the notification bar 2015-11-08 23:37:14 +00:00
Matthew Hodgson
9526deb024 add error dialogs and order search results by recents 2015-11-08 16:19:53 +00:00
Matthew Hodgson
567176ea6c put a load of margin on the bottommost sublist to increase its hit target size and avoid problems when toggling its hiddenness 2015-11-08 14:08:17 +00:00
Matthew Hodgson
5494a4ea6c s/deprioritize/demote/ 2015-11-08 13:50:36 +00:00
Matthew Hodgson
827c0da33c commented out debug 2015-11-08 13:42:45 +00:00
Matthew Hodgson
f0dbb422f6 update the actual target list, which may not be the same as the one we dropped on 2015-11-08 13:13:01 +00:00
Matthew Hodgson
5c406856ed adjust column widths to match design 2015-11-08 12:59:19 +00:00
Matthew Hodgson
b15def84bc fix spacing of the layout to match latest designs 2015-11-08 12:48:23 +00:00
Matthew Hodgson
bbbe074d92 hide all the debugging behind if (debug) 2015-11-08 12:24:32 +00:00
Matthew Hodgson
36da1accca click on CallView preview to jump to call 2015-11-08 12:14:10 +00:00
Matthew Hodgson
e289235e17 fix tooltip positioning when collapsed 2015-11-08 12:02:26 +00:00
Matthew Hodgson
c60e8736c1 handle collapsed drop-targets better 2015-11-08 11:50:15 +00:00
Matthew Hodgson
69899e3718 position sublist chevron better when collapsed 2015-11-08 11:44:13 +00:00
Matthew Hodgson
ed4c5b9f73 switch initial spinner to mx_Spinner 2015-11-07 20:16:44 +00:00
Matthew Hodgson
4e170a2831 fix onRoomTags signature 2015-11-07 20:16:05 +00:00
Matthew Hodgson
07200d7953 Merge branch 'develop' into matthew/orderable-roomlist 2015-11-07 17:29:18 +00:00
Matthew Hodgson
4a195dd3f0 sacrifice a small mountainside of goats to make placeholder-based work correctly 2015-11-07 02:57:56 +00:00
Matthew Hodgson
fe442f5c24 fix various edge cases when dragging stuff back to the conversations list 2015-11-06 23:30:57 +01:00
Matthew Hodgson
89327bd38f precedence fail :( 2015-11-06 21:33:28 +01:00
Matthew Hodgson
f102e3b3b7 collapsible sublist graphics 2015-11-06 21:25:35 +01:00
Matthew Hodgson
1150e22190 collapsible sublists 2015-11-06 21:25:20 +01:00
Matthew Hodgson
886ffbf158 switch to m.* prefixes for tags before it's too late 2015-11-06 21:00:34 +01:00
Matthew Hodgson
c884c5fc33 actually manage manual ordering; support arbitrary tags; bug fixes 2015-11-06 20:54:07 +01:00
David Baker
d462e0b21b Merge pull request #335 from stevenhammerton/sh-cas-token-login
Replace CAS login with token login
2015-11-06 15:41:15 +00:00
Steven Hammerton
fdf79d709e Replace CAS login with token login 2015-11-06 11:22:59 +00:00
David Baker
e20388388e null check 2015-11-05 17:40:37 +00:00
Kegan Dougal
3a8c263e8e Add resending bar (and resend all option)
Factor out resend logic which was in the context menu into a separate
Resend file (it shouldn't be in the skin, but it also isn't really
suitable for a controller given 2 different views invoke it..)
2015-11-05 15:59:03 +00:00
Kegan Dougal
804af341ac Add a 'connection lost' bar. 2015-11-05 14:52:44 +00:00
David Baker
0aa90d918c bump js-sdk dep to develop 2015-11-05 14:45:16 +00:00
David Baker
4bf6992398 Don't send read receipts for our own events and null check in a few places. 2015-11-05 14:16:15 +00:00
Matthew Hodgson
8842147ec3 skin RoomDropTarget correctly 2015-11-05 11:21:45 +00:00
David Baker
942659df0d Work around the bug where some channels have no name from the js sdk which was causing vector to exception and never load. 2015-11-04 14:15:57 +00:00
Matthew Hodgson
61e55b3ca3 implement most of drag & drop. 2015-11-04 02:25:08 +00:00
Matthew Hodgson
7fe7af6026 refactor out the sections of the RoomList into RoomSubLists. Start wiring up tags 2015-11-04 00:19:37 +00:00
Erik Johnston
7dc5f91fad Remove unused code 2015-11-03 18:59:45 +00:00
Erik Johnston
5b773b99c0 Add basic m.video view support 2015-11-03 18:56:55 +00:00
Matthew Hodgson
8b9b268ec0 make our state explicit 2015-11-03 14:35:55 +00:00
Matthew Hodgson
27cf9cf561 put invites above recents 2015-11-03 14:35:48 +00:00
Matthew Hodgson
b1b2704bed avoid racey NPE on first login 2015-11-03 14:35:39 +00:00
David Baker
2a4a02f36e More on read receipts: listen for events, add keys & class / very minimal css. 2015-11-03 13:44:40 +00:00
Matthew Hodgson
ff35e02b4d Merge pull request #317 from vector-im/erikj/icons
Use relative rather than absolute paths for icons
2015-11-02 23:53:27 +00:00
Erik Johnston
4dac9bc1b8 Use relative rather than absolute paths for icons 2015-11-02 23:47:04 +00:00
David Baker
11c38014e5 Sort of display read avatars but without live updating 2015-11-02 18:55:28 +00:00
Kegsay
842d6b6c2c Merge pull request #314 from vector-im/kegan/graceful-no-voip
Add unsupported suffix on Ongoing conf notification if conf calls are…
2015-11-02 18:18:46 +00:00
Kegan Dougal
6e63153d83 Add unsupported suffix on Ongoing conf notification if conf calls are unsupported in the browser 2015-11-02 18:01:20 +00:00
David Baker
159f0c9594 Merge remote-tracking branch 'origin/develop' into read_receipts 2015-11-02 14:29:20 +00:00
David Baker
e869814f2d Don't display anything if TextForEvent doesn't give us any text. Fixes #253 (catapillar of doom). 2015-11-02 14:14:47 +00:00
Kegsay
3b82884947 Merge pull request #298 from vector-im/kegan/reject-invites
Add invite rejection
2015-11-02 09:50:17 +00:00
Kegan Dougal
38780ad492 Merge branch 'develop' into kegan/reject-invites 2015-11-02 09:47:51 +00:00
Matthew Hodgson
e25d31a9fe Merge pull request #296 from vector-im/matthew/redesign
Matthew/redesign
2015-10-30 18:30:13 +00:00
Matthew Hodgson
56d00c2ec7 make onFinished required prop for modal contents 2015-10-30 18:26:22 +00:00
Matthew Hodgson
79af89fd1b fix missing decl 2015-10-30 18:26:05 +00:00
Matthew Hodgson
11e176df66 comment for the hidden collapse button 2015-10-30 18:23:08 +00:00
Matthew Hodgson
75bc878657 comment what a CR is 2015-10-30 18:22:21 +00:00
Matthew Hodgson
ddbc8dffb3 switch from enums to string literals for SearchBar.Scope 2015-10-30 18:21:54 +00:00
Matthew Hodgson
6aad99a505 comment \u200b 2015-10-30 18:20:29 +00:00
Matthew Hodgson
35cebc56d3 rewrite the HTML message stuff to fix XSS and improve clarity 2015-10-30 18:19:20 +00:00
Kegan Dougal
668234be4c Add reject button and impl 2015-10-30 17:18:25 +00:00
Kegsay
626e8bab1a Merge pull request #283 from vector-im/kegan/blocking
Add feature-based browser blocking
2015-10-30 14:59:06 +00:00
Kegan Dougal
633bbd8f29 Review comments: add chrome blurb. 2015-10-30 14:58:47 +00:00
David Baker
ffb9ce89c7 Merge branch 'develop' into matthew/redesign 2015-10-30 11:50:34 +00:00
David Baker
ce9a91e155 bundle.css shouldn't be necessary apart from the vector/bundle.* above 2015-10-30 11:33:33 +00:00
Matthew Hodgson
fdfa0cbd0e display search results correct; support HTML markup 2015-10-30 04:10:37 +00:00
Matthew Hodgson
d315e4afcd show m.room.names 2015-10-30 02:06:34 +00:00
Matthew Hodgson
80c04048d0 cancel viewsource dialog with escape 2015-10-29 21:30:29 +00:00
Matthew Hodgson
05d96f4cfb fix filters, and stop react exploding on unrecognised event tiles 2015-10-29 18:28:30 +00:00
Matthew Hodgson
8239e57fa1 more lightbox tweaks 2015-10-29 18:28:30 +00:00
David Baker
f4ca30bb38 Throw exception if EventTile is instantiated with an event type it doesn't support. 2015-10-29 18:12:42 +00:00
Kegan Dougal
cc313f350c Merge branch 'develop' into kegan/blocking 2015-10-29 16:03:26 +00:00
Erik Johnston
ae2768af9c Remove left/right padding from ongoing call notification, so that we don't get scrollbars in chrome 2015-10-29 15:57:31 +00:00
Kegan Dougal
511b1f409c Add objectfit and localstorage to browser features 2015-10-29 15:56:03 +00:00
David Baker
f00ee95563 Merge branch 'develop' of github.com:vector-im/vector-web into read_receipts 2015-10-29 11:27:56 +00:00
Matthew Hodgson
9fd2bf0989 remove transparent background for now; specify image width & height; punt the label over to the far RHS; to get around various layout problems in Chrome 44 and Safari 8 2015-10-29 11:01:23 +00:00
Matthew Hodgson
2c05515141 simplify keys 2015-10-29 02:34:06 +00:00
Matthew Hodgson
eb6fbe6a5a theoretically scope the search, but it doesn't work 2015-10-29 02:24:35 +00:00
Matthew Hodgson
2ee840922d basic implementation of search 2015-10-29 02:03:04 +00:00
Matthew Hodgson
0ade5ff640 lightbox buttons 2015-10-29 00:39:12 +00:00
Matthew Hodgson
dc401075a7 try to make the edit button more reliable 2015-10-29 00:38:51 +00:00
Matthew Hodgson
de1e8e9f93 implement redact and links 2015-10-29 00:38:26 +00:00
Matthew Hodgson
dbac2e299e tweak spacing of label on lightbox 2015-10-28 22:49:20 +00:00
Matthew Hodgson
8eaa96b0b3 black magic fixes to the lightbox 2015-10-28 19:41:49 +00:00
Matthew Hodgson
cb095ba5a0 WIP search stuff 2015-10-28 19:41:23 +00:00
Matthew Hodgson
0bfb1416c1 WIP search stuff 2015-10-28 19:39:45 +00:00
Kegan Dougal
22369729f9 Remove test feature 2015-10-28 17:42:19 +00:00
Kegan Dougal
59d8cbe742 Use Modernizr to check for browser compatibility
Add a CompatibilityPage which is shown for incompatible clients. If they
continue on regardless, proceed as if it never happened.
2015-10-28 17:39:50 +00:00
Matthew Hodgson
00a7ea994a kill random grey backgrounds for transparent avatars 2015-10-28 16:52:50 +00:00
Matthew Hodgson
7fbe38e74d fix padding feckup 2015-10-28 16:02:59 +00:00
Matthew Hodgson
a25207960c search bar 2015-10-28 01:05:28 +00:00
Matthew Hodgson
04aff6aab7 unhide labels on recents menu for Amandine 2015-10-27 23:51:40 +00:00
Matthew Hodgson
cbaf134625 merge develop 2015-10-27 23:28:34 +00:00
David Baker
b8fc926255 Send read receipts 2015-10-27 14:38:46 +00:00
Matthew Hodgson
aac00db16b WIP for new lightbox viewer 2015-10-27 01:39:19 +00:00
Matthew Hodgson
7c445cc108 fix error when joining rooms 2015-10-27 01:17:42 +00:00
Matthew Hodgson
363e3f4e21 image viewing tweaks 2015-10-25 23:33:28 +00:00
Matthew Hodgson
78cff9f20d fix upload drop target 2015-10-25 23:13:03 +00:00
Matthew Hodgson
86fb313b9b fix upload drop target 2015-10-25 23:12:57 +00:00
Matthew Hodgson
8840895e70 fix progressbar 2015-10-25 23:08:21 +00:00
Matthew Hodgson
ed76a46739 list power like this for now 2015-10-25 23:01:16 +00:00
Matthew Hodgson
7fdb82d87f memberinfo look & feel 2015-10-25 22:55:30 +00:00
Matthew Hodgson
729babae4f quick implementation of all new MemberInfo 2015-10-25 19:09:38 +00:00
Matthew Hodgson
731881ee7b fix language 2015-10-25 12:35:52 +00:00
Matthew Hodgson
47dca51c38 spell out how to set up the deps when developing 2015-10-25 12:33:13 +00:00
Matthew Hodgson
1ecf0f0183 Merge branch 'develop' of git+ssh://github.com/vector-im/vector-web into matthew/redesign 2015-10-25 11:57:35 +00:00
Matthew Hodgson
435a9cd9e4 actually use the config file for default HS and IS URLs... 2015-10-25 02:42:41 +00:00
Matthew Hodgson
8cd6d70c0a fix voip buttons header 2015-10-25 02:36:27 +00:00
Matthew Hodgson
1d3c821672 improve spacing a bit 2015-10-25 02:26:24 +00:00
Matthew Hodgson
6d6e1366dc s/Delete/Redact/ 2015-10-25 02:13:01 +00:00
Matthew Hodgson
19d272b171 Merge branch 'develop' of git+ssh://github.com/vector-im/vector-web into matthew/redesign 2015-10-25 02:12:35 +00:00
Matthew Hodgson
8ebb8ba427 fix up new message layout 2015-10-25 02:09:16 +00:00
Matthew Hodgson
9c215efcbf fix up header layout some more 2015-10-25 02:09:06 +00:00
Matthew Hodgson
6e3e0a1447 implement new roomheader 2015-10-25 01:52:28 +00:00
Matthew Hodgson
d16968d528 update badge count in realtime 2015-10-25 01:16:41 +00:00
Matthew Hodgson
28c3787fb3 implement bottom-right call button 2015-10-25 01:03:22 +00:00
Matthew Hodgson
d8bc362a89 fix invites 2015-10-25 00:59:33 +01:00
Matthew Hodgson
13f3548057 fix badge pos 2015-10-24 20:58:00 +01:00
Matthew Hodgson
39871e52df fix NPE 2015-10-24 20:57:05 +01:00
Matthew Hodgson
0cffd8dd84 sort out files button & NPE 2015-10-24 20:56:27 +01:00
Matthew Hodgson
f4d21f883a Add on a membership badge 2015-10-24 20:47:48 +01:00
Matthew Hodgson
a74cef0d64 fix stupid typing warnings 2015-10-24 20:28:42 +01:00
Matthew Hodgson
e59bfe16dc sort out the membership list 2015-10-24 20:19:54 +01:00
Matthew Hodgson
e718cad053 invites section 2015-10-24 02:02:33 +01:00
Matthew Hodgson
b6cac2bc89 Merge branch 'develop' of git+ssh://github.com/vector-im/vector-web into matthew/redesign 2015-10-23 18:03:49 +01:00
Matthew Hodgson
a86861e9b9 make badges work again 2015-10-23 18:03:35 +01:00
Matthew Hodgson
6e2362e8a9 reskin file upload UI 2015-10-23 17:43:40 +01:00
Matthew Hodgson
300005243c only bold current room if it has unread msgs 2015-10-23 17:43:30 +01:00
Matthew Hodgson
4019e359ca fix visibility during contextual window 2015-10-23 12:46:08 +01:00
Matthew Hodgson
185efb00fb new buttons 2015-10-23 12:41:59 +01:00
Matthew Hodgson
d946b39671 stop annoying popping and fix layout of hoverover tile stuff 2015-10-23 12:41:51 +01:00
Matthew Hodgson
c74dc8ef47 slightly prettier source view 2015-10-23 12:41:32 +01:00
Matthew Hodgson
7292a2ced5 kill blue lozenges 2015-10-23 12:40:28 +01:00
Matthew Hodgson
baf777a418 Merge branch 'develop' into matthew/redesign 2015-10-23 11:25:20 +01:00
Matthew Hodgson
11e6cf9757 Merge branch 'develop' into matthew/redesign 2015-10-23 11:22:00 +01:00
Matthew Hodgson
30b2156278 fix typing notifs 2015-10-23 11:19:13 +01:00
Matthew Hodgson
7f65ba506b WIP of new CSS 2015-10-23 02:39:56 +01:00
288 changed files with 8988 additions and 6572 deletions

12
.gitignore vendored
View File

@@ -1,3 +1,9 @@
node_modules
vector/bundle.*
lib
/cert.pem
/.DS_Store
/karma-reports
/key.pem
/lib
/node_modules
/packages/
/vector/bundle.*
/vector/components.css

14
.modernizr.json Normal file
View File

@@ -0,0 +1,14 @@
{
"minify": true,
"classPrefix": "modernizr_",
"options": [
"setClasses"
],
"feature-detects": [
"test/css/displaytable",
"test/css/flexbox",
"test/es5/specification",
"test/css/objectfit",
"test/storage/localstorage"
]
}

View File

@@ -7,3 +7,6 @@ include:
* https://github.com/neko259
Improved scrollbar CSS
* Florent VIOLLEAU (https://github.com/floviolleau) <floviolleau at gmail dot com>
Improve README.md for a better understanding of installation instructions

160
CHANGELOG.md Normal file
View File

@@ -0,0 +1,160 @@
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)
* Update to matrix-react-sdk 0.6.0 - see
[changelog](https://github.com/matrix-org/matrix-react-sdk/blob/v0.6.0/CHANGELOG.md)
* Style selection color.
[\#1557](https://github.com/vector-im/vector-web/pull/1557)
* Fix NPE when loading the Settings page which infini-spinnered
[\#1518](https://github.com/vector-im/vector-web/pull/1518)
* Add option to enable email notifications
[\#1469](https://github.com/vector-im/vector-web/pull/1469)
Changes in [0.6.1](https://github.com/vector-im/vector-web/releases/tag/v0.6.1) (2016-04-22)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.6.0...v0.6.1)
* Update to matrix-react-sdk 0.5.2 - see
[changelog](https://github.com/matrix-org/matrix-react-sdk/blob/v0.5.2/CHANGELOG.md)
* Don't relayout scrollpanels every time something changes
[\#1438](https://github.com/vector-im/vector-web/pull/1438)
* Include react-addons-perf for non-production builds
[\#1431](https://github.com/vector-im/vector-web/pull/1431)
Changes in [0.6.0](https://github.com/vector-im/vector-web/releases/tag/v0.6.0) (2016-04-19)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.5.0...v0.6.0)
* Matthew/design tweaks
[\#1402](https://github.com/vector-im/vector-web/pull/1402)
* Improve handling of notification rules we can't parse
[\#1399](https://github.com/vector-im/vector-web/pull/1399)
* Do less mangling of jenkins builds
[\#1391](https://github.com/vector-im/vector-web/pull/1391)
* Start Notifications component refactor
[\#1386](https://github.com/vector-im/vector-web/pull/1386)
* make the UI fadable to help with decluttering
[\#1376](https://github.com/vector-im/vector-web/pull/1376)
* Get and display a user's pushers in settings
[\#1374](https://github.com/vector-im/vector-web/pull/1374)
* URL previewing support
[\#1343](https://github.com/vector-im/vector-web/pull/1343)
* 😄 Emoji autocomplete and unicode emoji to image conversion using emojione.
[\#1332](https://github.com/vector-im/vector-web/pull/1332)
* Show full-size avatar on MemberInfo avatar click
[\#1340](https://github.com/vector-im/vector-web/pull/1340)
* Numerous other changes via [matrix-react-sdk 0.5.1](https://github.com/matrix-org/matrix-react-sdk/blob/v0.5.1/CHANGELOG.md)
Changes in [0.5.0](https://github.com/vector-im/vector-web/releases/tag/v0.5.0) (2016-03-30)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.4.1...v0.5.0)
* Prettier, animated placeholder :D
[\#1292](https://github.com/vector-im/vector-web/pull/1292)
(Disabled for now due to high CPU usage)
* RoomDirectory: use SimpleRoomHeader instead of RoomHeader
[\#1307](https://github.com/vector-im/vector-web/pull/1307)
* Tell webpack not to parse the highlight.js languages
[\#1277](https://github.com/vector-im/vector-web/pull/1277)
* CSS for https://github.com/matrix-org/matrix-react-sdk/pull/247
[\#1249](https://github.com/vector-im/vector-web/pull/1249)
* URI-decode the hash-fragment
[\#1254](https://github.com/vector-im/vector-web/pull/1254)
Changes in [0.4.1](https://github.com/vector-im/vector-web/releases/tag/v0.4.1) (2016-03-23)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.4.0...v0.4.1)
* Update to matrix-react-sdk 0.3.1; see
https://github.com/matrix-org/matrix-react-sdk/blob/v0.3.1/CHANGELOG.md
(Disables debug logging)
Changes in [0.4.0](https://github.com/vector-im/vector-web/releases/tag/v0.4.0) (2016-03-23)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.3.0...v0.4.0)
* Update to matrix-react-sdk 0.3.0; see
https://github.com/matrix-org/matrix-react-sdk/blob/master/CHANGELOG.md
Other changes
* permalink button
[\#1232](https://github.com/vector-im/vector-web/pull/1232)
* make senderprofiles clickable
[\#1191](https://github.com/vector-im/vector-web/pull/1191)
* fix notif spam when logging in from a guest session by correctly logging out
first.
[\#1180](https://github.com/vector-im/vector-web/pull/1180)
* use new start_login_from_guest dispatch for cancellable logins from guest
accounts
[\#1165](https://github.com/vector-im/vector-web/pull/1165)
* Use then() chaining rather than manual callbacks
[\#1171](https://github.com/vector-im/vector-web/pull/1171)
* Remove trailing whitespace
[\#1163](https://github.com/vector-im/vector-web/pull/1163)
* Update the actions of default rules instead of overriding.
[\#1037](https://github.com/vector-im/vector-web/pull/1037)
* Update README to include `npm install` in react-sdk
[\#1137](https://github.com/vector-im/vector-web/pull/1137)
Changes in vector v0.3.0 (2016-03-11)
======================================
* Lots of new bug fixes and updates
Changes in vector v0.2.0 (2016-02-24)
======================================
* Refactor of matrix-react-sdk and vector to remove separation between views and
controllers
* Temporarily break the layering abstraction between vector and matrix-react-sdk
for expedience in developing vector.
* Vast numbers of new features, including read receipts, read-up-to markers,
updated look and feel, search, new room and user settings, and email invites.
Changes in vector v0.1.2 (2015-10-28)
======================================
* Support Room Avatars
* Fullscreen video calls
* Mute mic in VoIP calls
* Fix bug with multiple desktop notifications
* Context menu on messages
* Better hover-over on member list
* Support CAS auth
* Many other bug fixes
Changes in vector v0.1.1 (2015-08-10)
======================================
* Support logging in with an email address
* Use the Vector identity server
* Fix a bug where the client was not stopped properly on logout
* Fix bugs where field values would be forgotten if login or registration failed
* Improve URL bar navigation
* Add explanatory help text on advanced server options
* Fix a bug which caused execptions on malformed VoIP invitations
* Remove superfluous scrollbars on Firefox
* Numerous CSS fixes
* Improved accessibility
* Support command-click / middle click to open image in a new tab
* Improved room directory
* Fix display of text with many combining unicode points
Changes in vector v0.1.0 (2015-08-10)
======================================
Initial release

View File

@@ -1,31 +0,0 @@
Changes in vector v0.1.2 (2015-10-28)
======================================
* Support Room Avatars
* Fullscreen video calls
* Mute mic in VoIP calls
* Fix bug with multiple desktop notifications
* Context menu on messages
* Better hover-over on member list
* Support CAS auth
* Many other bug fixes
Changes in vector v0.1.1 (2015-08-10)
======================================
* Support logging in with an email address
* Use the Vector identity server
* Fix a bug where the client was not stopped properly on logout
* Fix bugs where field values would be forgotten if login or registration failed
* Improve URL bar navigation
* Add explanatory help text on advanced server options
* Fix a bug which caused execptions on malformed VoIP invitations
* Remove superfluous scrollbars on Firefox
* Numerous CSS fixes
* Improved accessibility
* Support command-click / middle click to open image in a new tab
* Improved room directory
* Fix display of text with many combining unicode points
Changes in vector v0.1.0 (2015-08-10)
======================================
Initial release

159
README.md
View File

@@ -7,52 +7,137 @@ Getting started
===============
1. Install or update `node.js` so that your `npm` is at least at version `2.0.0`
2. Clone the repo: `git clone https://github.com/vector-im/vector-web.git`
3. Switch to the SDK directory: `cd vector-web`
4. Install the prerequisites: `npm install`
5. Start the development builder and a testing server: `npm start`
6. Wait a few seconds for the initial build to finish.
7. Open http://127.0.0.1:8080/ in your browser to see your newly built Vector.
1. Clone the repo: `git clone https://github.com/vector-im/vector-web.git`
1. Switch to the vector directory: `cd vector-web`
1. Install the prerequisites: `npm install`
1. 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.
With `npm start`, any changes you make to the source files will cause a rebuild so
your changes will show up when you refresh.
your changes will show up when you refresh. This development server also disables
caching, so do NOT use it in production.
For production use, run `npm run build` to build all the necessary files
into the `vector` directory and run your own server.
Development
Configuring
===========
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.
Configure the app by modifying the `config.json` file:
However, all serious development on Vector happens on the `develop` branch. This typically
depends on the `develop` snapshot versions of `matrix-react-sdk` and `matrix-js-sdk`
too, which isn't expressed in Vector's `package.json`. To do this, check out
the `develop` branches of these libraries and then use `npm link` to tell Vector
about them:
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.
1. `git clone git@github.com:matrix-org/matrix-react-sdk.git`
2. `cd matrix-react-sdk`
3. `git checkout develop`
4. `npm install`
5. `npm start` (to start the dev rebuilder)
6. `cd ../vector-web`
7. Link the react sdk package into the example:
`npm link path/to/your/react/sdk`
Similarly, you may need to `npm link path/to/your/js/sdk` in your `matrix-react-sdk`
directory.
If you add or remove any components from the Vector skin, you will need to rebuild
the skin's index by running, `npm run reskindex`.
You may need to run `npm i source-map-loader` in matrix-js-sdk if you get errors
about "Cannot resolve module 'source-map-loader'" due to shortcomings in webpack.
You will need to re-run `npm run build` after editing `config.json`.
Deployment
==========
Just run `npm build` and then mount the `vector` directory on your webserver to
actually serve up the app, which is entirely static content.
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.
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.
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.
[Be aware that there may be problems with this process under npm version 3.]
First clone and build `matrix-js-sdk`:
1. `git clone git@github.com:matrix-org/matrix-js-sdk.git`
1. `pushd matrix-js-sdk`
1. `git checkout develop`
1. `npm install`
1. `npm install source-map-loader` # because webpack is made of fail (https://github.com/webpack/webpack/issues/1472)
1. `popd`
Then similarly with `matrix-react-sdk`:
1. `git clone git@github.com:matrix-org/matrix-react-sdk.git`
1. `pushd matrix-react-sdk`
1. `git checkout develop`
1. `npm install`
1. `rm -r node_modules/matrix-js-sdk; ln -s ../../matrix-js-sdk node_modules/`
1. `popd`
Finally, build and start vector itself:
1. `git clone git@github.com:vector-im/vector-web.git`
1. `cd vector-web`
1. `git checkout develop`
1. `npm install`
1. `rm -r node_modules/matrix-js-sdk; ln -s ../../matrix-js-sdk node_modules/`
1. `rm -r node_modules/matrix-react-sdk; ln -s ../../matrix-react-sdk node_modules/`
1. `npm start`
1. Wait a few seconds for the initial build to finish; you should see something like:
```
Hash: b0af76309dd56d7275c8
Version: webpack 1.12.14
Time: 14533ms
Asset Size Chunks Chunk Names
bundle.js 4.2 MB 0 [emitted] main
bundle.css 91.5 kB 0 [emitted] main
bundle.js.map 5.29 MB 0 [emitted] main
bundle.css.map 116 kB 0 [emitted] main
+ 1013 hidden modules
```
Remember, the command will not terminate since it runs the web server
and rebuilds source files when they change.
1. Open http://127.0.0.1:8080/ in your browser to see your newly built Vector.
When you make changes to `matrix-js-sdk` or `matrix-react-sdk`, you will need
to run `npm run build` in the relevant directory. You can do this automatically
by instead running `npm start` in each directory, to start a development
builder which will watch for changes to the files and rebuild automatically.
If you add or remove any components from the Vector skin, you will need to rebuild
the skin's index by running, `npm run reskindex`.
Enabling encryption
===================
End-to-end encryption in Vector and Matrix is not yet considered ready for
day-to-day use; it is experimental and should be considered only as a
proof-of-concept. See https://matrix.org/jira/browse/SPEC-162 for an overview
of the current progress.
To build a version of vector with support for end-to-end encryption, install
the olm module with `npm i https://matrix.org/packages/npm/olm/olm-0.1.0.tgz`
before running `npm start`. The olm library will be detected and used if
available.
To enable encryption for a room, type
```
/encrypt on
```
in the message bar in that room. Vector will then generate a set of keys, and
encrypt all outgoing messages in that room. (Note that other people in that
room will send messages in the clear unless they also `/encrypt on`.)
Note that historical encrypted messages cannot currently be decoded - history
is therefore lost when the page is reloaded.
There is currently no visual indication of whether encryption is enabled for a
room, or whether a particular message was encrypted.

View File

@@ -1,4 +1,7 @@
{
"default_hs_url": "https://matrix.org",
"default_is_url": "https://vector.im"
"default_is_url": "https://vector.im",
"brand": "Vector",
"integrations_ui_url": "http://localhost:8081/",
"integrations_rest_url": "http://localhost:5050"
}

170
deploy/redeploy.py Executable file
View File

@@ -0,0 +1,170 @@
#!/usr/bin/env python
from __future__ import print_function
import json, requests, tarfile, argparse, os, errno
from urlparse import urljoin
from flask import Flask, jsonify, request, abort
app = Flask(__name__)
arg_jenkins_url, arg_extract_path, arg_should_clean, arg_symlink = (
None, None, None, None
)
def download_file(url):
local_filename = url.split('/')[-1]
r = requests.get(url, stream=True)
with open(local_filename, 'wb') as f:
for chunk in r.iter_content(chunk_size=1024):
if chunk: # filter out keep-alive new chunks
f.write(chunk)
return local_filename
def untar_to(tarball, dest):
with tarfile.open(tarball) as tar:
tar.extractall(dest)
def create_symlink(source, linkname):
try:
os.symlink(source, linkname)
except OSError, e:
if e.errno == errno.EEXIST:
# atomic modification
os.symlink(source, linkname + ".tmp")
os.rename(linkname + ".tmp", linkname)
else:
raise e
@app.route("/", methods=["POST"])
def on_receive_jenkins_poke():
# {
# "name": "VectorWebDevelop",
# "build": {
# "number": 8
# }
# }
incoming_json = request.get_json()
if not incoming_json:
abort(400, "No JSON provided!")
return
print("Incoming JSON: %s" % (incoming_json,))
job_name = incoming_json.get("name")
if not isinstance(job_name, basestring):
abort(400, "Bad job name: %s" % (job_name,))
return
build_num = incoming_json.get("build", {}).get("number", 0)
if not build_num or build_num <= 0 or not isinstance(build_num, int):
abort(400, "Missing or bad build number")
return
artifact_url = urljoin(
arg_jenkins_url, "job/%s/%s/api/json" % (job_name, build_num)
)
artifact_response = requests.get(artifact_url).json()
# {
# "actions": [],
# "artifacts": [
# {
# "displayPath": "vector-043f6991a4ed-react-20f77d1224ef-js-0a7efe3e8bd5.tar.gz",
# "fileName": "vector-043f6991a4ed-react-20f77d1224ef-js-0a7efe3e8bd5.tar.gz",
# "relativePath": "vector-043f6991a4ed-react-20f77d1224ef-js-0a7efe3e8bd5.tar.gz"
# }
# ],
# "building": false,
# "description": null,
# "displayName": "#11",
# "duration": 137976,
# "estimatedDuration": 132008,
# "executor": null,
# "fullDisplayName": "VectorWebDevelop #11",
# "id": "11",
# "keepLog": false,
# "number": 11,
# "queueId": 12254,
# "result": "SUCCESS",
# "timestamp": 1454432640079,
# "url": "http://matrix.org/jenkins/job/VectorWebDevelop/11/",
# "builtOn": "",
# "changeSet": {},
# "culprits": []
# }
if artifact_response.get("result") != "SUCCESS":
abort(404, "Not deploying. Build was not marked as SUCCESS.")
return
if len(artifact_response.get("artifacts", [])) != 1:
abort(404, "Not deploying. Build has an unexpected number of artifacts.")
return
tar_gz_path = artifact_response["artifacts"][0]["relativePath"]
if not tar_gz_path.endswith(".tar.gz"):
abort(404, "Not deploying. Artifact is not a .tar.gz file")
return
tar_gz_url = urljoin(
arg_jenkins_url, "job/%s/%s/artifact/%s" % (job_name, build_num, tar_gz_path)
)
print("Retrieving .tar.gz file: %s" % tar_gz_url)
filename = download_file(tar_gz_url)
print("Downloaded file: %s" % filename)
name_str = filename.replace(".tar.gz", "")
untar_location = os.path.join(arg_extract_path, name_str)
untar_to(filename, untar_location)
if arg_should_clean:
os.remove(filename)
# stamp the version somewhere JS can get to it
with open(os.path.join(untar_location, "vector/version"), "w") as stamp_file:
stamp_file.write(name_str)
create_symlink(source=os.path.join(untar_location, "vector"), linkname=arg_symlink)
return jsonify({})
if __name__ == "__main__":
parser = argparse.ArgumentParser("Runs a Vector redeployment server.")
parser.add_argument(
"-j", "--jenkins", dest="jenkins", default="http://matrix.org/jenkins/", help=(
"The base URL of the Jenkins web server. This will be hit to get the\
built artifacts (the .gz file) for redeploying."
)
)
parser.add_argument(
"-p", "--port", dest="port", default=4000, type=int, help=(
"The port to listen on for requests from Jenkins."
)
)
parser.add_argument(
"-e", "--extract", dest="extract", default="./extracted", help=(
"The location to extract .tar.gz files to."
)
)
parser.add_argument(
"-c", "--clean", dest="clean", action="store_true", default=False, help=(
"Remove .tar.gz files after they have been downloaded and extracted."
)
)
parser.add_argument(
"-s", "--symlink", dest="symlink", default="./latest", help=(
"Write a symlink to this location pointing to the extracted tarball. \
New builds will keep overwriting this symlink. The symlink will point \
to the /vector directory INSIDE the tarball."
)
)
args = parser.parse_args()
if args.jenkins.endswith("/"): # important for urljoin
arg_jenkins_url = args.jenkins
else:
arg_jenkins_url = args.jenkins + "/"
arg_extract_path = args.extract
arg_should_clean = args.clean
arg_symlink = args.symlink
print(
"Listening on port %s. Extracting to %s%s. Symlinking to %s. Jenkins URL: %s" %
(args.port, arg_extract_path,
" (clean after)" if arg_should_clean else "", arg_symlink, arg_jenkins_url)
)
app.run(host="0.0.0.0", port=args.port, debug=True)

33
jenkins.sh Executable file
View File

@@ -0,0 +1,33 @@
#!/bin/bash
set -e
export NVM_DIR="/home/jenkins/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm use 4
set -x
npm install
# we may be using a dev branch of react-sdk, in which case we need to build it
(cd node_modules/matrix-react-sdk && npm run build)
# run the mocha tests
npm run test
# build our artifacts; dumps them in ./vector
npm run build:dev
# gzip up ./vector
rm vector-*.tar.gz || true # rm previous artifacts without failing if it doesn't exist
# node_modules deps from 'npm install' don't have a .git dir so can't
# rev-parse; but they do set the commit in package.json under 'gitHead' which
# we're grabbing here.
REACT_SHA=$(grep 'gitHead' node_modules/matrix-react-sdk/package.json | cut -d \" -f 4 | head -c 12)
JSSDK_SHA=$(grep 'gitHead' node_modules/matrix-js-sdk/package.json | cut -d \" -f 4 | head -c 12)
VECTOR_SHA=$(git rev-parse --short=12 HEAD) # use the ACTUAL SHA rather than assume develop
tar -zcvhf vector-$VECTOR_SHA-react-$REACT_SHA-js-$JSSDK_SHA.tar.gz vector #g[z]ip, [c]reate archive, [v]erbose, [f]ilename, [h]ard-dereference (do not archive symlinks)

136
karma.conf.js Normal file
View File

@@ -0,0 +1,136 @@
// karma.conf.js - the config file for karma, which runs our tests.
var path = require('path');
var webpack = require('webpack');
/*
* We use webpack to build our tests. It's a pain to have to wait for webpack
* to build everything; however it's the easiest way to load our dependencies
* from node_modules.
*
* If you run karma in multi-run mode (with `npm run test:multi`), it will watch
* the tests for changes, and webpack will rebuild using a cache. This is much quicker
* than a clean rebuild.
*/
// the name of the test file. By default, a special file which runs all tests.
var testFile = process.env.KARMA_TEST_FILE || 'test/all-tests.js';
process.env.PHANTOMJS_BIN = 'node_modules/.bin/phantomjs';
process.env.Q_DEBUG = 1;
module.exports = function (config) {
config.set({
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha'],
// list of files / patterns to load in the browser
files: [
testFile,
{pattern: 'vector/img/*', watched: false, included: false, served: true, nocache: false},
],
// redirect img links to the karma server
proxies: {
"/img/": "/base/vector/img/",
},
// preprocess matching files before serving them to the browser
// available preprocessors:
// https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'test/**/*.js': ['webpack', 'sourcemap']
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'junit'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR ||
// config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file
// changes
autoWatch: true,
// start these browsers
// available browser launchers:
// https://npmjs.org/browse/keyword/karma-launcher
browsers: [
'Chrome',
//'PhantomJS',
],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
// singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity,
junitReporter: {
outputDir: 'karma-reports',
},
webpack: {
module: {
loaders: [
{ test: /\.json$/, loader: "json" },
{
test: /\.js$/, loader: "babel",
include: [path.resolve('./src'),
path.resolve('./test'),
],
query: {
// we're using babel 5, for consistency with
// the release build, which doesn't use the
// presets.
// presets: ['react', 'es2015'],
},
},
],
noParse: [
// don't parse the languages within highlight.js. They
// cause stack overflows
// (https://github.com/webpack/webpack/issues/1721), and
// there is no need for webpack to parse them - they can
// just be included as-is.
/highlight\.js\/lib\/languages/,
// also disable parsing for sinon, because it
// tries to do voodoo with 'require' which upsets
// webpack (https://github.com/webpack/webpack/issues/304)
/sinon\/pkg\/sinon\.js$/,
],
},
resolve: {
alias: {
// alias any requires to the react module to the one in our path, otherwise
// we tend to get the react source included twice when using npm link.
react: path.resolve('./node_modules/react'),
// same goes for js-sdk
"matrix-js-sdk": path.resolve('./node_modules/matrix-js-sdk'),
sinon: 'sinon/pkg/sinon.js',
},
root: [
path.resolve('./src'),
path.resolve('./test'),
],
},
devtool: 'inline-source-map',
},
});
};

View File

@@ -1,6 +1,6 @@
{
"name": "vector-web",
"version": "0.1.2",
"version": "0.7.3",
"description": "Vector webapp",
"author": "matrix.org",
"repository": {
@@ -9,40 +9,73 @@
},
"license": "Apache-2.0",
"style": "bundle.css",
"matrix-react-parent": "matrix-react-sdk",
"scripts": {
"reskindex": "reskindex vector -h src/skins/vector/header",
"build:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/bundle.css -c uglifycss --no-watch",
"reskindex": "reskindex -h src/header",
"build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js",
"build:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css --no-watch",
"build:compile": "babel --source-maps -d lib src",
"build:bundle": "NODE_ENV=production webpack -p lib/vector/index.js vector/bundle.js",
"build: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",
"package": "scripts/package.sh",
"start:js": "webpack -w src/vector/index.js vector/bundle.js",
"start:skins:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/bundle.css",
"start:js:prod": "NODE_ENV=production webpack -w src/vector/index.js vector/bundle.js",
"start:skins:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css",
"//cache": "Note the -c 1 below due to https://code.google.com/p/chromium/issues/detail?id=508270",
"start": "parallelshell \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
"clean": "rimraf lib vector/bundle.css vector/bundle.js vector/bundle.js.map",
"prepublish": "npm run build:css && npm run build:compile"
"start:prod": "parallelshell \"npm run start:js:prod\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
"clean": "rimraf lib vector/bundle.css vector/bundle.js vector/bundle.js.map vector/webpack.css*",
"prepublish": "npm run build:css && npm run build:compile",
"test": "karma start --single-run=true --autoWatch=false --browsers PhantomJS --colors=false",
"test:multi": "karma start"
},
"dependencies": {
"babel-polyfill": "^6.5.0",
"classnames": "^2.1.2",
"extract-text-webpack-plugin": "^0.9.1",
"filesize": "^3.1.2",
"flux": "~2.0.3",
"gemini-scrollbar": "matrix-org/gemini-scrollbar#87ebaa7",
"gfm.css": "^1.1.1",
"highlight.js": "^9.0.0",
"linkifyjs": "^2.0.0-beta.4",
"matrix-js-sdk": "^0.3.0",
"matrix-react-sdk": "^0.0.2",
"matrix-js-sdk": "^0.5.4",
"matrix-react-sdk": "^0.6.3",
"modernizr": "^3.1.0",
"q": "^1.4.1",
"react": "^0.13.3",
"react-loader": "^1.4.0"
"react": "^15.0.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",
"sanitize-html": "^1.11.1"
},
"devDependencies": {
"babel": "^5.8.23",
"babel-core": "^5.8.25",
"babel-loader": "^5.3.2",
"catw": "^1.0.1",
"css-raw-loader": "^0.1.1",
"expect": "^1.16.0",
"http-server": "^0.8.4",
"json-loader": "^0.5.3",
"karma": "^0.13.22",
"karma-chrome-launcher": "^0.2.3",
"karma-cli": "^0.1.2",
"karma-junit-reporter": "^0.4.1",
"karma-mocha": "^0.2.2",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^1.7.0",
"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",
"rimraf": "^2.4.3",
"source-map-loader": "^0.1.5",
"uglifycss": "0.0.15"
"webpack": "^1.12.14"
}
}

12
release.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/sh
#
# Script to perform a release of vector-web.
#
# Requires github-changelog-generator; to install, do
# pip install git+https://github.com/matrix-org/github-changelog-generator.git
set -e
cd `dirname $0`
exec ./node_modules/matrix-js-sdk/release.sh -z "$@"

124
scripts/issues-burndown.pl Normal file
View File

@@ -0,0 +1,124 @@
#!/usr/bin/env perl
use warnings;
use strict;
use Net::GitHub;
use DateTime;
use DateTime::Format::ISO8601;
my $gh = Net::GitHub->new(
login => 'ara4n', pass => 'secret'
);
$gh->set_default_user_repo('vector-im', 'vector-web');
my @issues = $gh->issue->repos_issues({ state => 'all', milestone => 3 });
while ($gh->issue->has_next_page) {
push @issues, $gh->issue->next_page;
}
# we want:
# day by day:
# split by { open, closed }
# split by { bug, feature, neither }
# each split by { p1, p2, p3, p4, p5, unprioritised } <- priority
# each split by { minor, major, critical, cosmetic, network, no-severity } <- severity
# then split (with overlap between the groups) as { total, tag1, tag2, ... }?
# ...and then all over again split by milestone.
my $days = {};
my $schema = {};
my $now = DateTime->now();
foreach my $issue (@issues) {
next if ($issue->{pull_request});
# use Data::Dumper;
# print STDERR Dumper($issue);
my @label_list = map { $_->{name} } @{$issue->{labels}};
my $labels = {};
$labels->{$_} = 1 foreach (@label_list);
$labels->{bug}++ if ($labels->{cosmetic} && !$labels->{bug} && !$labels->{feature});
my $extract_labels = sub {
my $label = undef;
foreach (@_) {
$label ||= $_ if (delete $labels->{$_});
}
return $label;
};
my $state = $issue->{state};
my $type = &$extract_labels(qw(bug feature)) || "neither";
my $priority = &$extract_labels(qw(p1 p2 p3 p4 p5)) || "unprioritised";
my $severity = &$extract_labels(qw(minor major critical cosmetic network)) || "no-severity";
my $start = DateTime::Format::ISO8601->parse_datetime($issue->{created_at});
do {
my $ymd = $start->ymd();
$days->{ $ymd }->{ 'created' }->{ $type }->{ $priority }->{ $severity }->{ total }++;
$schema->{ 'created' }->{ $type }->{ $priority }->{ $severity }->{ total }++;
foreach (keys %$labels) {
$days->{ $ymd }->{ 'created' }->{ $type }->{ $priority }->{ $severity }->{ $_ }++;
$schema->{ 'created' }->{ $type }->{ $priority }->{ $severity }->{ $_ }++;
}
$start = $start->add(days => 1);
} while (DateTime->compare($start, $now) < 0);
if ($state eq 'closed') {
my $end = DateTime::Format::ISO8601->parse_datetime($issue->{closed_at});
do {
my $ymd = $end->ymd();
$days->{ $ymd }->{ 'resolved' }->{ $type }->{ $priority }->{ $severity }->{ total }++;
$schema->{ 'resolved' }->{ $type }->{ $priority }->{ $severity }->{ total }++;
foreach (keys %$labels) {
$days->{ $ymd }->{ 'resolved' }->{ $type }->{ $priority }->{ $severity }->{ $_ }++;
$schema->{ 'resolved' }->{ $type }->{ $priority }->{ $severity }->{ $_ }++;
}
$end = $end->add(days => 1);
} while (DateTime->compare($end, $now) < 0);
}
}
print "day,";
foreach my $state (sort keys %{$schema}) {
foreach my $type (grep { /^(bug|feature)$/ } sort keys %{$schema->{$state}}) {
foreach my $priority (grep { /^(p1|p2)$/ } sort keys %{$schema->{$state}->{$type}}) {
foreach my $severity (sort keys %{$schema->{$state}->{$type}->{$priority}}) {
# foreach my $tag (sort keys %{$schema->{$state}->{$type}->{$priority}->{$severity}}) {
# print "\"$type\n$priority\n$severity\n$tag\",";
# }
print "\"$state\n$type\n$priority\n$severity\",";
}
}
}
}
print "\n";
foreach my $day (sort keys %$days) {
print "$day,";
foreach my $state (sort keys %{$schema}) {
foreach my $type (grep { /^(bug|feature)$/ } sort keys %{$schema->{$state}}) {
foreach my $priority (grep { /^(p1|p2)$/ } sort keys %{$schema->{$state}->{$type}}) {
foreach my $severity (sort keys %{$schema->{$state}->{$type}->{$priority}}) {
# foreach my $tag (sort keys %{$schema->{$state}->{$type}->{$priority}->{$severity}}) {
# print $days->{$day}->{$state}->{$type}->{$priority}->{$severity}->{$tag} || 0;
# print ",";
# }
print $days->{$day}->{$state}->{$type}->{$priority}->{$severity}->{total} || 0;
print ",";
}
}
}
}
print "\n";
}

104
scripts/issues-no-state.pl Executable file
View File

@@ -0,0 +1,104 @@
#!/usr/bin/env perl
use warnings;
use strict;
use Net::GitHub;
use DateTime;
use DateTime::Format::ISO8601;
my $gh = Net::GitHub->new(
login => 'ara4n', pass => 'secret'
);
$gh->set_default_user_repo('vector-im', 'vector-web');
my @issues = $gh->issue->repos_issues({ state => 'all', milestone => 3 });
while ($gh->issue->has_next_page) {
push @issues, $gh->issue->next_page;
}
# we want:
# day by day:
# split by { open, closed }
# split by { bug, feature, neither }
# each split by { p1, p2, p3, p4, p5, unprioritised } <- priority
# each split by { minor, major, critical, cosmetic, network, no-severity } <- severity
# then split (with overlap between the groups) as { total, tag1, tag2, ... }?
# ...and then all over again split by milestone.
my $days = {};
my $schema = {};
my $now = DateTime->now();
foreach my $issue (@issues) {
next if ($issue->{pull_request});
use Data::Dumper;
print STDERR Dumper($issue);
my @label_list = map { $_->{name} } @{$issue->{labels}};
my $labels = {};
$labels->{$_} = 1 foreach (@label_list);
$labels->{bug}++ if ($labels->{cosmetic} && !$labels->{bug} && !$labels->{feature});
my $extract_labels = sub {
my $label = undef;
foreach (@_) {
$label ||= $_ if (delete $labels->{$_});
}
return $label;
};
my $type = &$extract_labels(qw(bug feature)) || "neither";
my $priority = &$extract_labels(qw(p1 p2 p3 p4 p5)) || "unprioritised";
my $severity = &$extract_labels(qw(minor major critical cosmetic network)) || "no-severity";
my $start = DateTime::Format::ISO8601->parse_datetime($issue->{created_at});
my $end = $issue->{closed_at} ? DateTime::Format::ISO8601->parse_datetime($issue->{closed_at}) : $now;
do {
my $ymd = $start->ymd();
$days->{ $ymd }->{ $type }->{ $priority }->{ $severity }->{ total }++;
$schema->{ $type }->{ $priority }->{ $severity }->{ total }++;
foreach (keys %$labels) {
$days->{ $ymd }->{ $type }->{ $priority }->{ $severity }->{ $_ }++;
$schema->{ $type }->{ $priority }->{ $severity }->{ $_ }++;
}
$start = $start->add(days => 1);
} while (DateTime->compare($start, $end) < 0);
}
print "day,";
foreach my $type (sort keys %{$schema}) {
foreach my $priority (sort keys %{$schema->{$type}}) {
foreach my $severity (sort keys %{$schema->{$type}->{$priority}}) {
# foreach my $tag (sort keys %{$schema->{$type}->{$priority}->{$severity}}) {
# print "\"$type\n$priority\n$severity\n$tag\",";
# }
print "\"$type\n$priority\n$severity\",";
}
}
}
print "\n";
foreach my $day (sort keys %$days) {
print "$day,";
foreach my $type (sort keys %{$schema}) {
foreach my $priority (sort keys %{$schema->{$type}}) {
foreach my $severity (sort keys %{$schema->{$type}->{$priority}}) {
# foreach my $tag (sort keys %{$schema->{$type}->{$priority}->{$severity}}) {
# print $days->{$day}->{$type}->{$priority}->{$severity}->{$tag} || 0;
# print ",";
# }
print $days->{$day}->{$type}->{$priority}->{$severity}->{total} || 0;
print ",";
}
}
}
print "\n";
}

15
scripts/package.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
set -e
version=`git describe --dirty --tags || echo unknown`
npm run build
mkdir -p packages
cp -r vector vector-$version
echo $version > vector-$version/version
tar chvzf packages/vector-$version.tar.gz vector-$version
rm -r vector-$version
echo
echo "Packaged packages/vector-$version.tar.gz"

View File

@@ -1,53 +0,0 @@
/*
Copyright 2015 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
module.exports = {
avatarUrlForMember: function(member, width, height, resizeMethod) {
var url = member.getAvatarUrl(
MatrixClientPeg.get().getHomeserverUrl(),
width,
height,
resizeMethod
);
if (!url) {
// member can be null here currently since on invites, the JS SDK
// does not have enough info to build a RoomMember object for
// the inviter.
url = this.defaultAvatarUrlForString(member ? member.userId : '');
}
return url;
},
defaultAvatarUrlForString: function(s) {
var total = 0;
for (var i = 0; i < s.length; ++i) {
total += s.charCodeAt(i);
}
switch (total % 3) {
case 0:
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9QjNbxSKP4eagAFnTseHFErFYLBaLxWKxWCwWi8Vi8cX4CzAABSwCRWJw31gAAAAASUVORK5CYII=";
case 1:
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9chOaxgCP4eagAFk9seHFErFYLBaLxWKxWCwWi8Vi8cX4CzAAtKMCks/JG8MAAAAASUVORK5CYII=";
case 2:
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9YzNayQCP4eagADldseHFErFYLBaLxWKxWCwWi8Vi8cX4CzAAyiACeHwPiu4AAAAASUVORK5CYII=";
}
}
}

View File

@@ -1,81 +0,0 @@
/*
Copyright 2015 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require('react');
// Shamelessly ripped off Modal.js. There's probably a better way
// of doing reusable widgets like dialog boxes & menus where we go and
// pass in a custom control as the actual body.
module.exports = {
ContextualMenuContainerId: "mx_ContextualMenu_Container",
getOrCreateContainer: function() {
var container = document.getElementById(this.ContextualMenuContainerId);
if (!container) {
container = document.createElement("div");
container.id = this.ContextualMenuContainerId;
document.body.appendChild(container);
}
return container;
},
createMenu: function (Element, props) {
var self = this;
var closeMenu = function() {
React.unmountComponentAtNode(self.getOrCreateContainer());
if (props && props.onFinished) props.onFinished.apply(null, arguments);
};
var position = {
top: props.top - 20,
};
var chevron = null;
if (props.left) {
chevron = <img className="mx_ContextualMenu_chevron_left" src="img/chevron-left.png" width="9" height="16" />
position.left = props.left + 8;
} else {
chevron = <img className="mx_ContextualMenu_chevron_right" src="img/chevron-right.png" width="9" height="16" />
position.right = props.right + 8;
}
var className = 'mx_ContextualMenu_wrapper';
// FIXME: If a menu uses getDefaultProps it clobbers the onFinished
// property set here so you can't close the menu from a button click!
var menu = (
<div className={className}>
<div className="mx_ContextualMenu" style={position}>
{chevron}
<Element {...props} onFinished={closeMenu}/>
</div>
<div className="mx_ContextualMenu_background" onClick={closeMenu}></div>
</div>
);
React.render(menu, this.getOrCreateContainer());
return {close: closeMenu};
},
};

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -44,6 +44,7 @@ ConferenceCall.prototype.setup = function() {
// looking for a 1:1 room with this conf user ID!)
var call = Matrix.createNewMatrixCall(self.client, room.roomId);
call.confUserId = self.confUserId;
call.groupRoomId = self.groupRoomId;
return call;
});
};
@@ -85,15 +86,15 @@ ConferenceCall.prototype._getConferenceUserRoom = function() {
};
/**
* Check if this room member is in fact a conference bot.
* @param {RoomMember} The room member to check
* Check if this user ID is in fact a conference bot.
* @param {string} userId The user ID to check.
* @return {boolean} True if it is a conference bot.
*/
module.exports.isConferenceUser = function(roomMember) {
if (roomMember.userId.indexOf("@" + USER_PREFIX) !== 0) {
module.exports.isConferenceUser = function(userId) {
if (userId.indexOf("@" + USER_PREFIX) !== 0) {
return false;
}
var base64part = roomMember.userId.split(":")[0].substring(1 + USER_PREFIX.length);
var base64part = userId.split(":")[0].substring(1 + USER_PREFIX.length);
if (base64part) {
var decoded = new Buffer(base64part, "base64").toString();
// ! $STUFF : $STUFF

54
src/component-index.js Normal file
View File

@@ -0,0 +1,54 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* THIS FILE IS AUTO-GENERATED
* You can edit it you like, but your changes will be overwritten,
* so you'd just be trying to swim upstream like a salmon.
* You are not a salmon.
*
* To update it, run:
* ./reskindex.js -h header
*/
module.exports.components = require('matrix-react-sdk/lib/component-index').components;
module.exports.components['structures.BottomLeftMenu'] = require('./components/structures/BottomLeftMenu');
module.exports.components['structures.CompatibilityPage'] = require('./components/structures/CompatibilityPage');
module.exports.components['structures.LeftPanel'] = require('./components/structures/LeftPanel');
module.exports.components['structures.RightPanel'] = require('./components/structures/RightPanel');
module.exports.components['structures.RoomDirectory'] = require('./components/structures/RoomDirectory');
module.exports.components['structures.RoomSubList'] = require('./components/structures/RoomSubList');
module.exports.components['structures.SearchBox'] = require('./components/structures/SearchBox');
module.exports.components['structures.ViewSource'] = require('./components/structures/ViewSource');
module.exports.components['views.elements.ImageView'] = require('./components/views/elements/ImageView');
module.exports.components['views.elements.Spinner'] = require('./components/views/elements/Spinner');
module.exports.components['views.globals.GuestWarningBar'] = require('./components/views/globals/GuestWarningBar');
module.exports.components['views.globals.MatrixToolbar'] = require('./components/views/globals/MatrixToolbar');
module.exports.components['views.globals.NewVersionBar'] = require('./components/views/globals/NewVersionBar');
module.exports.components['views.login.VectorCustomServerDialog'] = require('./components/views/login/VectorCustomServerDialog');
module.exports.components['views.login.VectorLoginFooter'] = require('./components/views/login/VectorLoginFooter');
module.exports.components['views.login.VectorLoginHeader'] = require('./components/views/login/VectorLoginHeader');
module.exports.components['views.messages.DateSeparator'] = require('./components/views/messages/DateSeparator');
module.exports.components['views.messages.MessageTimestamp'] = require('./components/views/messages/MessageTimestamp');
module.exports.components['views.messages.SenderProfile'] = require('./components/views/messages/SenderProfile');
module.exports.components['views.rooms.BottomLeftMenuTile'] = require('./components/views/rooms/BottomLeftMenuTile');
module.exports.components['views.rooms.MessageContextMenu'] = require('./components/views/rooms/MessageContextMenu');
module.exports.components['views.rooms.RoomDNDView'] = require('./components/views/rooms/RoomDNDView');
module.exports.components['views.rooms.RoomDropTarget'] = require('./components/views/rooms/RoomDropTarget');
module.exports.components['views.rooms.RoomTooltip'] = require('./components/views/rooms/RoomTooltip');
module.exports.components['views.rooms.SearchBar'] = require('./components/views/rooms/SearchBar');
module.exports.components['views.settings.Notifications'] = require('./components/views/settings/Notifications');

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -40,19 +40,26 @@ module.exports = React.createClass({
return <div className="mx_RoomTile_name">{name}</div>
}
else if (this.state.hover) {
var RoomTooltip = sdk.getComponent("molecules.RoomTooltip");
var RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
return <RoomTooltip name={name}/>;
}
},
render: function() {
var BottomLeftMenuTile = sdk.getComponent('molecules.BottomLeftMenuTile');
var BottomLeftMenuTile = sdk.getComponent('rooms.BottomLeftMenuTile');
var TintableSvg = sdk.getComponent('elements.TintableSvg');
return (
<div className="mx_BottomLeftMenu">
<div className="mx_BottomLeftMenu_options">
<BottomLeftMenuTile collapsed={ this.props.collapsed } img="img/create-big.png" label="Create new room" onClick={ this.onCreateRoomClick }/>
<BottomLeftMenuTile collapsed={ this.props.collapsed } img="img/directory-big.png" label="Directory" onClick={ this.onRoomDirectoryClick }/>
<BottomLeftMenuTile collapsed={ this.props.collapsed } img="img/settings-big.png" label="Settings" onClick={ this.onSettingsClick }/>
<div className="mx_BottomLeftMenu_createRoom" title="Start chat" onClick={ this.onCreateRoomClick }>
<TintableSvg src="img/icons-create-room.svg" width="24" height="24"/>
</div>
<div className="mx_BottomLeftMenu_directory" title="Room directory" onClick={ this.onRoomDirectoryClick }>
<TintableSvg src="img/icons-directory.svg" width="24" height="24"/>
</div>
<div className="mx_BottomLeftMenu_settings" title="Settings" onClick={ this.onSettingsClick }>
<TintableSvg src="img/icons-settings.svg" width="24" height="24"/>
</div>
</div>
</div>
);

View File

@@ -0,0 +1,66 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require('react');
module.exports = React.createClass({
displayName: 'CompatibilityPage',
propTypes: {
onAccept: React.PropTypes.func
},
getDefaultProps: function() {
return {
onAccept: function() {} // NOP
};
},
onAccept: function() {
this.props.onAccept();
},
render: function() {
return (
<div className="mx_CompatibilityPage">
<div className="mx_CompatibilityPage_box">
<p>Sorry, your browser is <b>not</b> able to run Vector.</p>
<p>
Vector uses many advanced browser features, some of which are not
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>,
<a href="http://apple.com/safari">Safari</a> and
<a href="http://opera.com">Opera</a> work too.
</p>
<p>
With your current browser, the look and feel of the application may
be completely incorrect, and some or all features may not function.
If you want to try it anyway you can continue, but you are on your own
in terms of any issues you may encounter!
</p>
<button onClick={this.onAccept}>
I understand the risks and wish to continue
</button>
</div>
</div>
);
}
});

View File

@@ -0,0 +1,133 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require('react');
var DragDropContext = require('react-dnd').DragDropContext;
var HTML5Backend = require('react-dnd-html5-backend');
var sdk = require('matrix-react-sdk')
var dis = require('matrix-react-sdk/lib/dispatcher');
var VectorConferenceHandler = require('../../VectorConferenceHandler');
var CallHandler = require("matrix-react-sdk/lib/CallHandler");
var LeftPanel = React.createClass({
displayName: 'LeftPanel',
getInitialState: function() {
return {
showCallElement: null,
searchFilter: '',
};
},
componentDidMount: function() {
this.dispatcherRef = dis.register(this.onAction);
},
componentWillReceiveProps: function(newProps) {
this._recheckCallElement(newProps.selectedRoom);
},
componentWillUnmount: function() {
dis.unregister(this.dispatcherRef);
},
onAction: function(payload) {
switch (payload.action) {
// listen for call state changes to prod the render method, which
// may hide the global CallView if the call it is tracking is dead
case 'call_state':
this._recheckCallElement(this.props.selectedRoom);
break;
}
},
_recheckCallElement: function(selectedRoomId) {
// if we aren't viewing a room with an ongoing call, but there is an
// active call, show the call element - we need to do this to make
// audio/video not crap out
var activeCall = CallHandler.getAnyActiveCall();
var callForRoom = CallHandler.getCallForRoom(selectedRoomId);
var showCall = (activeCall && activeCall.call_state === 'connected' && !callForRoom);
this.setState({
showCallElement: showCall
});
},
onHideClick: function() {
dis.dispatch({
action: 'hide_left_panel',
});
},
onCallViewClick: function() {
var call = CallHandler.getAnyActiveCall();
if (call) {
dis.dispatch({
action: 'view_room',
room_id: call.groupRoomId || call.roomId,
});
}
},
onSearch: function(term) {
this.setState({ searchFilter: term });
},
render: function() {
var RoomList = sdk.getComponent('rooms.RoomList');
var BottomLeftMenu = sdk.getComponent('structures.BottomLeftMenu');
var SearchBox = sdk.getComponent('structures.SearchBox');
var collapseButton;
var classes = "mx_LeftPanel mx_fadable";
if (this.props.collapsed) {
classes += " collapsed";
}
else {
// Hide the collapse button until we work out how to display it in the new skin
// collapseButton = <img className="mx_LeftPanel_hideButton" onClick={ this.onHideClick } src="img/hide.png" width="12" height="20" alt="<"/>
}
var callPreview;
if (this.state.showCallElement && !this.props.collapsed) {
var CallView = sdk.getComponent('voip.CallView');
callPreview = (
<CallView
className="mx_LeftPanel_callView" onClick={this.onCallViewClick}
ConferenceHandler={VectorConferenceHandler} />
);
}
return (
<aside className={classes} style={{ opacity: this.props.opacity }}>
<SearchBox collapsed={ this.props.collapsed } onSearch={ this.onSearch } />
{ collapseButton }
{ callPreview }
<RoomList
selectedRoom={this.props.selectedRoom}
collapsed={this.props.collapsed}
searchFilter={this.state.searchFilter}
ConferenceHandler={VectorConferenceHandler} />
<BottomLeftMenu collapsed={this.props.collapsed}/>
</aside>
);
}
});
module.exports = DragDropContext(HTML5Backend)(LeftPanel);

View File

@@ -0,0 +1,181 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require('react');
var sdk = require('matrix-react-sdk')
var dis = require('matrix-react-sdk/lib/dispatcher');
var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
var rate_limited_func = require('matrix-react-sdk/lib/ratelimitedfunc');
module.exports = React.createClass({
displayName: 'RightPanel',
Phase : {
MemberList: 'MemberList',
FileList: 'FileList',
MemberInfo: 'MemberInfo',
},
componentWillMount: function() {
this.dispatcherRef = dis.register(this.onAction);
var cli = MatrixClientPeg.get();
cli.on("RoomState.members", this.onRoomStateMember);
},
componentWillUnmount: function() {
dis.unregister(this.dispatcherRef);
if (MatrixClientPeg.get()) {
MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember);
}
},
getInitialState: function() {
return {
phase : this.Phase.MemberList
}
},
onMemberListButtonClick: function() {
if (this.props.collapsed) {
this.setState({ phase: this.Phase.MemberList });
dis.dispatch({
action: 'show_right_panel',
});
}
else {
dis.dispatch({
action: 'hide_right_panel',
});
}
},
onRoomStateMember: function(ev, state, member) {
// redraw the badge on the membership list
if (this.state.phase == this.Phase.MemberList && member.roomId === this.props.roomId) {
this._delayedUpdate();
}
else if (this.state.phase === this.Phase.MemberInfo && member.roomId === this.props.roomId &&
member.userId === this.state.member.userId) {
// refresh the member info (e.g. new power level)
this._delayedUpdate();
}
},
_delayedUpdate: new rate_limited_func(function() {
this.forceUpdate();
}, 500),
onAction: function(payload) {
if (payload.action === "view_user") {
dis.dispatch({
action: 'show_right_panel',
});
if (payload.member) {
this.setState({
phase: this.Phase.MemberInfo,
member: payload.member,
});
}
else {
this.setState({
phase: this.Phase.MemberList
});
}
}
if (payload.action === "view_room") {
if (this.state.phase === this.Phase.MemberInfo) {
this.setState({
phase: this.Phase.MemberList
});
}
}
},
render: function() {
var MemberList = sdk.getComponent('rooms.MemberList');
var TintableSvg = sdk.getComponent("elements.TintableSvg");
var buttonGroup;
var panel;
var filesHighlight;
var membersHighlight;
if (!this.props.collapsed) {
if (this.state.phase == this.Phase.MemberList || this.state.phase === this.Phase.MemberInfo) {
membersHighlight = <div className="mx_RightPanel_headerButton_highlight"></div>;
}
else if (this.state.phase == this.Phase.FileList) {
filesHighlight = <div className="mx_RightPanel_headerButton_highlight"></div>;
}
}
var membersBadge;
if ((this.state.phase == this.Phase.MemberList || this.state.phase === this.Phase.MemberInfo) && this.props.roomId) {
var cli = MatrixClientPeg.get();
var room = cli.getRoom(this.props.roomId);
if (room) {
membersBadge = <div className="mx_RightPanel_headerButton_badge">{ room.getJoinedMembers().length }</div>;
}
}
if (this.props.roomId) {
buttonGroup =
<div className="mx_RightPanel_headerButtonGroup">
<div className="mx_RightPanel_headerButton" title="Members" onClick={ this.onMemberListButtonClick }>
<TintableSvg src="img/members.svg" width="17" height="22"/>
{ membersBadge }
{ membersHighlight }
</div>
<div className="mx_RightPanel_headerButton mx_RightPanel_filebutton" title="Files">
<TintableSvg src="img/files.svg" width="17" height="22"/>
{ filesHighlight }
</div>
</div>;
if (!this.props.collapsed) {
if(this.state.phase == this.Phase.MemberList) {
panel = <MemberList roomId={this.props.roomId} key={this.props.roomId} />
}
else if(this.state.phase == this.Phase.MemberInfo) {
var MemberInfo = sdk.getComponent('rooms.MemberInfo');
panel = <MemberInfo roomId={this.props.roomId} member={this.state.member} key={this.props.roomId} />
}
}
}
if (!panel) {
panel = <div className="mx_RightPanel_blank"></div>;
}
var classes = "mx_RightPanel mx_fadable";
if (this.props.collapsed) {
classes += " collapsed";
}
return (
<aside className={classes} style={{ opacity: this.props.opacity }}>
<div className="mx_RightPanel_header">
{ buttonGroup }
</div>
{ panel }
<div className="mx_RightPanel_footer">
</div>
</aside>
);
}
});

View File

@@ -0,0 +1,228 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require('react');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var ContentRepo = require("matrix-js-sdk").ContentRepo;
var Modal = require('matrix-react-sdk/lib/Modal');
var sdk = require('matrix-react-sdk')
var dis = require('matrix-react-sdk/lib/dispatcher');
var GeminiScrollbar = require('react-gemini-scrollbar');
var linkify = require('linkifyjs');
var linkifyString = require('linkifyjs/string');
var linkifyMatrix = require('matrix-react-sdk/lib/linkify-matrix');
var sanitizeHtml = require('sanitize-html');
linkifyMatrix(linkify);
module.exports = React.createClass({
displayName: 'RoomDirectory',
getInitialState: function() {
return {
publicRooms: [],
roomAlias: '',
loading: true,
}
},
componentWillMount: function() {
// dis.dispatch({
// action: 'ui_opacity',
// sideOpacity: 0.3,
// middleOpacity: 0.3,
// });
},
componentDidMount: function() {
var self = this;
MatrixClientPeg.get().publicRooms(function (err, data) {
if (err) {
self.setState({ loading: false });
console.error("Failed to get publicRooms: %s", JSON.stringify(err));
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to get public room list",
description: err.message
});
}
else {
self.setState({
publicRooms: data.chunk,
loading: false,
});
self.forceUpdate();
}
});
},
componentWillUnmount: function() {
// dis.dispatch({
// action: 'ui_opacity',
// sideOpacity: 1.0,
// middleOpacity: 1.0,
// });
},
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;
}
}
var oob_data = {};
if (room) {
if (MatrixClientPeg.get().isGuest()) {
if (!room.world_readable && !room.guest_can_join) {
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
Modal.createDialog(NeedToRegisterDialog, {
title: "Failed to join the room",
description: "This room is inaccessible to guests. You may be able to join if you register."
});
return;
}
}
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"),
};
}
dis.dispatch({
action: 'view_room',
room_id: roomId,
oob_data: oob_data,
});
},
getRows: function(filter) {
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
if (!this.state.publicRooms) return [];
var rooms = this.state.publicRooms.filter(function(a) {
// FIXME: if incrementally typing, keep narrowing down the search set
// incrementally rather than starting over each time.
return (((a.name && a.name.toLowerCase().search(filter.toLowerCase()) >= 0) ||
(a.aliases && a.aliases[0].toLowerCase().search(filter.toLowerCase()) >= 0)) &&
a.num_joined_members > 0);
}).sort(function(a,b) {
return a.num_joined_members - b.num_joined_members;
});
var rows = [];
var self = this;
var guestRead, guestJoin, perms;
for (var i = 0; i < rooms.length; i++) {
var alias = rooms[i].canonical_alias || (rooms[i].aliases ? rooms[i].aliases[0] : "");
var name = rooms[i].name || alias || "Unnamed room";
guestRead = null;
guestJoin = null;
if (rooms[i].world_readable) {
guestRead = (
<div className="mx_RoomDirectory_perm">World readable</div>
);
}
if (rooms[i].guest_can_join) {
guestJoin = (
<div className="mx_RoomDirectory_perm">Guests can join</div>
);
}
perms = null;
if (guestRead || guestJoin) {
perms = <div className="mx_RoomDirectory_perms">{guestRead} {guestJoin}</div>;
}
var topic = rooms[i].topic || '';
topic = linkifyString(sanitizeHtml(topic));
rows.unshift(
<tr key={ rooms[i].room_id } onClick={self.showRoom.bind(null, rooms[i].room_id)}>
<td className="mx_RoomDirectory_roomAvatar">
<BaseAvatar width={24} height={24} resizeMethod='crop'
name={ name } idName={ name }
url={ ContentRepo.getHttpUriForMxc(
MatrixClientPeg.get().getHomeserverUrl(),
rooms[i].avatar_url, 24, 24, "crop") } />
</td>
<td className="mx_RoomDirectory_roomDescription">
<div className="mx_RoomDirectory_name">{ name }</div>&nbsp;
{ perms }
<div className="mx_RoomDirectory_topic"
onClick={ function(e) { e.stopPropagation() } }
dangerouslySetInnerHTML={{ __html: topic }}/>
<div className="mx_RoomDirectory_alias">{ alias }</div>
</td>
<td className="mx_RoomDirectory_roomMemberCount">
{ rooms[i].num_joined_members }
</td>
</tr>
);
}
return rows;
},
onKeyUp: function(ev) {
this.forceUpdate();
this.setState({ roomAlias : this.refs.roomAlias.value })
if (ev.key == "Enter") {
this.showRoom(this.refs.roomAlias.value);
}
},
render: function() {
if (this.state.loading) {
var Loader = sdk.getComponent("elements.Spinner");
return (
<div className="mx_RoomDirectory">
<Loader />
</div>
);
}
var SimpleRoomHeader = sdk.getComponent('rooms.SimpleRoomHeader');
return (
<div className="mx_RoomDirectory">
<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} >
<table ref="directory_table" className="mx_RoomDirectory_table">
<tbody>
{ this.getRows(this.state.roomAlias) }
</tbody>
</table>
</GeminiScrollbar>
</div>
</div>
);
}
});

View File

@@ -0,0 +1,367 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require('react');
var DropTarget = require('react-dnd').DropTarget;
var sdk = require('matrix-react-sdk')
var dis = require('matrix-react-sdk/lib/dispatcher');
var Unread = require('matrix-react-sdk/lib/Unread');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
// turn this on for drop & drag console debugging galore
var debug = false;
var roomListTarget = {
canDrop: function() {
return true;
},
drop: function(props, monitor, component) {
if (debug) console.log("dropped on sublist")
},
hover: function(props, monitor, component) {
var item = monitor.getItem();
if (component.state.sortedList.length == 0 && props.editable) {
if (debug) console.log("hovering on sublist " + props.label + ", isOver=" + monitor.isOver());
if (item.targetList !== component) {
item.targetList.removeRoomTile(item.room);
item.targetList = component;
}
component.moveRoomTile(item.room, 0);
}
},
};
var RoomSubList = React.createClass({
displayName: 'RoomSubList',
debug: debug,
propTypes: {
list: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
label: React.PropTypes.string.isRequired,
tagName: React.PropTypes.string,
editable: React.PropTypes.bool,
order: React.PropTypes.string.isRequired,
selectedRoom: React.PropTypes.string.isRequired,
startAsHidden: React.PropTypes.bool,
showSpinner: React.PropTypes.bool, // true to show a spinner if 0 elements when expanded
collapsed: React.PropTypes.bool.isRequired, // is LeftPanel collapsed?
onHeaderClick: React.PropTypes.func,
alwaysShowHeader: React.PropTypes.bool,
incomingCall: React.PropTypes.object,
onShowMoreRooms: React.PropTypes.func,
searchFilter: React.PropTypes.string,
},
getInitialState: function() {
return {
hidden: this.props.startAsHidden || false,
truncateAt: 20,
sortedList: [],
};
},
getDefaultProps: function() {
return {
onHeaderClick: function() {}, // NOP
onShowMoreRooms: function() {} // NOP
};
},
componentWillMount: function() {
this.sortList(this.applySearchFilter(this.props.list, this.props.searchFilter), this.props.order);
},
componentWillReceiveProps: function(newProps) {
// order the room list appropriately before we re-render
//if (debug) console.log("received new props, list = " + newProps.list);
this.sortList(this.applySearchFilter(newProps.list, newProps.searchFilter), newProps.order);
},
applySearchFilter: function(list, filter) {
if (filter === "") return list;
return list.filter((room) => {
return room.name && room.name.toLowerCase().indexOf(filter.toLowerCase()) >= 0
});
},
onClick: function(ev) {
var isHidden = !this.state.hidden;
this.setState({ hidden : isHidden });
if (isHidden) {
// as good a way as any to reset the truncate state
this.setState({ truncateAt : 20 });
this.props.onShowMoreRooms();
}
this.props.onHeaderClick(isHidden);
},
tsOfNewestEvent: function(room) {
for (var i = room.timeline.length - 1; i >= 0; --i) {
var ev = room.timeline[i];
if (Unread.eventTriggersUnreadCount(ev) ||
(ev.sender && ev.sender.userId === MatrixClientPeg.get().credentials.userId))
{
return ev.getTs();
}
}
// we might only have events that don't trigger the unread indicator,
// in which case use the oldest event even if normally it wouldn't count.
// This is better than just assuming the last event was forever ago.
if (room.timeline.length) {
return room.timeline[0].getTs();
} else {
return Number.MAX_SAFE_INTEGER;
}
},
// TODO: factor the comparators back out into a generic comparator
// so that view_prev_room and view_next_room can do the right thing
recentsComparator: function(roomA, roomB) {
return this.tsOfNewestEvent(roomB) - this.tsOfNewestEvent(roomA);
},
manualComparator: function(roomA, roomB) {
if (!roomA.tags[this.props.tagName] || !roomB.tags[this.props.tagName]) return 0;
var a = roomA.tags[this.props.tagName].order;
var b = roomB.tags[this.props.tagName].order;
return a == b ? this.recentsComparator(roomA, roomB) : ( a > b ? 1 : -1);
},
sortList: function(list, order) {
if (list === undefined) list = this.state.sortedList;
if (order === undefined) order = this.props.order;
var comparator;
list = list || [];
if (order === "manual") comparator = this.manualComparator;
if (order === "recent") comparator = this.recentsComparator;
//if (debug) console.log("sorting list for sublist " + this.props.label + " with length " + list.length + ", this.props.list = " + this.props.list);
this.setState({ sortedList: list.sort(comparator) });
},
moveRoomTile: function(room, atIndex) {
if (debug) console.log("moveRoomTile: id " + room.roomId + ", atIndex " + atIndex);
//console.log("moveRoomTile before: " + JSON.stringify(this.state.rooms));
var found = this.findRoomTile(room);
var rooms = this.state.sortedList;
if (found.room) {
if (debug) console.log("removing at index " + found.index + " and adding at index " + atIndex);
rooms.splice(found.index, 1);
rooms.splice(atIndex, 0, found.room);
}
else {
if (debug) console.log("Adding at index " + atIndex);
rooms.splice(atIndex, 0, room);
}
this.setState({ sortedList: rooms });
// console.log("moveRoomTile after: " + JSON.stringify(this.state.rooms));
},
// XXX: this isn't invoked via a property method but indirectly via
// the roomList property method. Unsure how evil this is.
removeRoomTile: function(room) {
if (debug) console.log("remove room " + room.roomId);
var found = this.findRoomTile(room);
var rooms = this.state.sortedList;
if (found.room) {
rooms.splice(found.index, 1);
}
else {
console.warn("Can't remove room " + room.roomId + " - can't find it");
}
this.setState({ sortedList: rooms });
},
findRoomTile: function(room) {
var index = this.state.sortedList.indexOf(room);
if (index >= 0) {
// console.log("found: room: " + room.roomId + " with index " + index);
}
else {
if (debug) console.log("didn't find room");
room = null;
}
return ({
room: room,
index: index,
});
},
calcManualOrderTagData: function(room) {
var index = this.state.sortedList.indexOf(room);
// we sort rooms by the lexicographic ordering of the 'order' metadata on their tags.
// for convenience, we calculate this for now a floating point number between 0.0 and 1.0.
var orderA = 0.0; // by default we're next to the beginning of the list
if (index > 0) {
var prevTag = this.state.sortedList[index - 1].tags[this.props.tagName];
if (!prevTag) {
console.error("Previous room in sublist is not tagged to be in this list. This should never happen.")
}
else if (prevTag.order === undefined) {
console.error("Previous room in sublist has no ordering metadata. This should never happen.");
}
else {
orderA = prevTag.order;
}
}
var orderB = 1.0; // by default we're next to the end of the list too
if (index < this.state.sortedList.length - 1) {
var nextTag = this.state.sortedList[index + 1].tags[this.props.tagName];
if (!nextTag) {
console.error("Next room in sublist is not tagged to be in this list. This should never happen.")
}
else if (nextTag.order === undefined) {
console.error("Next room in sublist has no ordering metadata. This should never happen.");
}
else {
orderB = nextTag.order;
}
}
var order = (orderA + orderB) / 2.0;
if (order === orderA || order === orderB) {
console.error("Cannot describe new list position. This should be incredibly unlikely.");
// TODO: renumber the list
}
return order;
},
makeRoomTiles: function() {
var self = this;
var RoomTile = sdk.getComponent("rooms.RoomTile");
return this.state.sortedList.map(function(room) {
var selected = room.roomId == self.props.selectedRoom;
// XXX: is it evil to pass in self as a prop to RoomTile?
return (
<RoomTile
room={ room }
roomSubList={ self }
key={ room.roomId }
collapsed={ self.props.collapsed || false}
selected={ selected }
unread={ Unread.doesRoomHaveUnreadMessages(room) }
highlight={ room.getUnreadNotificationCount('highlight') > 0 || self.props.label === 'Invites' }
isInvite={ self.props.label === 'Invites' }
incomingCall={ self.props.incomingCall && (self.props.incomingCall.roomId === room.roomId) ? self.props.incomingCall : null } />
);
});
},
_getHeaderJsx: function() {
var TintableSvg = sdk.getComponent("elements.TintableSvg");
return (
<h2 onClick={ this.onClick } className="mx_RoomSubList_label">
{ this.props.collapsed ? '' : this.props.label }
<img className="mx_RoomSubList_chevron"
src={ this.state.hidden ? "img/list-close.svg" : "img/list-open.svg" }
width="10" height="10" />
</h2>
);
},
_createOverflowTile: function(overflowCount, totalCount) {
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
// XXX: this is duplicated from RoomTile - factor it out
return (
<div className="mx_RoomTile mx_RoomTile_ellipsis" onClick={this._showFullMemberList}>
<div className="mx_RoomTile_avatar">
<BaseAvatar url="img/ellipsis.svg" name="..." width={24} height={24} />
</div>
<div className="mx_RoomTile_name">and { overflowCount } others...</div>
</div>
);
},
_showFullMemberList: function() {
this.setState({
truncateAt: -1
});
this.props.onShowMoreRooms();
},
render: function() {
var connectDropTarget = this.props.connectDropTarget;
var RoomDropTarget = sdk.getComponent('rooms.RoomDropTarget');
var TruncatedList = sdk.getComponent('elements.TruncatedList');
var label = this.props.collapsed ? null : this.props.label;
//console.log("render: " + JSON.stringify(this.state.sortedList));
var target;
if (this.state.sortedList.length == 0 && this.props.editable) {
target = <RoomDropTarget label={ 'Drop here to ' + this.props.verb }/>;
}
if (this.state.sortedList.length > 0 || this.props.editable) {
var subList;
var classes = "mx_RoomSubList";
if (!this.state.hidden) {
subList = <TruncatedList className={ classes } truncateAt={this.state.truncateAt}
createOverflowElement={this._createOverflowTile} >
{ target }
{ this.makeRoomTiles() }
</TruncatedList>;
}
else {
subList = <TruncatedList className={ classes }>
</TruncatedList>;
}
return connectDropTarget(
<div>
{ this._getHeaderJsx() }
{ subList }
</div>
);
}
else {
var Loader = sdk.getComponent("elements.Spinner");
return (
<div className="mx_RoomSubList">
{ this.props.alwaysShowHeader ? this._getHeaderJsx() : undefined }
{ (this.props.showSpinner && !this.state.hidden) ? <Loader /> : undefined }
</div>
);
}
}
});
// Export the wrapped version, inlining the 'collect' functions
// to more closely resemble the ES7
module.exports =
DropTarget('RoomTile', roomListTarget, function(connect) {
return {
connectDropTarget: connect.dropTarget(),
}
})(RoomSubList);

View File

@@ -0,0 +1,119 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require('react');
var sdk = require('matrix-react-sdk')
var dis = require('matrix-react-sdk/lib/dispatcher');
var rate_limited_func = require('matrix-react-sdk/lib/ratelimitedfunc');
module.exports = React.createClass({
displayName: 'SearchBox',
propTypes: {
collapsed: React.PropTypes.bool,
onSearch: React.PropTypes.func,
},
getInitialState: function() {
return {
searchTerm: "",
};
},
onChange: function() {
if (!this.refs.search) return;
this.setState({ searchTerm: this.refs.search.value });
this.onSearch();
},
onSearch: new rate_limited_func(
function() {
this.props.onSearch(this.refs.search.value);
},
100
),
onToggleCollapse: function(show) {
if (show) {
dis.dispatch({
action: 'show_left_panel',
});
}
else {
dis.dispatch({
action: 'hide_left_panel',
});
}
},
render: function() {
var TintableSvg = sdk.getComponent('elements.TintableSvg');
var toggleCollapse;
if (this.props.collapsed) {
toggleCollapse =
<div className="mx_SearchBox_maximise" onClick={ this.onToggleCollapse.bind(this, true) }>
<TintableSvg src="img/maximise.svg" width="10" height="16" alt="&lt;"/>
</div>
}
else {
toggleCollapse =
<div className="mx_SearchBox_minimise" onClick={ this.onToggleCollapse.bind(this, false) }>
<TintableSvg src="img/minimise.svg" width="10" height="16" alt="&lt;"/>
</div>
}
var searchControls;
if (!this.props.collapsed) {
searchControls = [
this.state.searchTerm.length > 0 ?
<div key="button"
className="mx_SearchBox_closeButton"
onClick={ ()=>{ this.refs.search.value = ""; this.onChange(); } }>
<TintableSvg
className="mx_SearchBox_searchButton"
src="img/icons-close.svg" width="24" height="24"
/>
</div>
:
<TintableSvg
key="button"
className="mx_SearchBox_searchButton"
src="img/right_search.svg" width="24" height="24"
/>,
<input
key="searchfield"
type="text"
ref="search"
className="mx_SearchBox_search"
value={ this.state.searchTerm }
onChange={ this.onChange }
placeholder="Search room names"
/>
];
}
var self = this;
return (
<div className="mx_SearchBox">
{ searchControls }
{ toggleCollapse }
</div>
);
}
});

View File

@@ -0,0 +1,54 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require('react');
module.exports = React.createClass({
displayName: 'ViewSource',
propTypes: {
onFinished: React.PropTypes.func.isRequired
},
componentDidMount: function() {
document.addEventListener("keydown", this.onKeyDown);
},
componentWillUnmount: function() {
document.removeEventListener("keydown", this.onKeyDown);
},
onKeyDown: function(ev) {
if (ev.keyCode == 27) { // escape
ev.stopPropagation();
ev.preventDefault();
this.props.onFinished();
}
},
render: function() {
return (
<div className="mx_ViewSource">
<pre>
{JSON.stringify(this.props.mxEvent.event, null, 2)}
</pre>
</div>
);
}
});

View File

@@ -0,0 +1,189 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require('react');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var DateUtils = require('matrix-react-sdk/lib/DateUtils');
var filesize = require('filesize');
module.exports = React.createClass({
displayName: 'ImageView',
propTypes: {
src: React.PropTypes.string.isRequired, // the source of the image being displayed
name: React.PropTypes.string, // the main title ('name') for the image
link: React.PropTypes.string, // the link (if any) applied to the name of the image
width: React.PropTypes.number, // width of the image src in pixels
height: React.PropTypes.number, // height of the image src in pixels
fileSize: React.PropTypes.number, // size of the image src in bytes
onFinished: React.PropTypes.func.isRequired, // callback when the lightbox is dismissed
// the event (if any) that the Image is displaying. Used for event-specific stuff like
// redactions, senders, timestamps etc. Other descriptors are taken from the explicit
// properties above, which let us use lightboxes to display images which aren't associated
// with events.
mxEvent: React.PropTypes.object,
},
// XXX: keyboard shortcuts for managing dialogs should be done by the modal
// dialog base class somehow, surely...
componentDidMount: function() {
document.addEventListener("keydown", this.onKeyDown);
},
componentWillUnmount: function() {
document.removeEventListener("keydown", this.onKeyDown);
},
onKeyDown: function(ev) {
if (ev.keyCode == 27) { // escape
ev.stopPropagation();
ev.preventDefault();
this.props.onFinished();
}
},
onRedactClick: function() {
var self = this;
MatrixClientPeg.get().redactEvent(
this.props.mxEvent.getRoomId(), this.props.mxEvent.getId()
).done(function() {
if (self.props.onFinished) self.props.onFinished();
}, function(e) {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
// display error message stating you couldn't delete this.
var code = e.errcode || e.statusCode;
Modal.createDialog(ErrorDialog, {
title: "Error",
description: "You cannot delete this image. (" + code + ")"
});
});
},
getName: function () {
var name = this.props.name;
if (name && this.props.link) {
name = <a href={ this.props.link } target="_blank">{ name }</a>;
}
return name;
},
render: function() {
/*
// In theory max-width: 80%, max-height: 80% on the CSS should work
// but in practice, it doesn't, so do it manually:
var width = this.props.width || 500;
var height = this.props.height || 500;
var maxWidth = document.documentElement.clientWidth * 0.8;
var maxHeight = document.documentElement.clientHeight * 0.8;
var widthFrac = width / maxWidth;
var heightFrac = height / maxHeight;
var displayWidth;
var displayHeight;
if (widthFrac > heightFrac) {
displayWidth = Math.min(width, maxWidth);
displayHeight = (displayWidth / width) * height;
} else {
displayHeight = Math.min(height, maxHeight);
displayWidth = (displayHeight / height) * width;
}
var style = {
width: displayWidth,
height: displayHeight
};
*/
var style, res;
if (this.props.width && this.props.height) {
style = {
width: this.props.width,
height: this.props.height,
};
res = style.width + "x" + style.height + "px";
}
var size;
if (this.props.fileSize) {
size = filesize(this.props.fileSize);
}
var size_res;
if (size && res) {
size_res = size + ", " + res;
}
else {
size_res = size || res;
}
var showEventMeta = !!this.props.mxEvent;
var eventMeta;
if(showEventMeta) {
eventMeta = (<div className="mx_ImageView_metadata">
Uploaded on { DateUtils.formatDate(new Date(this.props.mxEvent.getTs())) } by { this.props.mxEvent.getSender() }
</div>);
}
var eventRedact;
if(showEventMeta) {
eventRedact = (<div className="mx_ImageView_button" onClick={this.onRedactClick}>
Redact
</div>);
}
return (
<div className="mx_ImageView">
<div className="mx_ImageView_lhs">
</div>
<div className="mx_ImageView_content">
<img src={this.props.src} style={style}/>
<div className="mx_ImageView_labelWrapper">
<div className="mx_ImageView_label">
<img className="mx_ImageView_cancel" src="img/cancel-white.svg" width="18" height="18" alt="Close" onClick={ this.props.onFinished }/>
<div className="mx_ImageView_shim">
</div>
<div className="mx_ImageView_name">
{ this.getName() }
</div>
{ eventMeta }
<a className="mx_ImageView_link" href={ this.props.src } target="_blank">
<div className="mx_ImageView_download">
Download this file<br/>
<span className="mx_ImageView_size">{ size_res }</span>
</div>
</a>
{ eventRedact }
<div className="mx_ImageView_shim">
</div>
</div>
</div>
</div>
<div className="mx_ImageView_rhs">
</div>
</div>
);
}
});

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ module.exports = React.createClass({
var h = this.props.h || 32;
var imgClass = this.props.imgClassName || "";
return (
<div>
<div className="mx_Spinner">
<img src="img/spinner.gif" width={w} height={h} className={imgClass}/>
</div>
);

View File

@@ -0,0 +1,43 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var React = require('react');
var dis = require('matrix-react-sdk/lib/dispatcher')
module.exports = React.createClass({
displayName: 'GuestWarningBar',
onRegisterClicked: function() {
dis.dispatch({'action': 'start_upgrade_registration'});
},
onLoginClicked: function() {
dis.dispatch({'action': 'logout'});
dis.dispatch({'action': 'start_login'});
},
render: function() {
return (
<div className="mx_GuestWarningBar">
<img className="mx_GuestWarningBar_warning" src="img/warning.svg" width="24" height="23" alt="/!\"/>
<div>
You are using Vector as a guest. <a onClick={this.onRegisterClicked}>Register</a> or <a onClick={this.onLoginClicked}>log in</a> to access more rooms and features.
</div>
</div>
);
}
});

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -17,23 +17,28 @@ limitations under the License.
'use strict';
var React = require('react');
var Notifier = require("matrix-react-sdk/lib/Notifier");
var sdk = require('matrix-react-sdk')
module.exports = React.createClass({
displayName: 'MatrixToolbar',
hideToolbar: function() {
var Notifier = sdk.getComponent('organisms.Notifier');
Notifier.setToolbarHidden(true);
},
onClick: function() {
Notifier.setEnabled(true);
},
render: function() {
var EnableNotificationsButton = sdk.getComponent("atoms.EnableNotificationsButton");
return (
<div className="mx_MatrixToolbar">
You are not receiving desktop notifications. <EnableNotificationsButton />
<div className="mx_MatrixToolbar_close"><img src="img/close-white.png" width="16" height="16" onClick={ this.hideToolbar } /></div>
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="/!\"/>
<div>
You are not receiving desktop notifications. <a className="mx_MatrixToolbar_link" onClick={ this.onClick }>Enable them now</a>
</div>
<div className="mx_MatrixToolbar_close"><img src="img/cancel.svg" width="18" height="18" onClick={ this.hideToolbar } /></div>
</div>
);
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -17,17 +17,20 @@ limitations under the License.
'use strict';
var React = require('react');
//var RoomDropTargetController = require('matrix-react-sdk/lib/controllers/molecules/RoomDropTargetController')
var sdk = require('matrix-react-sdk')
module.exports = React.createClass({
displayName: 'RoomDropTarget',
// mixins: [RoomDropTargetController],
displayName: 'NewVersionBar',
render: function() {
return (
<div className="mx_RoomDropTarget">
{this.props.text}
<div className="mx_MatrixToolbar">
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="/!\"/>
<div>
A new version of Vector is available. Refresh your browser.
</div>
</div>
);
}
});

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,38 +14,36 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
/*
* Usage:
* Modal.createDialog(ErrorDialog, {
* title: "some text", (default: "Error")
* description: "some more text",
* button: "Button Text",
* onClose: someFunction,
* focus: true|false (default: true)
* });
*/
var React = require('react');
var ErrorDialogController = require('matrix-react-sdk/lib/controllers/organisms/ErrorDialog')
var React = require("react");
module.exports = React.createClass({
displayName: 'ErrorDialog',
mixins: [ErrorDialogController],
displayName: 'VectorCustomServerDialog',
statics: {
replaces: 'CustomServerDialog',
},
render: function() {
return (
<div className="mx_ErrorDialog">
<div className="mx_ErrorDialogTitle">
{this.props.title}
<div className="mx_Dialog_title">
Custom Server Options
</div>
<div className="mx_Dialog_content">
{this.props.description}
<span>
You can use the custom server options to log into other Matrix
servers by specifying a different Home server URL.
<br/>
This allows you to use Vector with an existing Matrix account on
a different home server.
<br/>
<br/>
You can also set a custom identity server but you won't be able to
invite users by email address, or be invited by email address yourself.
</span>
</div>
<div className="mx_Dialog_buttons">
<button onClick={this.props.onFinished} autoFocus={this.props.focus}>
{this.props.button}
<button onClick={this.props.onFinished} autoFocus={true}>
Dismiss
</button>
</div>
</div>

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,26 +18,20 @@ limitations under the License.
var React = require('react');
var TextForEvent = require('matrix-react-sdk/lib/TextForEvent');
module.exports = React.createClass({
displayName: 'EventAsTextTile',
displayName: 'VectorLoginFooter',
statics: {
needsSenderProfile: function() {
return false;
}
replaces: 'LoginFooter',
},
render: function() {
var text = TextForEvent.textForEvent(this.props.mxEvent);
if (text == null || text.length == 0) return null;
return (
<div className="mx_EventAsTextTile">
{TextForEvent.textForEvent(this.props.mxEvent)}
<div className="mx_Login_links">
<a href="https://medium.com/@Vector">blog</a>&nbsp;&nbsp;&middot;&nbsp;&nbsp;
<a href="https://twitter.com/@VectorCo">twitter</a>&nbsp;&nbsp;&middot;&nbsp;&nbsp;
<a href="https://github.com/vector-im/vector-web">github</a>&nbsp;&nbsp;&middot;&nbsp;&nbsp;
<a href="https://matrix.org">powered by Matrix</a>
</div>
);
},
}
});

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -19,16 +19,16 @@ limitations under the License.
var React = require('react');
module.exports = React.createClass({
displayName: 'ViewSource',
displayName: 'VectorLoginHeader',
statics: {
replaces: 'LoginHeader',
},
render: function() {
return (
<div className="mx_ViewSource">
<pre>
{JSON.stringify(this.props.mxEvent.event, null, 2)}
</pre>
<div className="mx_Login_logo">
<img src="img/logo.png" width="249" height="78" alt="vector"/>
</div>
);
}
});

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -17,16 +17,18 @@ limitations under the License.
'use strict';
var React = require('react');
var DateUtils = require('matrix-react-sdk/lib/DateUtils');
module.exports = React.createClass({
displayName: 'UnknownMessageTile',
displayName: 'MessageTimestamp',
render: function() {
var content = this.props.mxEvent.getContent();
var date = new Date(this.props.ts);
return (
<span className="mx_UnknownMessageTile">
{content.body}
<span className="mx_MessageTimestamp">
{ DateUtils.formatDate(date) }
</span>
);
},
});

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -17,31 +17,26 @@ limitations under the License.
'use strict';
var React = require('react');
var classNames = require("classnames");
// The Lato WOFF doesn't include sensible combining diacritics, so Chrome chokes on rendering them.
// Revert to Arial when this happens, which on OSX works at least.
var zalgo = /[\u0300-\u036f\u1ab0-\u1aff\u1dc0-\u1dff\u20d0-\u20ff\ufe20-\ufe2f]/;
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 classes = classNames({
mx_SenderProfile: true,
// taken from https://en.wikipedia.org/wiki/Combining_character
mx_SenderProfile_zalgo: zalgo.test(name),
});
var msgtype = mxEvent.getContent().msgtype;
if (msgtype && msgtype == 'm.emote') {
name = ''; // emote message must include the name so don't duplicate it
return <span/>; // emote message must include the name so don't duplicate it
}
return (
<span className={classes}>
<span className="mx_SenderProfile" onClick={this.props.onClick}>
{name} { this.props.aux }
</span>
);

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -41,14 +41,14 @@ module.exports = React.createClass({
label = <div className="mx_RoomTile_name">{ this.props.label }</div>;
}
else if (this.state.hover) {
var RoomTooltip = sdk.getComponent("molecules.RoomTooltip");
var RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
label = <RoomTooltip bottom={ true } label={ this.props.label }/>;
}
return (
<div className="mx_RoomTile" onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} onClick={this.props.onClick}>
<div className="mx_RoomTile_avatar">
<img src={ this.props.img } width="36" height="36"/>
<img src={ this.props.img } width="26" height="26"/>
</div>
{ label }
</div>

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -22,30 +22,29 @@ var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var dis = require('matrix-react-sdk/lib/dispatcher');
var sdk = require('matrix-react-sdk')
var Modal = require('matrix-react-sdk/lib/Modal');
var Resend = require("matrix-react-sdk/lib/Resend");
module.exports = React.createClass({
displayName: 'MessageContextMenu',
propTypes: {
/* the MatrixEvent associated with the context menu */
mxEvent: React.PropTypes.object.isRequired,
/* an optional EventTileOps implementation that can be used to unhide preview widgets */
eventTileOps: React.PropTypes.object,
/* callback called when the menu is dismissed */
onFinished: React.PropTypes.func,
},
onResendClick: function() {
MatrixClientPeg.get().resendEvent(
this.props.mxEvent, MatrixClientPeg.get().getRoom(
this.props.mxEvent.getRoomId()
)
).done(function() {
dis.dispatch({
action: 'message_sent'
});
}, function() {
dis.dispatch({
action: 'message_send_failed'
});
});
dis.dispatch({action: 'message_resend_started'});
Resend.resend(this.props.mxEvent);
if (this.props.onFinished) this.props.onFinished();
},
onViewSourceClick: function() {
var ViewSource = sdk.getComponent('organisms.ViewSource');
var ViewSource = sdk.getComponent('structures.ViewSource');
Modal.createDialog(ViewSource, {
mxEvent: this.props.mxEvent
});
@@ -58,7 +57,7 @@ module.exports = React.createClass({
).done(function() {
// message should disappear by itself
}, function(e) {
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
// display error message stating you couldn't delete this.
var code = e.errcode || e.statusCode;
Modal.createDialog(ErrorDialog, {
@@ -69,36 +68,88 @@ module.exports = React.createClass({
if (this.props.onFinished) this.props.onFinished();
},
onCancelSendClick: function() {
Resend.removeFromQueue(this.props.mxEvent);
if (this.props.onFinished) this.props.onFinished();
},
onPermalinkClick: function() {
if (this.props.onFinished) this.props.onFinished();
},
onUnhidePreviewClick: function() {
if (this.props.eventTileOps) {
this.props.eventTileOps.unhideWidget();
}
if (this.props.onFinished) this.props.onFinished();
},
render: function() {
var eventStatus = this.props.mxEvent.status;
var resendButton;
var viewSourceButton;
var redactButton;
var cancelButton;
var permalinkButton;
var unhidePreviewButton;
if (this.props.mxEvent.status == 'not_sent') {
if (eventStatus === 'not_sent') {
resendButton = (
<div className="mx_ContextualMenu_field" onClick={this.onResendClick}>
Resend
</div>
);
}
else {
if (!eventStatus) { // sent
redactButton = (
<div className="mx_ContextualMenu_field" onClick={this.onRedactClick}>
Delete
Redact
</div>
);
}
if (eventStatus === "queued" || eventStatus === "not_sent") {
cancelButton = (
<div className="mx_ContextualMenu_field" onClick={this.onCancelSendClick}>
Cancel Sending
</div>
);
}
viewSourceButton = (
<div className="mx_ContextualMenu_field" onClick={this.onViewSourceClick}>
View Source
</div>
);
if (this.props.eventTileOps) {
if (this.props.eventTileOps.isWidgetHidden()) {
unhidePreviewButton = (
<div className="mx_ContextualMenu_field" onClick={this.onUnhidePreviewClick}>
Unhide Preview
</div>
)
}
}
// 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">
<a href={ "#/room/" + this.props.mxEvent.getRoomId() +"/"+ this.props.mxEvent.getId() }
onClick={ this.onPermalinkClick }>Permalink</a>
</div>
);
return (
<div>
{resendButton}
{redactButton}
{cancelButton}
{viewSourceButton}
{unhidePreviewButton}
{permalinkButton}
</div>
);
}

View File

@@ -0,0 +1,205 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require('react');
var DragSource = require('react-dnd').DragSource;
var DropTarget = require('react-dnd').DropTarget;
var dis = require("matrix-react-sdk/lib/dispatcher");
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var sdk = require('matrix-react-sdk');
var RoomTile = require('matrix-react-sdk/lib/components/views/rooms/RoomTile');
/**
* Specifies the drag source contract.
* Only `beginDrag` function is required.
*/
var roomTileSource = {
canDrag: function(props, monitor) {
return props.roomSubList.props.editable;
},
beginDrag: function (props) {
// Return the data describing the dragged item
var item = {
room: props.room,
originalList: props.roomSubList,
originalIndex: props.roomSubList.findRoomTile(props.room).index,
targetList: props.roomSubList, // at first target is same as original
// lastTargetRoom: null,
// lastYOffset: null,
// lastYDelta: null,
};
if (props.roomSubList.debug) console.log("roomTile beginDrag for " + item.room.roomId);
// doing this 'correctly' with state causes react-dnd to break seemingly due to the state transitions
props.room._dragging = true;
return item;
},
endDrag: function (props, monitor, component) {
var item = monitor.getItem();
if (props.roomSubList.debug) console.log("roomTile endDrag for " + item.room.roomId + " with didDrop=" + monitor.didDrop());
props.room._dragging = false;
if (monitor.didDrop()) {
if (props.roomSubList.debug) console.log("force updating component " + item.targetList.props.label);
item.targetList.forceUpdate(); // as we're not using state
}
if (monitor.didDrop() && item.targetList.props.editable) {
// if we moved lists, remove the old tag
if (item.targetList !== item.originalList && item.originalList.props.tagName) {
// commented out attempts to set a spinner on our target component as component is actually
// the original source component being dragged, not our target. To fix we just need to
// move all of this to endDrop in the target instead. FIXME later.
//component.state.set({ spinner: component.state.spinner ? component.state.spinner++ : 1 });
MatrixClientPeg.get().deleteRoomTag(item.room.roomId, item.originalList.props.tagName).finally(function() {
//component.state.set({ spinner: component.state.spinner-- });
}).fail(function(err) {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to remove tag " + item.originalList.props.tagName + " from room",
description: err.toString()
});
});
}
var newOrder= {};
if (item.targetList.props.order === 'manual') {
newOrder['order'] = item.targetList.calcManualOrderTagData(item.room);
}
// if we moved lists or the ordering changed, add the new tag
if (item.targetList.props.tagName && (item.targetList !== item.originalList || newOrder)) {
//component.state.set({ spinner: component.state.spinner ? component.state.spinner++ : 1 });
MatrixClientPeg.get().setRoomTag(item.room.roomId, item.targetList.props.tagName, newOrder).finally(function() {
//component.state.set({ spinner: component.state.spinner-- });
}).fail(function(err) {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to add tag " + item.targetList.props.tagName + " to room",
description: err.toString()
});
});
}
}
else {
// cancel the drop and reset our original position
if (props.roomSubList.debug) console.log("cancelling drop & drag");
props.roomSubList.moveRoomTile(item.room, item.originalIndex);
if (item.targetList && item.targetList !== item.originalList) {
item.targetList.removeRoomTile(item.room);
}
}
}
};
var roomTileTarget = {
canDrop: function() {
return false;
},
hover: function(props, monitor) {
var item = monitor.getItem();
//var off = monitor.getClientOffset();
// console.log("hovering on room " + props.room.roomId + ", isOver=" + monitor.isOver());
//console.log("item.targetList=" + item.targetList + ", roomSubList=" + props.roomSubList);
var switchedTarget = false;
if (item.targetList !== props.roomSubList) {
// we've switched target, so remove the tile from the previous target.
// n.b. the previous target might actually be the source list.
if (props.roomSubList.debug) console.log("switched target sublist");
switchedTarget = true;
item.targetList.removeRoomTile(item.room);
item.targetList = props.roomSubList;
}
if (!item.targetList.props.editable) return;
if (item.targetList.props.order === 'manual') {
if (item.room.roomId !== props.room.roomId && props.room !== item.lastTargetRoom) {
// find the offset of the target tile in the list.
var roomTile = props.roomSubList.findRoomTile(props.room);
// shuffle the list to add our tile to that position.
props.roomSubList.moveRoomTile(item.room, roomTile.index);
}
// stop us from flickering between our droptarget and the previous room.
// whenever the cursor changes direction we have to reset the flicker-damping.
/*
var yDelta = off.y - item.lastYOffset;
if ((yDelta > 0 && item.lastYDelta < 0) ||
(yDelta < 0 && item.lastYDelta > 0))
{
// the cursor changed direction - forget our previous room
item.lastTargetRoom = null;
}
else {
// track the last room we were hovering over so we can stop
// bouncing back and forth if the droptarget is narrower than
// the other list items. The other way to do this would be
// to reduce the size of the hittarget on the list items, but
// can't see an easy way to do that.
item.lastTargetRoom = props.room;
}
if (yDelta) item.lastYDelta = yDelta;
item.lastYOffset = off.y;
*/
}
else if (switchedTarget) {
if (!props.roomSubList.findRoomTile(item.room).room) {
// add to the list in the right place
props.roomSubList.moveRoomTile(item.room, 0);
}
// we have to sort the list whatever to recalculate it
props.roomSubList.sortList();
}
},
};
// Export the wrapped version, inlining the 'collect' functions
// to more closely resemble the ES7
module.exports =
DropTarget('RoomTile', roomTileTarget, function(connect, monitor) {
return {
// Call this function inside render()
// to let React DnD handle the drag events:
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver(),
}
})(
DragSource('RoomTile', roomTileSource, function(connect, monitor) {
return {
// Call this function inside render()
// to let React DnD handle the drag events:
connectDragSource: connect.dragSource(),
// You can ask the monitor about the current drag state:
isDragging: monitor.isDragging()
};
})(RoomTile));
module.exports.replaces = 'RoomTile';

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,20 +18,24 @@ limitations under the License.
var React = require('react');
var EnableNotificationsButtonController = require('matrix-react-sdk/lib/controllers/atoms/EnableNotificationsButton')
module.exports = React.createClass({
displayName: 'EnableNotificationsButton',
mixins: [EnableNotificationsButtonController],
displayName: 'RoomDropTarget',
render: function() {
if (this.enabled()) {
if (this.props.placeholder) {
return (
<button className="mx_EnableNotificationsButton" onClick={this.onClick}>Disable Notifications</button>
<div className="mx_RoomDropTarget mx_RoomDropTarget_placeholder">
</div>
);
} else {
}
else {
return (
<button className="mx_EnableNotificationsButton" onClick={this.onClick}>Enable Notifications</button>
<div className="mx_RoomDropTarget">
<div className="mx_RoomDropTarget_avatar"></div>
<div className="mx_RoomDropTarget_label">
{ this.props.label }
</div>
</div>
);
}
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ limitations under the License.
'use strict';
var React = require('react');
var ReactDOM = require('react-dom');
var dis = require('matrix-react-sdk/lib/dispatcher');
@@ -24,21 +25,21 @@ module.exports = React.createClass({
displayName: 'RoomTooltip',
componentDidMount: function() {
var tooltip = ReactDOM.findDOMNode(this);
if (!this.props.bottom) {
// tell the roomlist about us so it can position us
dis.dispatch({
action: 'view_tooltip',
tooltip: this.getDOMNode(),
tooltip: tooltip,
});
}
else {
var tooltip = this.getDOMNode();
tooltip.style.top = tooltip.parentElement.getBoundingClientRect().top + "px";
tooltip.style.top = (70 + tooltip.parentElement.getBoundingClientRect().top) + "px";
tooltip.style.display = "block";
}
},
componentDidUnmount: function() {
componentWillUnmount: function() {
if (!this.props.bottom) {
dis.dispatch({
action: 'view_tooltip',

View File

@@ -0,0 +1,69 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require('react');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var sdk = require('matrix-react-sdk');
var classNames = require('classnames');
module.exports = React.createClass({
displayName: 'SearchBar',
getInitialState: function() {
return ({
scope: 'Room'
});
},
onThisRoomClick: function() {
this.setState({ scope: 'Room' });
},
onAllRoomsClick: function() {
this.setState({ scope: 'All' });
},
onSearchChange: function(e) {
if (e.keyCode === 13) { // on enter...
this.onSearch();
}
if (e.keyCode === 27) { // escape...
this.props.onCancelClick();
}
},
onSearch: function() {
this.props.onSearch(this.refs.search_term.value, this.state.scope);
},
render: function() {
var searchButtonClasses = classNames({ mx_SearchBar_searchButton : true, mx_SearchBar_searching: this.props.searchInProgress });
var thisRoomClasses = classNames({ mx_SearchBar_button : true, mx_SearchBar_unselected : this.state.scope !== 'Room' });
var allRoomsClasses = classNames({ mx_SearchBar_button : true, mx_SearchBar_unselected : this.state.scope !== 'All' });
return (
<div className="mx_SearchBar">
<input ref="search_term" className="mx_SearchBar_input" type="text" autoFocus={true} placeholder="Search..." onKeyDown={this.onSearchChange}/>
<div className={ searchButtonClasses } onClick={this.onSearch}><img src="img/search-button.svg" width="37" height="37" alt="Search"/></div>
<div className={ thisRoomClasses } onClick={this.onThisRoomClick}>This Room</div>
<div className={ allRoomsClasses } onClick={this.onAllRoomsClick}>All Rooms</div>
<img className="mx_SearchBar_cancel" src="img/cancel.svg" width="18" height="18" onClick={this.props.onCancelClick} />
</div>
);
}
});

View File

@@ -0,0 +1,867 @@
/*
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.
*/
'use strict';
var React = require('react');
var q = require("q");
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,
// which should be factored out to other files.
// TODO: this component also does a lot of direct poking into this.state, which
// is VERY NAUGHTY.
var NotificationUtils = notifications.NotificationUtils;
var VectorPushRulesDefinitions = notifications.VectorPushRulesDefinitions;
var PushRuleVectorState = notifications.PushRuleVectorState;
var ContentRules = notifications.ContentRules;
/**
* Rules that Vector used to set in order to override the actions of default rules.
* These are used to port peoples existing overrides to match the current API.
* These can be removed and forgotten once everyone has moved to the new client.
*/
var LEGACY_RULES = {
"im.vector.rule.contains_display_name": ".m.rule.contains_display_name",
"im.vector.rule.room_one_to_one": ".m.rule.room_one_to_one",
"im.vector.rule.room_message": ".m.rule.message",
"im.vector.rule.invite_for_me": ".m.rule.invite_for_me",
"im.vector.rule.call": ".m.rule.call",
"im.vector.rule.notices": ".m.rule.suppress_notices"
};
function portLegacyActions(actions) {
var decoded = NotificationUtils.decodeActions(actions);
if (decoded !== null) {
return NotificationUtils.encodeActions(decoded);
} else {
// We don't recognise one of the actions here, so we don't try to
// canonicalise them.
return actions;
}
}
module.exports = React.createClass({
displayName: 'Notififications',
phases: {
LOADING: "LOADING", // The component is loading or sending data to the hs
DISPLAY: "DISPLAY", // The component is ready and display data
ERROR: "ERROR" // There was an error
},
propTypes: {
// The array of threepids from the JS SDK (required for email notifications)
threepids: React.PropTypes.array.isRequired,
},
getDefaultProps: function() {
return {
threepids: []
};
},
getInitialState: function() {
return {
phase: this.phases.LOADING,
masterPushRule: undefined, // The master rule ('.m.rule.master')
vectorPushRules: [], // HS default push rules displayed in Vector UI
vectorContentRules: { // Keyword push rules displayed in Vector UI
vectorState: PushRuleVectorState.ON,
rules: []
},
externalPushRules: [], // Push rules (except content rule) that have been defined outside Vector UI
externalContentRules: [] // Keyword push rules that have been defined outside Vector UI
};
},
componentWillMount: function() {
this._refreshFromServer();
},
onEnableNotificationsChange: function(event) {
var self = this;
this.setState({
phase: this.phases.LOADING
});
MatrixClientPeg.get().setPushRuleEnabled('global', self.state.masterPushRule.kind, self.state.masterPushRule.rule_id, !event.target.checked).done(function() {
self._refreshFromServer();
});
},
onEnableDesktopNotificationsChange: function(event) {
UserSettingsStore.setEnableNotifications(event.target.checked);
},
onEnableEmailNotificationsChange: function(address, event) {
var emailPusherPromise;
if (event.target.checked) {
var data = {}
if (configJson.brand) {
data['brand'] = configJson.brand;
}
emailPusherPromise = UserSettingsStore.addEmailPusher(address, data);
} else {
var emailPusher = UserSettingsStore.getEmailPusher(this.state.pushers, address);
emailPusher.kind = null;
emailPusherPromise = MatrixClientPeg.get().setPusher(emailPusher);
}
emailPusherPromise.done(() => {
this._refreshFromServer();
}, (error) => {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Error saving email notification preferences",
description: "Vector was unable to save your email notification preferences.",
});
});
},
onNotifStateButtonClicked: function(event) {
// FIXME: use .bind() rather than className metadata here surely
var vectorRuleId = event.target.className.split("-")[0];
var newPushRuleVectorState = event.target.className.split("-")[1];
if ("_keywords" === vectorRuleId) {
this._setKeywordsPushRuleVectorState(newPushRuleVectorState)
}
else {
var rule = this.getRule(vectorRuleId);
if (rule) {
this._setPushRuleVectorState(rule, newPushRuleVectorState);
}
}
},
onKeywordsClicked: function(event) {
var self = this;
// Compute the keywords list to display
var keywords = [];
for (var i in this.state.vectorContentRules.rules) {
var rule = this.state.vectorContentRules.rules[i];
keywords.push(rule.pattern);
}
if (keywords.length) {
// As keeping the order of per-word push rules hs side is a bit tricky to code,
// display the keywords in alphabetical order to the user
keywords.sort();
keywords = keywords.join(", ");
}
else {
keywords = "";
}
var TextInputDialog = sdk.getComponent("dialogs.TextInputDialog");
Modal.createDialog(TextInputDialog, {
title: "Keywords",
description: "Enter keywords separated by a comma:",
value: keywords,
onFinished: function onFinished(should_leave, newValue) {
if (should_leave && newValue !== keywords) {
var newKeywords = newValue.split(',');
for (var i in newKeywords) {
newKeywords[i] = newKeywords[i].trim();
}
// Remove duplicates and empty
newKeywords = newKeywords.reduce(function(array, keyword){
if (keyword !== "" && array.indexOf(keyword) < 0) {
array.push(keyword);
}
return array;
},[]);
self._setKeywords(newKeywords);
}
}
});
},
getRule: function(vectorRuleId) {
for (var i in this.state.vectorPushRules) {
var rule = this.state.vectorPushRules[i];
if (rule.vectorRuleId === vectorRuleId) {
return rule;
}
}
},
_setPushRuleVectorState: function(rule, newPushRuleVectorState) {
if (rule && rule.vectorState !== newPushRuleVectorState) {
this.setState({
phase: this.phases.LOADING
});
var self = this;
var cli = MatrixClientPeg.get();
var deferreds = [];
var ruleDefinition = VectorPushRulesDefinitions[rule.vectorRuleId];
if (rule.rule) {
var actions = ruleDefinition.vectorStateToActions[newPushRuleVectorState];
if (!actions) {
// The new state corresponds to disabling the rule.
deferreds.push(cli.setPushRuleEnabled('global', rule.rule.kind, rule.rule.rule_id, false));
}
else {
// The new state corresponds to enabling the rule and setting specific actions
deferreds.push(this._updatePushRuleActions(rule.rule, actions, true));
}
}
q.all(deferreds).done(function() {
self._refreshFromServer();
}, function(error) {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Can't change settings",
description: error.toString(),
onFinished: self._refreshFromServer
});
});
}
},
_setKeywordsPushRuleVectorState: function(newPushRuleVectorState) {
// Is there really a change?
if (this.state.vectorContentRules.vectorState === newPushRuleVectorState
|| this.state.vectorContentRules.rules.length === 0) {
return;
}
var self = this;
var cli = MatrixClientPeg.get();
this.setState({
phase: this.phases.LOADING
});
// Update all rules in self.state.vectorContentRules
var deferreds = [];
for (var i in this.state.vectorContentRules.rules) {
var rule = this.state.vectorContentRules.rules[i];
var enabled, actions;
switch (newPushRuleVectorState) {
case PushRuleVectorState.ON:
if (rule.actions.length !== 1) {
actions = PushRuleVectorState.actionsFor(PushRuleVectorState.ON);
}
if (this.state.vectorContentRules.vectorState === PushRuleVectorState.OFF) {
enabled = true;
}
break;
case PushRuleVectorState.LOUD:
if (rule.actions.length !== 3) {
actions = PushRuleVectorState.actionsFor(PushRuleVectorState.LOUD);
}
if (this.state.vectorContentRules.vectorState === PushRuleVectorState.OFF) {
enabled = true;
}
break;
case PushRuleVectorState.OFF:
enabled = false;
break;
}
if (actions) {
// Note that the workaround in _updatePushRuleActions will automatically
// enable the rule
deferreds.push(this._updatePushRuleActions(rule, actions, enabled));
}
else if (enabled != undefined) {
deferreds.push(cli.setPushRuleEnabled('global', rule.kind, rule.rule_id, enabled));
}
}
q.all(deferreds).done(function(resps) {
self._refreshFromServer();
}, function(error) {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Can't update user notification settings",
description: error.toString(),
onFinished: self._refreshFromServer
});
});
},
_setKeywords: function(newKeywords) {
this.setState({
phase: this.phases.LOADING
});
var self = this;
var cli = MatrixClientPeg.get();
var removeDeferreds = [];
// Remove per-word push rules of keywords that are no more in the list
var vectorContentRulesPatterns = [];
for (var i in self.state.vectorContentRules.rules) {
var rule = self.state.vectorContentRules.rules[i];
vectorContentRulesPatterns.push(rule.pattern);
if (newKeywords.indexOf(rule.pattern) < 0) {
removeDeferreds.push(cli.deletePushRule('global', rule.kind, rule.rule_id));
}
}
// If the keyword is part of `externalContentRules`, remove the rule
// before recreating it in the right Vector path
for (var i in self.state.externalContentRules) {
var rule = self.state.externalContentRules[i];
if (newKeywords.indexOf(rule.pattern) >= 0) {
removeDeferreds.push(cli.deletePushRule('global', rule.kind, rule.rule_id));
}
}
var onError = function(error) {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Can't update keywords",
description: error.toString(),
onFinished: self._refreshFromServer
});
}
// Then, add the new ones
q.all(removeDeferreds).done(function(resps) {
var deferreds = [];
var pushRuleVectorStateKind = self.state.vectorContentRules.vectorState;
if (pushRuleVectorStateKind === PushRuleVectorState.OFF) {
// When the current global keywords rule is OFF, we need to look at
// the flavor of rules in 'vectorContentRules' to apply the same actions
// when creating the new rule.
// Thus, this new rule will join the 'vectorContentRules' set.
if (self.state.vectorContentRules.rules.length) {
pushRuleVectorStateKind = PushRuleVectorState.contentRuleVectorStateKind(self.state.vectorContentRules.rules[0]);
}
else {
// ON is default
pushRuleVectorStateKind = PushRuleVectorState.ON;
}
}
for (var i in newKeywords) {
var keyword = newKeywords[i];
if (vectorContentRulesPatterns.indexOf(keyword) < 0) {
if (self.state.vectorContentRules.vectorState !== PushRuleVectorState.OFF) {
deferreds.push(cli.addPushRule
('global', 'content', keyword, {
actions: PushRuleVectorState.actionsFor(pushRuleVectorStateKind),
pattern: keyword
}));
}
else {
deferreds.push(self._addDisabledPushRule('global', 'content', keyword, {
actions: PushRuleVectorState.actionsFor(pushRuleVectorStateKind),
pattern: keyword
}));
}
}
}
q.all(deferreds).done(function(resps) {
self._refreshFromServer();
}, onError);
}, onError);
},
// Create a push rule but disabled
_addDisabledPushRule: function(scope, kind, ruleId, body) {
var cli = MatrixClientPeg.get();
return cli.addPushRule(scope, kind, ruleId, body).then(function() {
return cli.setPushRuleEnabled(scope, kind, ruleId, false);
});
},
// Check if any legacy im.vector rules need to be ported to the new API
// for overriding the actions of default rules.
_portRulesToNewAPI: function(rulesets) {
var self = this;
var needsUpdate = [];
var cli = MatrixClientPeg.get();
for (var kind in rulesets.global) {
var ruleset = rulesets.global[kind];
for (var i = 0; i < ruleset.length; ++i) {
var rule = ruleset[i];
if (rule.rule_id in LEGACY_RULES) {
console.log("Porting legacy rule", rule);
needsUpdate.push( function(kind, rule) {
return cli.setPushRuleActions(
'global', kind, LEGACY_RULES[rule.rule_id], portLegacyActions(rule.actions)
).then( function() {
return cli.deletePushRule('global', kind, rule.rule_id);
})
}(kind, rule));
}
}
}
if (needsUpdate.length > 0) {
// If some of the rules need to be ported then wait for the porting
// to happen and then fetch the rules again.
return q.allSettled(needsUpdate).then( function() {
return cli.getPushRules();
});
} else {
// Otherwise return the rules that we already have.
return rulesets;
}
},
_refreshFromServer: function() {
var self = this;
var pushRulesPromise = MatrixClientPeg.get().getPushRules().then(self._portRulesToNewAPI).then(function(rulesets) {
//console.log("resolving pushRulesPromise");
/// XXX seriously? wtf is this?
MatrixClientPeg.get().pushRules = rulesets;
// Get homeserver default rules and triage them by categories
var rule_categories = {
// The master rule (all notifications disabling)
'.m.rule.master': 'master',
// The default push rules displayed by Vector UI
// XXX: .m.rule.contains_user_name is not managed (not a fancy rule for Vector?)
'.m.rule.contains_display_name': 'vector',
'.m.rule.room_one_to_one': 'vector',
'.m.rule.message': 'vector',
'.m.rule.invite_for_me': 'vector',
//'.m.rule.member_event': 'vector',
'.m.rule.call': 'vector',
'.m.rule.suppress_notices': 'vector'
// Others go to others
};
// HS default rules
var defaultRules = {master: [], vector: {}, others: []};
for (var kind in rulesets.global) {
for (var i = 0; i < Object.keys(rulesets.global[kind]).length; ++i) {
var r = rulesets.global[kind][i];
var cat = rule_categories[r.rule_id];
r.kind = kind;
if (r.rule_id[0] === '.') {
if (cat === 'vector') {
defaultRules.vector[r.rule_id] = r;
}
else if (cat === 'master') {
defaultRules.master.push(r);
}
else {
defaultRules['others'].push(r);
}
}
}
}
// Get the master rule if any defined by the hs
if (defaultRules.master.length > 0) {
self.state.masterPushRule = defaultRules.master[0];
}
// parse the keyword rules into our state
var contentRules = ContentRules.parseContentRules(rulesets);
self.state.vectorContentRules = {
vectorState: contentRules.vectorState,
rules: contentRules.rules,
};
self.state.externalContentRules = contentRules.externalRules;
// Build the rules displayed in the Vector UI matrix table
self.state.vectorPushRules = [];
self.state.externalPushRules = [];
var vectorRuleIds = [
'.m.rule.contains_display_name',
'_keywords',
'.m.rule.room_one_to_one',
'.m.rule.message',
'.m.rule.invite_for_me',
//'im.vector.rule.member_event',
'.m.rule.call',
'.m.rule.suppress_notices'
];
for (var i in vectorRuleIds) {
var vectorRuleId = vectorRuleIds[i];
if (vectorRuleId === '_keywords') {
// keywords needs a special handling
// For Vector UI, this is a single global push rule but translated in Matrix,
// it corresponds to all content push rules (stored in self.state.vectorContentRule)
self.state.vectorPushRules.push({
"vectorRuleId": "_keywords",
"description" : (<span>Messages containing <span className="mx_UserNotifSettings_keywords" onClick={ self.onKeywordsClicked }>keywords</span></span>),
"vectorState": self.state.vectorContentRules.vectorState
});
}
else {
var ruleDefinition = VectorPushRulesDefinitions[vectorRuleId];
var rule = defaultRules.vector[vectorRuleId];
var vectorState = ruleDefinition.ruleToVectorState(rule);
//console.log("Refreshing vectorPushRules for " + vectorRuleId +", "+ ruleDefinition.description +", " + rule +", " + vectorState);
self.state.vectorPushRules.push({
"vectorRuleId": vectorRuleId,
"description" : ruleDefinition.description,
"rule": rule,
"vectorState": vectorState,
});
// if there was a rule which we couldn't parse, add it to the external list
if (rule && !vectorState) {
rule.description = ruleDefinition.description;
self.state.externalPushRules.push(rule);
}
}
}
// Build the rules not managed by Vector UI
var otherRulesDescriptions = {
'.m.rule.message': "Notify for all other messages/rooms",
'.m.rule.fallback': "Notify me for anything else"
};
for (var i in defaultRules.others) {
var rule = defaultRules.others[i];
var ruleDescription = otherRulesDescriptions[rule.rule_id];
// Show enabled default rules that was modified by the user
if (ruleDescription && rule.enabled && !rule.default) {
rule.description = ruleDescription;
self.state.externalPushRules.push(rule);
}
}
});
var pushersPromise = MatrixClientPeg.get().getPushers().then(function(resp) {
//console.log("resolving pushersPromise");
self.setState({pushers: resp.pushers});
});
q.all([pushRulesPromise, pushersPromise]).then(function() {
self.setState({
phase: self.phases.DISPLAY
});
}, function(error) {
self.setState({
phase: self.phases.ERROR
});
}).finally(() => {
// actually explicitly update our state having been deep-manipulating it
self.setState({
masterPushRule: self.state.masterPushRule,
vectorContentRules: self.state.vectorContentRules,
vectorPushRules: self.state.vectorPushRules,
externalContentRules: self.state.externalContentRules,
externalPushRules: self.state.externalPushRules,
});
}).done();
},
_updatePushRuleActions: function(rule, actions, enabled) {
var cli = MatrixClientPeg.get();
return cli.setPushRuleActions(
'global', rule.kind, rule.rule_id, actions
).then( function() {
// Then, if requested, enabled or disabled the rule
if (undefined != enabled) {
return cli.setPushRuleEnabled(
'global', rule.kind, rule.rule_id, enabled
);
}
});
},
renderNotifRulesTableRow: function(title, className, pushRuleVectorState) {
return (
<tr key={ className }>
<th>
{title}
</th>
<th>
<input className= {className + "-" + PushRuleVectorState.OFF}
type="radio"
checked={ pushRuleVectorState === PushRuleVectorState.OFF }
onChange={ this.onNotifStateButtonClicked } />
</th>
<th>
<input className= {className + "-" + PushRuleVectorState.ON}
type="radio"
checked={ pushRuleVectorState === PushRuleVectorState.ON }
onChange={ this.onNotifStateButtonClicked } />
</th>
<th>
<input className= {className + "-" + PushRuleVectorState.LOUD}
type="radio"
checked={ pushRuleVectorState === PushRuleVectorState.LOUD }
onChange={ this.onNotifStateButtonClicked } />
</th>
</tr>
);
},
renderNotifRulesTableRows: function() {
var rows = [];
for (var i in this.state.vectorPushRules) {
var rule = this.state.vectorPushRules[i];
//console.log("rendering: " + rule.description + ", " + rule.vectorRuleId + ", " + rule.vectorState);
rows.push(this.renderNotifRulesTableRow(rule.description, rule.vectorRuleId, rule.vectorState));
}
return rows;
},
emailNotificationsRow: function(address, label) {
return (<div className="mx_UserNotifSettings_tableRow">
<div className="mx_UserNotifSettings_inputCell">
<input id="enableEmailNotifications_{address}"
ref="enableEmailNotifications_{address}"
type="checkbox"
checked={ UserSettingsStore.hasEmailPusher(this.state.pushers, address) }
onChange={ this.onEnableEmailNotificationsChange.bind(this, address) }
/>
</div>
<div className="mx_UserNotifSettings_labelCell">
<label htmlFor="enableEmailNotifications_{address}">
{label}
</label>
</div>
</div>);
},
render: function() {
var self = this;
var spinner;
if (this.state.phase === this.phases.LOADING) {
var Loader = sdk.getComponent("elements.Spinner");
spinner = <Loader />;
}
if (this.state.masterPushRule) {
var masterPushRuleDiv = (
<div className="mx_UserNotifSettings_tableRow">
<div className="mx_UserNotifSettings_inputCell">
<input id="enableNotifications"
ref="enableNotifications"
type="checkbox"
checked={ !this.state.masterPushRule.enabled }
onChange={ this.onEnableNotificationsChange } />
</div>
<div className="mx_UserNotifSettings_labelCell">
<label htmlFor="enableNotifications">
Enable notifications for this account
</label>
</div>
</div>
);
}
// When enabled, the master rule inhibits all existing rules
// So do not show all notification settings
if (this.state.masterPushRule && this.state.masterPushRule.enabled) {
return (
<div>
{masterPushRuleDiv}
<div className="mx_UserSettings_notifTable">
All notifications are currently disabled for all targets.
</div>
</div>
);
}
var emailNotificationsRow;
if (this.props.threepids.filter(function(tp) {
if (tp.medium == "email") {
return true;
}
}).length == 0) {
emailNotificationsRow = <div>
Add an email address above to configure email notifications
</div>;
} else {
// This only supports the first email address in your profile for now
emailNotificationsRow = this.emailNotificationsRow(
this.props.threepids[0].address,
"Enable email notifications ("+this.props.threepids[0].address+")"
);
}
// Build external push rules
var externalRules = [];
for (var i in this.state.externalPushRules) {
var rule = this.state.externalPushRules[i];
externalRules.push(<li>{ rule.description }</li>);
}
// Show keywords not displayed by the vector UI as a single external push rule
var externalKeyWords = [];
for (var i in this.state.externalContentRules) {
var rule = this.state.externalContentRules[i];
externalKeyWords.push(rule.pattern);
}
if (externalKeyWords.length) {
externalKeyWords = externalKeyWords.join(", ");
externalRules.push(<li>Notifications on the following keywords follow rules which cant be displayed here: { externalKeyWords }</li>);
}
var devicesSection;
if (this.state.pushers === undefined) {
devicesSection = <div className="error">Unable to fetch notification target list</div>
} else if (this.state.pushers.length == 0) {
devicesSection = null;
} else {
// TODO: It would be great to be able to delete pushers from here too,
// and this wouldn't be hard to add.
var rows = [];
for (var i = 0; i < this.state.pushers.length; ++i) {
rows.push(<tr key={ i }>
<td>{this.state.pushers[i].app_display_name}</td>
<td>{this.state.pushers[i].device_display_name}</td>
</tr>);
}
devicesSection = (<table className="mx_UserSettings_devicesTable">
<tbody>
{rows}
</tbody>
</table>);
}
if (devicesSection) {
devicesSection = (<div>
<h3>Notification targets</h3>
{ devicesSection }
</div>);
}
var advancedSettings;
if (externalRules.length) {
advancedSettings = (
<div>
<h3>Advanced notifications settings</h3>
There are advanced notifications which are not shown here.<br/>
You might have configured them in another client than Vector. You cannot tune them in Vector but they still apply.
<ul>
{ externalRules }
</ul>
</div>
);
}
return (
<div>
{masterPushRuleDiv}
<div className="mx_UserSettings_notifTable">
{ spinner }
<div className="mx_UserNotifSettings_tableRow">
<div className="mx_UserNotifSettings_inputCell">
<input id="enableDesktopNotifications"
ref="enableDesktopNotifications"
type="checkbox"
checked={ UserSettingsStore.getEnableNotifications() }
onChange={ this.onEnableDesktopNotificationsChange } />
</div>
<div className="mx_UserNotifSettings_labelCell">
<label htmlFor="enableDesktopNotifications">
Enable desktop notifications
</label>
</div>
</div>
<div className="mx_UserNotifSettings_tableRow">
<div className="mx_UserNotifSettings_inputCell">
<input id="enableDesktopAudioNotifications"
ref="enableDesktopAudioNotifications"
type="checkbox"
checked={ UserSettingsStore.getEnableAudioNotifications() }
onChange={ (e) => {
UserSettingsStore.setEnableAudioNotifications(e.target.checked);
this.forceUpdate();
}} />
</div>
<div className="mx_UserNotifSettings_labelCell">
<label htmlFor="enableDesktopAudioNotifications">
Enable audible notifications in web client
</label>
</div>
</div>
{ emailNotificationsRow }
<div className="mx_UserNotifSettings_pushRulesTableWrapper">
<table className="mx_UserNotifSettings_pushRulesTable">
<thead>
<tr>
<th width="55%"></th>
<th width="15%">Off</th>
<th width="15%">On</th>
<th width="15%">Highlight<br/>&amp; sound</th>
</tr>
</thead>
<tbody>
{ this.renderNotifRulesTableRows() }
</tbody>
</table>
</div>
{ advancedSettings }
{ devicesSection }
</div>
</div>
);
}
});

View File

@@ -1,97 +0,0 @@
/*
Copyright 2015 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var dis = require("matrix-react-sdk/lib/dispatcher");
var CallHandler = require("matrix-react-sdk/lib/CallHandler");
var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
var VectorConferenceHandler = require('../../../modules/VectorConferenceHandler');
/*
* State vars:
* this.state.call = MatrixCall|null
*
* Props:
* this.props.room = Room (JS SDK)
*
* Internal state:
* this._trackedRoom = (either from props.room or programatically set)
*/
module.exports = {
componentDidMount: function() {
this.dispatcherRef = dis.register(this.onAction);
this._trackedRoom = null;
if (this.props.room) {
this._trackedRoom = this.props.room;
this.showCall(this._trackedRoom.roomId);
}
else {
var call = CallHandler.getAnyActiveCall();
if (call) {
console.log(
"Global CallView is now tracking active call in room %s",
call.roomId
);
this._trackedRoom = MatrixClientPeg.get().getRoom(call.roomId);
this.showCall(call.roomId);
}
}
},
componentWillUnmount: function() {
dis.unregister(this.dispatcherRef);
},
onAction: function(payload) {
// don't filter out payloads for room IDs other than props.room because
// we may be interested in the conf 1:1 room
if (payload.action !== 'call_state' || !payload.room_id) {
return;
}
this.showCall(payload.room_id);
},
showCall: function(roomId) {
var call = (
CallHandler.getCallForRoom(roomId) ||
VectorConferenceHandler.getConferenceCallForRoom(roomId)
);
if (call) {
call.setLocalVideoElement(this.getVideoView().getLocalVideoElement());
call.setRemoteVideoElement(this.getVideoView().getRemoteVideoElement());
// give a separate element for audio stream playback - both for voice calls
// and for the voice stream of screen captures
call.setRemoteAudioElement(this.getVideoView().getRemoteAudioElement());
}
if (call && call.type === "video" && call.state !== 'ended') {
// if this call is a conf call, don't display local video as the
// conference will have us in it
this.getVideoView().getLocalVideoElement().style.display = (
call.confUserId ? "none" : "initial"
);
this.getVideoView().getRemoteVideoElement().style.display = "initial";
}
else {
this.getVideoView().getLocalVideoElement().style.display = "none";
this.getVideoView().getRemoteVideoElement().style.display = "none";
dis.dispatch({action: 'video_fullscreen', fullscreen: false});
}
}
};

View File

@@ -1,194 +0,0 @@
/*
Copyright 2015 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require("react");
var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
var RoomListSorter = require("matrix-react-sdk/lib/RoomListSorter");
var dis = require("matrix-react-sdk/lib/dispatcher");
var sdk = require('matrix-react-sdk');
var VectorConferenceHandler = require("../../modules/VectorConferenceHandler");
var CallHandler = require("matrix-react-sdk/lib/CallHandler");
var HIDE_CONFERENCE_CHANS = true;
module.exports = {
componentWillMount: function() {
var cli = MatrixClientPeg.get();
cli.on("Room", this.onRoom);
cli.on("Room.timeline", this.onRoomTimeline);
cli.on("Room.name", this.onRoomName);
cli.on("RoomState.events", this.onRoomStateEvents);
cli.on("RoomMember.name", this.onRoomMemberName);
var rooms = this.getRoomList();
this.setState({
roomList: rooms,
activityMap: {}
});
},
componentDidMount: function() {
this.dispatcherRef = dis.register(this.onAction);
},
onAction: function(payload) {
switch (payload.action) {
// listen for call state changes to prod the render method, which
// may hide the global CallView if the call it is tracking is dead
case 'call_state':
this._recheckCallElement(this.props.selectedRoom);
break;
case 'view_tooltip':
this.tooltip = payload.tooltip;
this._repositionTooltip();
if (this.tooltip) this.tooltip.style.display = 'block';
break
}
},
componentWillUnmount: function() {
dis.unregister(this.dispatcherRef);
if (MatrixClientPeg.get()) {
MatrixClientPeg.get().removeListener("Room", this.onRoom);
MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
MatrixClientPeg.get().removeListener("Room.name", this.onRoomName);
MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents);
}
},
componentWillReceiveProps: function(newProps) {
this.state.activityMap[newProps.selectedRoom] = undefined;
this._recheckCallElement(newProps.selectedRoom);
this.setState({
activityMap: this.state.activityMap
});
},
onRoom: function(room) {
this.refreshRoomList();
},
onRoomTimeline: function(ev, room, toStartOfTimeline) {
if (toStartOfTimeline) return;
var newState = {
roomList: this.getRoomList()
};
if (
room.roomId != this.props.selectedRoom &&
ev.getSender() != MatrixClientPeg.get().credentials.userId)
{
var hl = 1;
var actions = MatrixClientPeg.get().getPushActionsForEvent(ev);
if (actions && actions.tweaks && actions.tweaks.highlight) {
hl = 2;
}
// obviously this won't deep copy but this shouldn't be necessary
var amap = this.state.activityMap;
amap[room.roomId] = Math.max(amap[room.roomId] || 0, hl);
newState.activityMap = amap;
}
this.setState(newState);
},
onRoomName: function(room) {
this.refreshRoomList();
},
onRoomStateEvents: function(ev, state) {
setTimeout(this.refreshRoomList, 0);
},
onRoomMemberName: function(ev, member) {
setTimeout(this.refreshRoomList, 0);
},
refreshRoomList: function() {
var rooms = this.getRoomList();
this.setState({
roomList: rooms
});
},
getRoomList: function() {
return RoomListSorter.mostRecentActivityFirst(
MatrixClientPeg.get().getRooms().filter(function(room) {
var me = room.getMember(MatrixClientPeg.get().credentials.userId);
var shouldShowRoom = (
me && (me.membership == "join" || me.membership == "invite")
);
// hiding conf rooms only ever toggles shouldShowRoom to false
if (shouldShowRoom && HIDE_CONFERENCE_CHANS) {
// we want to hide the 1:1 conf<->user room and not the group chat
var joinedMembers = room.getJoinedMembers();
if (joinedMembers.length === 2) {
var otherMember = joinedMembers.filter(function(m) {
return m.userId !== me.userId
})[0];
if (VectorConferenceHandler.isConferenceUser(otherMember)) {
// console.log("Hiding conference 1:1 room %s", room.roomId);
shouldShowRoom = false;
}
}
}
return shouldShowRoom;
})
);
},
_recheckCallElement: function(selectedRoomId) {
// if we aren't viewing a room with an ongoing call, but there is an
// active call, show the call element - we need to do this to make
// audio/video not crap out
var activeCall = CallHandler.getAnyActiveCall();
var callForRoom = CallHandler.getCallForRoom(selectedRoomId);
var showCall = (activeCall && !callForRoom);
this.setState({
show_call_element: showCall
});
},
_repositionTooltip: function(e) {
if (this.tooltip && this.tooltip.parentElement) {
var scroll = this.getDOMNode();
this.tooltip.style.top = (scroll.parentElement.offsetTop + this.tooltip.parentElement.offsetTop - scroll.scrollTop) + "px";
}
},
makeRoomTiles: function() {
var self = this;
var RoomTile = sdk.getComponent("molecules.RoomTile");
return this.state.roomList.map(function(room) {
var selected = room.roomId == self.props.selectedRoom;
return (
<RoomTile
room={room}
key={room.roomId}
collapsed={self.props.collapsed}
selected={selected}
unread={self.state.activityMap[room.roomId] === 1}
highlight={self.state.activityMap[room.roomId] === 2}
/>
);
});
}
};

View File

@@ -1,503 +0,0 @@
/*
Copyright 2015 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
var React = require("react");
var q = require("q");
var ContentMessages = require("matrix-react-sdk/lib//ContentMessages");
var WhoIsTyping = require("matrix-react-sdk/lib/WhoIsTyping");
var Modal = require("matrix-react-sdk/lib/Modal");
var sdk = require('matrix-react-sdk/lib/index');
var CallHandler = require('matrix-react-sdk/lib/CallHandler');
var VectorConferenceHandler = require('../../modules/VectorConferenceHandler');
var dis = require("matrix-react-sdk/lib/dispatcher");
var PAGINATE_SIZE = 20;
var INITIAL_SIZE = 20;
module.exports = {
getInitialState: function() {
return {
room: this.props.roomId ? MatrixClientPeg.get().getRoom(this.props.roomId) : null,
messageCap: INITIAL_SIZE,
editingRoomSettings: false,
uploadingRoomSettings: false,
numUnreadMessages: 0,
draggingFile: false,
}
},
componentWillMount: function() {
this.dispatcherRef = dis.register(this.onAction);
MatrixClientPeg.get().on("Room.timeline", this.onRoomTimeline);
MatrixClientPeg.get().on("Room.name", this.onRoomName);
MatrixClientPeg.get().on("RoomMember.typing", this.onRoomMemberTyping);
MatrixClientPeg.get().on("RoomState.members", this.onRoomStateMember);
this.atBottom = true;
},
componentWillUnmount: function() {
if (this.refs.messageWrapper) {
var messageWrapper = this.refs.messageWrapper.getDOMNode();
messageWrapper.removeEventListener('drop', this.onDrop);
messageWrapper.removeEventListener('dragover', this.onDragOver);
messageWrapper.removeEventListener('dragleave', this.onDragLeaveOrEnd);
messageWrapper.removeEventListener('dragend', this.onDragLeaveOrEnd);
}
dis.unregister(this.dispatcherRef);
if (MatrixClientPeg.get()) {
MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
MatrixClientPeg.get().removeListener("Room.name", this.onRoomName);
MatrixClientPeg.get().removeListener("RoomMember.typing", this.onRoomMemberTyping);
MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember);
}
},
onAction: function(payload) {
switch (payload.action) {
case 'message_send_failed':
case 'message_sent':
case 'message_resend_started':
this.setState({
room: MatrixClientPeg.get().getRoom(this.props.roomId)
});
this.forceUpdate();
break;
case 'notifier_enabled':
this.forceUpdate();
break;
case 'call_state':
if (CallHandler.getCallForRoom(this.props.roomId)) {
// Call state has changed so we may be loading video elements
// which will obscure the message log.
// scroll to bottom
var messageWrapper = this.refs.messageWrapper;
if (messageWrapper) {
messageWrapper = messageWrapper.getDOMNode();
messageWrapper.scrollTop = messageWrapper.scrollHeight;
}
}
// possibly remove the conf call notification if we're now in
// the conf
this._updateConfCallNotification();
break;
}
},
// MatrixRoom still showing the messages from the old room?
// Set the key to the room_id. Sadly you can no longer get at
// the key from inside the component, or we'd check this in code.
/*componentWillReceiveProps: function(props) {
},*/
onRoomTimeline: function(ev, room, toStartOfTimeline) {
if (!this.isMounted()) return;
// ignore anything that comes in whilst pagingating: we get one
// event for each new matrix event so this would cause a huge
// number of UI updates. Just update the UI when the paginate
// call returns.
if (this.state.paginating) return;
// no point handling anything while we're waiting for the join to finish:
// we'll only be showing a spinner.
if (this.state.joining) return;
if (room.roomId != this.props.roomId) return;
if (this.refs.messageWrapper) {
var messageWrapper = this.refs.messageWrapper.getDOMNode();
this.atBottom = (
messageWrapper.scrollHeight - messageWrapper.scrollTop <=
(messageWrapper.clientHeight + 150)
);
}
var currentUnread = this.state.numUnreadMessages;
if (!toStartOfTimeline &&
(ev.getSender() !== MatrixClientPeg.get().credentials.userId)) {
// update unread count when scrolled up
if (this.atBottom) {
currentUnread = 0;
}
else {
currentUnread += 1;
}
}
this.setState({
room: MatrixClientPeg.get().getRoom(this.props.roomId),
numUnreadMessages: currentUnread
});
if (toStartOfTimeline && !this.state.paginating) {
this.fillSpace();
}
},
onRoomName: function(room) {
if (room.roomId == this.props.roomId) {
this.setState({
room: room
});
}
},
onRoomMemberTyping: function(ev, member) {
this.forceUpdate();
},
onRoomStateMember: function(ev, state, member) {
if (member.roomId !== this.props.roomId ||
member.userId !== VectorConferenceHandler.getConferenceUserIdForRoom(member.roomId)) {
return;
}
this._updateConfCallNotification();
},
_updateConfCallNotification: function() {
var room = MatrixClientPeg.get().getRoom(this.props.roomId);
if (!room) return;
var confMember = room.getMember(
VectorConferenceHandler.getConferenceUserIdForRoom(this.props.roomId)
);
if (!confMember) {
return;
}
var confCall = VectorConferenceHandler.getConferenceCallForRoom(confMember.roomId);
// A conf call notification should be displayed if there is an ongoing
// conf call but this cilent isn't a part of it.
this.setState({
displayConfCallNotification: (
(!confCall || confCall.call_state === "ended") &&
confMember.membership === "join"
)
});
},
componentDidMount: function() {
if (this.refs.messageWrapper) {
var messageWrapper = this.refs.messageWrapper.getDOMNode();
messageWrapper.addEventListener('drop', this.onDrop);
messageWrapper.addEventListener('dragover', this.onDragOver);
messageWrapper.addEventListener('dragleave', this.onDragLeaveOrEnd);
messageWrapper.addEventListener('dragend', this.onDragLeaveOrEnd);
messageWrapper.scrollTop = messageWrapper.scrollHeight;
this.fillSpace();
}
this._updateConfCallNotification();
},
componentDidUpdate: function() {
if (!this.refs.messageWrapper) return;
var messageWrapper = this.refs.messageWrapper.getDOMNode();
if (this.state.paginating && !this.waiting_for_paginate) {
var heightGained = messageWrapper.scrollHeight - this.oldScrollHeight;
messageWrapper.scrollTop += heightGained;
this.oldScrollHeight = undefined;
if (!this.fillSpace()) {
this.setState({paginating: false});
}
} else if (this.atBottom) {
messageWrapper.scrollTop = messageWrapper.scrollHeight;
if (this.state.numUnreadMessages !== 0) {
this.setState({numUnreadMessages: 0});
}
}
},
fillSpace: function() {
if (!this.refs.messageWrapper) return;
var messageWrapper = this.refs.messageWrapper.getDOMNode();
if (messageWrapper.scrollTop < messageWrapper.clientHeight && this.state.room.oldState.paginationToken) {
this.setState({paginating: true});
this.oldScrollHeight = messageWrapper.scrollHeight;
if (this.state.messageCap < this.state.room.timeline.length) {
this.waiting_for_paginate = false;
var cap = Math.min(this.state.messageCap + PAGINATE_SIZE, this.state.room.timeline.length);
this.setState({messageCap: cap, paginating: true});
} else {
this.waiting_for_paginate = true;
var cap = this.state.messageCap + PAGINATE_SIZE;
this.setState({messageCap: cap, paginating: true});
var self = this;
MatrixClientPeg.get().scrollback(this.state.room, PAGINATE_SIZE).finally(function() {
self.waiting_for_paginate = false;
if (self.isMounted()) {
self.setState({
room: MatrixClientPeg.get().getRoom(self.props.roomId)
});
}
// wait and set paginating to false when the component updates
});
}
return true;
}
return false;
},
onJoinButtonClicked: function(ev) {
var self = this;
MatrixClientPeg.get().joinRoom(this.props.roomId).then(function() {
self.setState({
joining: false,
room: MatrixClientPeg.get().getRoom(self.props.roomId)
});
}, function(error) {
self.setState({
joining: false,
joinError: error
});
});
this.setState({
joining: true
});
},
onMessageListScroll: function(ev) {
if (this.refs.messageWrapper) {
var messageWrapper = this.refs.messageWrapper.getDOMNode();
var wasAtBottom = this.atBottom;
this.atBottom = messageWrapper.scrollHeight - messageWrapper.scrollTop <= messageWrapper.clientHeight;
if (this.atBottom && !wasAtBottom) {
this.forceUpdate(); // remove unread msg count
}
}
if (!this.state.paginating) this.fillSpace();
},
onDragOver: function(ev) {
ev.stopPropagation();
ev.preventDefault();
ev.dataTransfer.dropEffect = 'none';
var items = ev.dataTransfer.items;
if (items.length == 1) {
if (items[0].kind == 'file') {
this.setState({ draggingFile : true });
ev.dataTransfer.dropEffect = 'copy';
}
}
},
onDrop: function(ev) {
ev.stopPropagation();
ev.preventDefault();
this.setState({ draggingFile : false });
var files = ev.dataTransfer.files;
if (files.length == 1) {
this.uploadFile(files[0]);
}
},
onDragLeaveOrEnd: function(ev) {
ev.stopPropagation();
ev.preventDefault();
this.setState({ draggingFile : false });
},
uploadFile: function(file) {
this.setState({
upload: {
fileName: file.name,
uploadedBytes: 0,
totalBytes: file.size
}
});
var self = this;
ContentMessages.sendContentToRoom(
file, this.props.roomId, MatrixClientPeg.get()
).progress(function(ev) {
//console.log("Upload: "+ev.loaded+" / "+ev.total);
self.setState({
upload: {
fileName: file.name,
uploadedBytes: ev.loaded,
totalBytes: ev.total
}
});
}).finally(function() {
self.setState({
upload: undefined
});
}).done(undefined, function() {
// display error message
});
},
getWhoIsTypingString: function() {
return WhoIsTyping.whoIsTypingString(this.state.room);
},
getEventTiles: function() {
var DateSeparator = sdk.getComponent('molecules.DateSeparator');
var ret = [];
var count = 0;
var EventTile = sdk.getComponent('molecules.EventTile');
for (var i = this.state.room.timeline.length-1; i >= 0 && count < this.state.messageCap; --i) {
var mxEv = this.state.room.timeline[i];
if (!EventTile.supportsEventType(mxEv.getType())) {
continue;
}
var continuation = false;
var last = false;
var dateSeparator = null;
if (i == this.state.room.timeline.length - 1) {
last = true;
}
if (i > 0 && count < this.state.messageCap - 1) {
if (this.state.room.timeline[i].sender &&
this.state.room.timeline[i - 1].sender &&
(this.state.room.timeline[i].sender.userId ===
this.state.room.timeline[i - 1].sender.userId) &&
(this.state.room.timeline[i].getType() ==
this.state.room.timeline[i - 1].getType())
)
{
continuation = true;
}
var ts0 = this.state.room.timeline[i - 1].getTs();
var ts1 = this.state.room.timeline[i].getTs();
if (new Date(ts0).toDateString() !== new Date(ts1).toDateString()) {
dateSeparator = <DateSeparator key={ts1} ts={ts1}/>;
continuation = false;
}
}
if (i === 1) { // n.b. 1, not 0, as the 0th event is an m.room.create and so doesn't show on the timeline
var ts1 = this.state.room.timeline[i].getTs();
dateSeparator = <li key={ts1}><DateSeparator ts={ts1}/></li>;
continuation = false;
}
ret.unshift(
<li key={mxEv.getId()}><EventTile mxEvent={mxEv} continuation={continuation} last={last}/></li>
);
if (dateSeparator) {
ret.unshift(dateSeparator);
}
++count;
}
return ret;
},
uploadNewState: function(new_name, new_topic, new_join_rule, new_history_visibility, new_power_levels) {
var old_name = this.state.room.name;
var old_topic = this.state.room.currentState.getStateEvents('m.room.topic', '');
if (old_topic) {
old_topic = old_topic.getContent().topic;
} else {
old_topic = "";
}
var old_join_rule = this.state.room.currentState.getStateEvents('m.room.join_rules', '');
if (old_join_rule) {
old_join_rule = old_join_rule.getContent().join_rule;
} else {
old_join_rule = "invite";
}
var old_history_visibility = this.state.room.currentState.getStateEvents('m.room.history_visibility', '');
if (old_history_visibility) {
old_history_visibility = old_history_visibility.getContent().history_visibility;
} else {
old_history_visibility = "shared";
}
var deferreds = [];
if (old_name != new_name && new_name != undefined && new_name) {
deferreds.push(
MatrixClientPeg.get().setRoomName(this.state.room.roomId, new_name)
);
}
if (old_topic != new_topic && new_topic != undefined) {
deferreds.push(
MatrixClientPeg.get().setRoomTopic(this.state.room.roomId, new_topic)
);
}
if (old_join_rule != new_join_rule && new_join_rule != undefined) {
deferreds.push(
MatrixClientPeg.get().sendStateEvent(
this.state.room.roomId, "m.room.join_rules", {
join_rule: new_join_rule,
}, ""
)
);
}
if (old_history_visibility != new_history_visibility && new_history_visibility != undefined) {
deferreds.push(
MatrixClientPeg.get().sendStateEvent(
this.state.room.roomId, "m.room.history_visibility", {
history_visibility: new_history_visibility,
}, ""
)
);
}
if (new_power_levels) {
deferreds.push(
MatrixClientPeg.get().sendStateEvent(
this.state.room.roomId, "m.room.power_levels", new_power_levels, ""
)
);
}
if (deferreds.length) {
var self = this;
q.all(deferreds).fail(function(err) {
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to set state",
description: err.toString()
});
}).finally(function() {
self.setState({
uploadingRoomSettings: false,
});
});
} else {
this.setState({
editingRoomSettings: false,
uploadingRoomSettings: false,
});
}
}
};

View File

@@ -1,58 +0,0 @@
/*
Copyright 2015 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var extend = require('matrix-react-sdk/lib/extend');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var BaseRegisterController = require('matrix-react-sdk/lib/controllers/templates/Register.js');
var RegisterController = {};
extend(RegisterController, BaseRegisterController);
RegisterController.onRegistered = function(user_id, access_token) {
MatrixClientPeg.replaceUsingAccessToken(
this.state.hs_url, this.state.is_url, user_id, access_token
);
this.setState({
step: 'profile',
busy: true
});
var self = this;
var cli = MatrixClientPeg.get();
cli.getProfileInfo(cli.credentials.userId).done(function(result) {
self.setState({
avatarUrl: result.avatar_url,
busy: false
});
},
function(err) {
console.err(err);
self.setState({
busy: false
});
});
};
RegisterController.onAccountReady = function() {
if (this.props.onLoggedIn) {
this.props.onLoggedIn();
}
};
module.exports = RegisterController;

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -0,0 +1,125 @@
/*
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.
*/
'use strict';
var PushRuleVectorState = require('./PushRuleVectorState');
module.exports = {
/**
* Extract the keyword rules from a list of rules, and parse them
* into a form which is useful for Vector's UI.
*
* Returns an object containing:
* rules: the primary list of keyword rules
* vectorState: a PushRuleVectorState indicating whether those rules are
* OFF/ON/LOUD
* externalRules: a list of other keyword rules, with states other than
* vectorState
*/
parseContentRules: function(rulesets) {
// first categorise the keyword rules in terms of their actions
var contentRules = this._categoriseContentRules(rulesets);
// Decide which content rules to display in Vector UI.
// Vector displays a single global rule for a list of keywords
// whereas Matrix has a push rule per keyword.
// Vector can set the unique rule in ON, LOUD or OFF state.
// Matrix has enabled/disabled plus a combination of (highlight, sound) tweaks.
// The code below determines which set of user's content push rules can be
// displayed by the vector UI.
// Push rules that does not fit, ie defined by another Matrix client, ends
// in externalRules.
// There is priority in the determination of which set will be the displayed one.
// The set with rules that have LOUD tweaks is the first choice. Then, the ones
// with ON tweaks (no tweaks).
if (contentRules.loud.length) {
return {
vectorState: PushRuleVectorState.LOUD,
rules: contentRules.loud,
externalRules: [].concat(contentRules.loud_but_disabled, contentRules.on, contentRules.on_but_disabled, contentRules.other),
};
}
else if (contentRules.loud_but_disabled.length) {
return {
vectorState: PushRuleVectorState.OFF,
rules: contentRules.loud_but_disabled,
externalRules: [].concat(contentRules.on, contentRules.on_but_disabled, contentRules.other),
};
}
else if (contentRules.on.length) {
return {
vectorState: PushRuleVectorState.ON,
rules: contentRules.on,
externalRules: [].concat(contentRules.on_but_disabled, contentRules.other),
};
}
else if (contentRules.on_but_disabled.length) {
return {
vectorState: PushRuleVectorState.OFF,
rules: contentRules.on_but_disabled,
externalRules: contentRules.other,
}
} else {
return {
vectorState: PushRuleVectorState.ON,
rules: [],
externalRules: contentRules.other,
}
}
},
_categoriseContentRules: function(rulesets) {
var contentRules = {on: [], on_but_disabled:[], loud: [], loud_but_disabled: [], other: []};
for (var kind in rulesets.global) {
for (var i = 0; i < Object.keys(rulesets.global[kind]).length; ++i) {
var r = rulesets.global[kind][i];
// check it's not a default rule
if (r.rule_id[0] === '.' || kind !== 'content') {
continue;
}
r.kind = kind; // is this needed? not sure
switch (PushRuleVectorState.contentRuleVectorStateKind(r)) {
case PushRuleVectorState.ON:
if (r.enabled) {
contentRules.on.push(r);
}
else {
contentRules.on_but_disabled.push(r);
}
break;
case PushRuleVectorState.LOUD:
if (r.enabled) {
contentRules.loud.push(r);
}
else {
contentRules.loud_but_disabled.push(r);
}
break;
default:
contentRules.other.push(r);
break;
}
}
}
return contentRules;
},
};

View File

@@ -0,0 +1,89 @@
/*
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.
*/
'use strict';
module.exports = {
// Encodes a dictionary of {
// "notify": true/false,
// "sound": string or undefined,
// "highlight: true/false,
// }
// to a list of push actions.
encodeActions: function(action) {
var notify = action.notify;
var sound = action.sound;
var highlight = action.highlight;
if (notify) {
var actions = ["notify"];
if (sound) {
actions.push({"set_tweak": "sound", "value": sound});
}
if (highlight) {
actions.push({"set_tweak": "highlight"});
} else {
actions.push({"set_tweak": "highlight", "value": false});
}
return actions;
} else {
return ["dont_notify"];
}
},
// Decode a list of actions to a dictionary of {
// "notify": true/false,
// "sound": string or undefined,
// "highlight: true/false,
// }
// If the actions couldn't be decoded then returns null.
decodeActions: function(actions) {
var notify = false;
var sound = null;
var highlight = false;
for (var i = 0; i < actions.length; ++i) {
var action = actions[i];
if (action === "notify") {
notify = true;
} else if (action === "dont_notify") {
notify = false;
} else if (typeof action === 'object') {
if (action.set_tweak === "sound") {
sound = action.value
} else if (action.set_tweak === "highlight") {
highlight = action.value;
} else {
// We don't understand this kind of tweak, so give up.
return null;
}
} else {
// We don't understand this kind of action, so give up.
return null;
}
}
if (highlight === undefined) {
// If a highlight tweak is missing a value then it defaults to true.
highlight = true;
}
var result = {notify: notify, highlight: highlight};
if (sound !== null) {
result.sound = sound;
}
return result;
},
};

View File

@@ -0,0 +1,94 @@
/*
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.
*/
'use strict';
var StandardActions = require('./StandardActions');
var NotificationUtils = require('./NotificationUtils');
var states = {
/** The push rule is disabled */
OFF: "off",
/** The user will receive push notification for this rule */
ON: "on",
/** The user will receive push notification for this rule with sound and
highlight if this is legitimate */
LOUD: "loud",
};
module.exports = {
/**
* Enum for state of a push rule as defined by the Vector UI.
* @readonly
* @enum {string}
*/
states: states,
/**
* Convert a PushRuleVectorState to a list of actions
*
* @return [object] list of push-rule actions
*/
actionsFor: function(pushRuleVectorState) {
if (pushRuleVectorState === this.ON) {
return StandardActions.ACTION_NOTIFY;
}
else if (pushRuleVectorState === this.LOUD) {
return StandardActions.ACTION_HIGHLIGHT_DEFAULT_SOUND;
}
},
/**
* Convert a pushrule's actions to a PushRuleVectorState.
*
* Determines whether a content rule is in the PushRuleVectorState.ON
* category or in PushRuleVectorState.LOUD, regardless of its enabled
* state. Returns null if it does not match these categories.
*/
contentRuleVectorStateKind: function(rule) {
var decoded = NotificationUtils.decodeActions(rule.actions);
if (!decoded) {
return null;
}
// Count tweaks to determine if it is a ON or LOUD rule
var tweaks = 0;
if (decoded.sound) {
tweaks++;
}
if (decoded.highlight) {
tweaks++;
}
var stateKind = null;
switch (tweaks) {
case 0:
stateKind = this.ON;
break;
case 2:
stateKind = this.LOUD;
break;
}
return stateKind;
},
};
for (var k in states) {
module.exports[k] = states[k];
};

View File

@@ -0,0 +1,30 @@
/*
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.
*/
'use strict';
var NotificationUtils = require('./NotificationUtils');
var encodeActions = NotificationUtils.encodeActions;
module.exports = {
ACTION_NOTIFY: encodeActions({notify: true}),
ACTION_NOTIFY_DEFAULT_SOUND: encodeActions({notify: true, sound: "default"}),
ACTION_NOTIFY_RING_SOUND: encodeActions({notify: true, sound: "ring"}),
ACTION_HIGHLIGHT_DEFAULT_SOUND: encodeActions({notify: true, sound: "default", highlight: true}),
ACTION_DONT_NOTIFY: encodeActions({notify: false}),
ACTION_DISABLED: null,
};

View File

@@ -0,0 +1,134 @@
/*
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.
*/
'use strict';
var StandardActions = require('./StandardActions');
var PushRuleVectorState = require('./PushRuleVectorState');
class VectorPushRuleDefinition {
constructor(opts) {
this.kind = opts.kind;
this.description = opts.description;
this.vectorStateToActions = opts.vectorStateToActions;
}
// Translate the rule actions and its enabled value into vector state
ruleToVectorState(rule) {
var enabled = false;
var actions = null;
if (rule) {
enabled = rule.enabled;
actions = rule.actions;
}
for (var stateKey in PushRuleVectorState.states) {
var state = PushRuleVectorState.states[stateKey];
var vectorStateToActions = this.vectorStateToActions[state];
if (!vectorStateToActions) {
// No defined actions means that this vector state expects a disabled (or absent) rule
if (!enabled) {
return state;
}
} else {
// The actions must match to the ones expected by vector state
if (enabled && JSON.stringify(rule.actions) === JSON.stringify(vectorStateToActions)) {
return state;
}
}
}
console.error("Cannot translate rule actions into Vector rule state. Rule: " +
JSON.stringify(rule));
return undefined;
}
};
/**
* The descriptions of rules managed by the Vector UI.
*/
module.exports = {
// Messages containing user's display name
// (skip contains_user_name which is too geeky)
".m.rule.contains_display_name": new VectorPushRuleDefinition({
kind: "underride",
description: "Messages containing my name",
vectorStateToActions: { // The actions for each vector state, or null to disable the rule.
on: StandardActions.ACTION_NOTIFY,
loud: StandardActions.ACTION_HIGHLIGHT_DEFAULT_SOUND,
off: StandardActions.ACTION_DISABLED
}
}),
// Messages just sent to the user in a 1:1 room
".m.rule.room_one_to_one": new VectorPushRuleDefinition({
kind: "underride",
description: "Messages in one-to-one chats",
vectorStateToActions: {
on: StandardActions.ACTION_NOTIFY,
loud: StandardActions.ACTION_NOTIFY_DEFAULT_SOUND,
off: StandardActions.ACTION_DONT_NOTIFY
}
}),
// Messages just sent to a group chat room
// 1:1 room messages are catched by the .m.rule.room_one_to_one rule if any defined
// By opposition, all other room messages are from group chat rooms.
".m.rule.message": new VectorPushRuleDefinition({
kind: "underride",
description: "Messages in group chats",
vectorStateToActions: {
on: StandardActions.ACTION_NOTIFY,
loud: StandardActions.ACTION_NOTIFY_DEFAULT_SOUND,
off: StandardActions.ACTION_DONT_NOTIFY
}
}),
// Invitation for the user
".m.rule.invite_for_me": new VectorPushRuleDefinition({
kind: "underride",
description: "When I'm invited to a room",
vectorStateToActions: {
on: StandardActions.ACTION_NOTIFY,
loud: StandardActions.ACTION_NOTIFY_DEFAULT_SOUND,
off: StandardActions.ACTION_DISABLED
}
}),
// Incoming call
".m.rule.call": new VectorPushRuleDefinition({
kind: "underride",
description: "Call invitation",
vectorStateToActions: {
on: StandardActions.ACTION_NOTIFY,
loud: StandardActions.ACTION_NOTIFY_RING_SOUND,
off: StandardActions.ACTION_DISABLED
}
}),
// Notifications from bots
".m.rule.suppress_notices": new VectorPushRuleDefinition({
kind: "override",
description: "Messages sent by bot",
vectorStateToActions: {
// .m.rule.suppress_notices is a "negative" rule, we have to invert its enabled value for vector UI
on: StandardActions.ACTION_DISABLED,
loud: StandardActions.ACTION_NOTIFY_DEFAULT_SOUND,
off: StandardActions.ACTION_DONT_NOTIFY,
}
}),
};

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,16 +16,9 @@ limitations under the License.
'use strict';
var React = require('react');
module.exports = React.createClass({
displayName: 'VideoFeed',
render: function() {
return (
<video>
</video>
);
},
});
module.exports = {
NotificationUtils: require('./NotificationUtils'),
PushRuleVectorState: require('./PushRuleVectorState'),
VectorPushRulesDefinitions: require('./VectorPushRulesDefinitions'),
ContentRules: require('./ContentRules'),
};

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -22,8 +22,13 @@ html {
}
body {
font-family: 'Lato', Helvetica, Arial, Sans-Serif;
font-size: 16px;
/* Open Sans lacks combining diacritics, so these will fall through
to the next font. Helevetica's diacritics however do not combine
nicely with Open Sans (on OSX, at least) and result in a huge
horizontal mess. Arial empirically gets it right, hence prioritising
Arial here. */
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
font-size: 15px;
color: #454545;
border: 0px;
margin: 0px;
@@ -34,9 +39,9 @@ div.error {
}
h2 {
color: #80cef4;
color: #454545;
font-weight: 400;
font-size: 20px;
font-size: 18px;
margin-top: 16px;
margin-bottom: 16px;
}
@@ -44,7 +49,35 @@ h2 {
a:hover,
a:link,
a:visited {
color: #80CEF4;
color: #76cfa6;
}
input[type=text]:focus, textarea:focus {
border: 1px solid #76CFA6;
outline: none;
box-shadow: none;
}
/* applied to side-panels and messagepanel when in RoomSettings */
.mx_fadable {
opacity: 1;
-webkit-transition: opacity 0.2s ease-in-out;
-moz-transition: opacity 0.2s ease-in-out;
-ms-transition: opacity 0.2s ease-in-out;
-o-transition: opacity 0.2s ease-in-out;
}
/* XXX: critical hack to GeminiScrollbar to allow them to work in FF 42 and Chrome 48.
Stop the scrollbar view from pushing out the container's overall sizing, which causes
flexbox to adapt to the new size and cause the view to keep growing.
*/
.gm-scrollbar-container .gm-scroll-view {
position: absolute;
}
/* hack to avoid accidental click-throughs if you miss the narrow scrollbar */
.gm-scrollbar.-vertical {
border-left: 6px solid transparent;
}
.mx_ContextualMenu_background {
@@ -58,7 +91,7 @@ a:visited {
}
.mx_ContextualMenu {
border: 1px solid #a9dbf4;
border: 1px solid #a4a4a4;
border-radius: 8px;
background-color: #fff;
color: #747474;
@@ -91,19 +124,9 @@ a:visited {
margin: 0 auto;
}
.mx_Dialog_background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000;
opacity: 0.2;
z-index: 2000;
}
.mx_Dialog_wrapper {
position: fixed;
z-index: 4000;
top: 0;
left: 0;
width: 100%;
@@ -124,18 +147,36 @@ a:visited {
background-color: #fff;
color: #747474;
text-align: center;
z-index: 2010;
z-index: 4010;
font-weight: 300;
font-size: 16px;
font-size: 15px;
position: relative;
border-radius: 8px;
max-width: 75%;
max-width: 80%;
}
.mx_ImageView {
margin: 6px;
/* hack: flexbox bug? */
margin-bottom: 4px;
.mx_Dialog_background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000;
opacity: 0.2;
}
.mx_Dialog_lightbox .mx_Dialog_background {
opacity: 0.85;
}
.mx_Dialog_lightbox .mx_Dialog {
border-radius: 0px;
background-color: transparent;
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
pointer-events: none;
}
.mx_Dialog_content {
@@ -146,26 +187,54 @@ a:visited {
padding-bottom: 24px;
}
.mx_Dialog button {
.mx_Dialog button, .mx_Dialog input[type="submit"] {
border: 0px;
height: 36px;
border-radius: 36px;
font-weight: 400;
font-size: 16px;
font-size: 15px;
color: #fff;
background-color: #80cef4;
background-color: #76cfa6;
margin-left: 8px;
margin-right: 8px;
padding-left: 1em;
padding-right: 1em;
}
.mx_ErrorDialogTitle,
.mx_QuestionDialogTitle {
.mx_Dialog_title {
min-height: 16px;
padding: 12px;
border-bottom: 1px solid #a9dbf4;
border-bottom: 1px solid #a4a4a4;
font-weight: bold;
font-size: 20px;
font-size: 18px;
line-height: 1.4;
}
.mx_TextInputDialog_label {
text-align: left;
padding-bottom: 12px;
}
.mx_TextInputDialog_input {
font-size: 15px;
border-radius: 3px;
border: 1px solid #f0f0f0;
padding: 9px;
color: #454545;
background-color: #fff;
}
.emojione {
height: 1em;
vertical-align: middle;
}
::-moz-selection {
background-color: #76CFA6;
color: white;
}
::selection {
background-color: #76CFA6;
color: white;
}

View File

@@ -1,7 +1,3 @@
.mx_RoomDropTarget,
.mx_RoomList_favourites_label,
.mx_RoomList_archive_label,
.mx_RoomHeader_search,
.mx_RoomSettings_encrypt,
.mx_CreateRoom_encrypt,
.mx_RightPanel_filebutton

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -15,10 +15,10 @@ limitations under the License.
*/
.mx_CreateRoom {
width: 720px;
width: 960px;
margin-left: auto;
margin-right: auto;
color: #4a4a4a;
color: #4a4a4a;
}
.mx_CreateRoom input,
@@ -26,7 +26,7 @@ limitations under the License.
border-radius: 3px;
border: 1px solid #c7c7c7;
font-weight: 300;
font-size: 14px;
font-size: 13px;
padding: 9px;
margin-top: 6px;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,12 +14,24 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_MatrixChat_splash {
position: relative;
height: 100%;
}
.mx_MatrixChat_splashButtons {
text-align: center;
width: 100%;
position: absolute;
bottom: 30px;
}
.mx_MatrixChat_wrapper {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
display: flex;
flex-direction: column;
-webkit-flex-direction: column;
@@ -35,7 +47,17 @@ limitations under the License.
-webkit-order: 1;
order: 1;
height: 21px;
height: 40px;
}
.mx_GuestWarningBar {
-webkit-box-ordinal-group: 1;
-moz-box-ordinal-group: 1;
-ms-flex-order: 1;
-webkit-order: 1;
order: 1;
height: 40px;
}
.mx_MatrixChat_toolbarShowing {
@@ -69,8 +91,10 @@ limitations under the License.
-webkit-order: 1;
order: 1;
-webkit-flex: 0 0 230px;
flex: 0 0 230px;
background-color: #eaf5f0;
-webkit-flex: 0 0 210px;
flex: 0 0 210px;
}
.mx_MatrixChat .mx_LeftPanel.collapsed {
@@ -85,17 +109,25 @@ limitations under the License.
-webkit-order: 2;
order: 2;
padding-left: 12px;
padding-right: 12px;
background-color: #f3f8fa;
padding-left: 25px;
padding-right: 22px;
background-color: #fff;
-webkit-flex: 1;
flex: 1;
/* Experimental fix for https://github.com/vector-im/vector-web/issues/947
and https://github.com/vector-im/vector-web/issues/946.
Empirically this stops the MessagePanel's width exploding outwards when
gemini is in 'prevented' mode
*/
overflow-x: auto;
/* XXX: Hack: apparently if you try to nest a flex-box
* within a non-flex-box within a flex-box, the height
* of the innermost element gets miscalculated if the
* parents are both auto.
* parents are both auto. Height has to be auto here
* for RoomView to correctly fit when the Toolbar is shown.
* Ideally we'd launch straight into the RoomView at this
* point, but instead we fudge it and make the middlePanel
* flex itself.
@@ -114,9 +146,8 @@ limitations under the License.
-webkit-order: 3;
order: 3;
background-color: #f3f8fa;
-webkit-flex: 0 0 230px;
flex: 0 0 230px;
-webkit-flex: 0 0 235px;
flex: 0 0 235px;
}
.mx_MatrixChat .mx_RightPanel.collapsed {

View File

@@ -0,0 +1,138 @@
/*
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_RoomStatusBar {
margin-top: 15px;
margin-left: 65px;
min-height: 34px;
}
/* position the indicator in the same place horizontally as .mx_EventTile_avatar. */
.mx_RoomStatusBar_indicator {
padding-left: 18px;
padding-right: 12px;
margin-left: -73px;
float: left;
width: 24px;
text-align: center;
}
.mx_RoomStatusBar_placeholderIndicator span {
color: #4a4a4a;
opacity: 0.5;
position: relative;
top: -4px;
/*
animation-duration: 1s;
animation-name: bounce;
animation-direction: alternate;
animation-iteration-count: infinite;
*/
}
.mx_RoomStatusBar_placeholderIndicator span:nth-child(1) {
animation-delay: 0.3s;
}
.mx_RoomStatusBar_placeholderIndicator span:nth-child(2) {
animation-delay: 0.6s;
}
.mx_RoomStatusBar_placeholderIndicator span:nth-child(3) {
animation-delay: 0.9s;
}
@keyframes bounce {
from {
opacity: 0.5;
top: 0;
}
to {
opacity: 0.2;
top: -3px;
}
}
.mx_RoomStatusBar_scrollDownIndicator {
cursor: pointer;
}
.mx_RoomStatusBar_unreadMessagesBar {
color: #ff0064;
cursor: pointer;
}
.mx_RoomStatusBar_connectionLostBar {
margin-top: 19px;
height: 58px;
}
.mx_RoomStatusBar_connectionLostBar img {
padding-left: 10px;
padding-right: 22px;
vertical-align: middle;
float: left;
}
.mx_RoomStatusBar_connectionLostBar_title {
color: #ff0064;
}
.mx_RoomStatusBar_connectionLostBar_desc {
color: #454545;
font-size: 13px;
opacity: 0.5;
}
.mx_RoomStatusBar_resend_link {
color: #454545 ! important;
text-decoration: underline ! important;
cursor: pointer;
}
.mx_RoomStatusBar_tabCompleteBar {
color: #4a4a4a;
}
.mx_RoomStatusBar_typingBar {
color: #4a4a4a;
opacity: 0.5;
overflow-y: hidden;
display: block;
}
.mx_RoomStatusBar_tabCompleteWrapper {
display: flex;
display: -webkit-flex;
height: 26px;
}
.mx_RoomStatusBar_tabCompleteWrapper .mx_TabCompleteBar {
flex: 1 1 auto;
-webkit-flex: 1 1 auto;
}
.mx_RoomStatusBar_tabCompleteEol {
flex: 0 0 auto;
-webkit-flex: 0 0 auto;
color: #76CFA6;
}
.mx_RoomStatusBar_tabCompleteEol object {
vertical-align: middle;
margin-right: 8px;
margin-top: -2px;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -36,15 +36,15 @@ limitations under the License.
-webkit-order: 1;
order: 1;
-webkit-flex: 0 0 88px;
flex: 0 0 88px;
-webkit-flex: 0 0 70px;
flex: 0 0 70px;
}
.mx_RoomView_fileDropTarget {
min-width: 0px;
max-width: 720px;
max-width: 960px;
width: 100%;
font-size: 20px;
font-size: 18px;
text-align: center;
pointer-events: none;
@@ -61,10 +61,10 @@ limitations under the License.
border-top-right-radius: 10px;
background-color: rgba(255, 255, 255, 0.9);
border: 2px dashed #80cef4;
border: 2px #e1dddd solid;
border-bottom: none;
position: absolute;
top: 88px;
top: 70px;
bottom: 0px;
z-index: 3000;
}
@@ -84,23 +84,31 @@ limitations under the License.
order: 2;
min-width: 0px;
max-width: 720px;
max-width: 960px;
width: 100%;
margin: auto;
overflow: auto;
border-bottom: 1px solid #a8dbf3;
border-bottom: 1px solid #e5e5e5;
-webkit-flex: 0 0 auto;
flex: 0 0 auto;
}
.mx_RoomView_messagePanel {
.mx_RoomView_topUnreadMessagesBar {
-webkit-box-ordinal-group: 3;
-moz-box-ordinal-group: 3;
-ms-flex-order: 3;
-webkit-order: 3;
order: 3;
}
.mx_RoomView_messagePanel {
-webkit-box-ordinal-group: 4;
-moz-box-ordinal-group: 4;
-ms-flex-order: 4;
-webkit-order: 4;
order: 4;
-webkit-flex: 1 1 0;
flex: 1 1 0;
@@ -111,8 +119,27 @@ limitations under the License.
}
.mx_RoomView_messageListWrapper {
max-width: 720px;
max-width: 960px;
margin: auto;
min-height: 100%;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
flex-direction: column;
-webkit-flex-direction: column;
justify-content: flex-end;
-webkit-justify-content: flex-end;
}
.mx_RoomView_searchResultsPanel .mx_RoomView_messageListWrapper {
justify-content: flex-start;
-webkit-justify-content: flex-start;
}
.mx_RoomView_MessageList {
@@ -129,8 +156,9 @@ limitations under the License.
clear: both;
margin-top: 32px;
margin-bottom: 8px;
margin-left: 63px;
padding-bottom: 6px;
border-bottom: 1px solid #a8dbf3;
border-bottom: 1px solid #e5e5e5;
}
.mx_RoomView_invitePrompt {
@@ -141,7 +169,7 @@ limitations under the License.
order: 2;
min-width: 0px;
max-width: 720px;
max-width: 960px;
width: 100%;
margin: auto;
@@ -149,55 +177,22 @@ limitations under the License.
margin-bottom: 12px;
}
li.mx_RoomView_myReadMarker_container {
height: 0px;
margin: 0px;
padding: 0px;
border: 0px;
}
hr.mx_RoomView_myReadMarker {
border-top: solid 1px #76cfa6;
border-bottom: solid 1px #76cfa6;
margin-top: 0px;
position: relative;
top: 5px;
}
.mx_RoomView_statusArea {
-webkit-box-ordinal-group: 4;
-moz-box-ordinal-group: 4;
-ms-flex-order: 4;
-webkit-order: 4;
order: 4;
width: 100%;
-webkit-flex: 0 0 58px;
flex: 0 0 58px;
}
.mx_RoomView_statusAreaBox {
max-width: 720px;
margin: auto;
border-top: 1px solid #a8dbf3;
}
.mx_RoomView_unreadMessagesBar {
margin-top: 13px;
color: #fff;
font-weight: bold;
background-color: #ff0064;
border-radius: 30px;
height: 30px;
line-height: 30px;
cursor: pointer;
}
.mx_RoomView_unreadMessagesBar img {
padding-left: 22px;
padding-right: 22px;
}
.mx_RoomView_typingBar {
margin-top: 17px;
margin-left: 56px;
color: #818794;
}
.mx_RoomView_typingBar img {
padding-left: 12px;
padding-right: 12px;
margin-left: -64px;
margin-top: -7px;
float: left;
}
.mx_RoomView .mx_MessageComposer {
-webkit-box-ordinal-group: 5;
-moz-box-ordinal-group: 5;
-ms-flex-order: 5;
@@ -205,44 +200,63 @@ limitations under the License.
order: 5;
width: 100%;
-webkit-flex: 0 0 63px;
flex: 0 0 63px;
margin-right: 2px;
-webkit-flex: 0 0 auto;
flex: 0 0 auto;
}
.mx_RoomView_uploadProgressOuter {
width: 100%;
background-color: rgba(169, 219, 244, 0.5);
height: 4px;
.mx_RoomView_statusAreaBox {
max-width: 960px;
margin: auto;
min-height: 60px;
}
.mx_RoomView_uploadProgressInner {
background-color: #80cef4;
height: 4px;
.mx_RoomView_statusAreaBox_line {
margin-left: 65px;
border-top: 1px solid #e5e5e5;
height: 1px;
}
.mx_RoomView_uploadFilename {
margin-top: 15px;
margin-left: 56px;
.mx_RoomView_inCall .mx_RoomView_statusAreaBox_line {
border-top: 1px hidden;
}
.mx_RoomView_uploadIcon {
float: left;
margin-top: 6px;
margin-left: 5px;
.mx_RoomView_inCall .mx_MessageComposer_wrapper {
border-top: 2px hidden;
}
.mx_RoomView_uploadCancel {
.mx_RoomView_inCall .mx_RoomView_statusAreaBox {
background-color: #76CFA6;
color: #fff;
position: relative;
}
.mx_RoomView_voipChevron {
position: absolute;
bottom: -11px;
right: 11px;
}
.mx_RoomView_voipButton {
float: right;
margin-top: 6px;
margin-right: 10px;
margin-right: 13px;
cursor: pointer;
}
.mx_RoomView_uploadBytes {
float: right;
opacity: 0.5;
margin-top: 15px;
margin-right: 10px;
.mx_RoomView_voipButton object {
pointer-events: none;
}
.mx_RoomView .mx_MessageComposer {
-webkit-box-ordinal-group: 6;
-moz-box-ordinal-group: 6;
-ms-flex-order: 6;
-webkit-order: 6;
order: 6;
width: 100%;
-webkit-flex: 0 0 auto;
flex: 0 0 auto;
margin-right: 2px;
}
.mx_RoomView_ongoingConfCallNotification {
@@ -251,5 +265,6 @@ limitations under the License.
background-color: #ff0064;
color: #fff;
font-weight: bold;
padding: 6px;
}
padding: 6px 0;
cursor: pointer;
}

View File

@@ -0,0 +1,68 @@
/*
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_SearchBox {
height: 24px;
margin-left: 16px;
margin-right: 20px;
padding-top: 24px;
padding-bottom: 22px;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
display: flex;
display: -webkit-flex;
}
.mx_SearchBox_searchButton {
margin-right: 10px;
pointer-events: none;
}
.mx_SearchBox_closeButton {
cursor: pointer;
}
.mx_SearchBox_search {
flex: 1 1 auto;
-webkit-flex: 1 1 auto;
width: 0px;
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
font-size: 12px;
margin-top: -2px;
height: 24px;
border: 0px ! important;
/* border-bottom: 1px solid rgba(0, 0, 0, 0.1) ! important; */
background-color: transparent;
border: 0px;
}
.mx_SearchBox_minimise,
.mx_SearchBox_maximise {
margin-top: 3px;
cursor: pointer;
}
.mx_SearchBox_minimise {
margin-left: 10px;
}
.mx_SearchBox_maximise {
margin-left: 9px;
}
.mx_SearchBox object {
pointer-events: none;
}

View File

@@ -0,0 +1,61 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_UploadBar {
position: relative;
}
.mx_UploadBar_uploadProgressOuter {
height: 5px;
margin-left: 63px;
margin-top: -1px;
padding-bottom: 5px;
}
.mx_UploadBar_uploadProgressInner {
background-color: #76cfa6;
height: 5px;
}
.mx_UploadBar_uploadFilename {
margin-top: 5px;
margin-left: 65px;
opacity: 0.5;
color: #4a4a4a;
}
.mx_UploadBar_uploadIcon {
float: left;
margin-top: 5px;
margin-left: 14px;
}
.mx_UploadBar_uploadCancel {
float: right;
margin-top: 5px;
margin-right: 10px;
position: relative;
opacity: 0.6;
cursor: pointer;
z-index: 1;
}
.mx_UploadBar_uploadBytes {
float: right;
margin-top: 5px;
margin-right: 30px;
color: #76cfa6;
}

View File

@@ -0,0 +1,188 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_UserSettings {
max-width: 960px;
width: 100%;
margin-left: auto;
margin-right: auto;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
flex-direction: column;
-webkit-flex-direction: column;
}
.mx_UserSettings .mx_RoomHeader {
-webkit-box-ordinal-group: 1;
-moz-box-ordinal-group: 1;
-ms-flex-order: 1;
-webkit-order: 1;
order: 1;
-webkit-flex: 0 0 70px;
flex: 0 0 70px;
}
.mx_UserSettings_body {
-webkit-box-ordinal-group: 2;
-moz-box-ordinal-group: 2;
-ms-flex-order: 2;
-webkit-order: 2;
order: 2;
-webkit-flex: 1 1 0;
flex: 1 1 0;
margin-top: -20px;
overflow-y: auto;
}
.mx_UserSettings h3 {
clear: both;
margin-left: 63px;
text-transform: uppercase;
color: #3d3b39;
font-weight: 600;
font-size: 13px;
margin-top: 26px;
margin-bottom: 10px;
}
.mx_UserSettings_section h3 {
margin-left: 0px;
}
.mx_UserSettings_spinner {
display: inline-block;
vertical-align: middle;
margin-right: 12px;
width: 32px;
height: 32px;
}
.mx_UserSettings_button {
display: inline;
vertical-align: middle;
border: 0px;
border-radius: 36px;
font-weight: 400;
font-size: 16px;
color: #fff;
background-color: #76cfa6;
width: auto;
margin: auto;
padding: 7px;
padding-left: 1.5em;
padding-right: 1.5em;
cursor: pointer;
}
.mx_UserSettings_section {
margin-left: 63px;
margin-top: 28px;
margin-bottom: 28px;
}
.mx_UserSettings_accountTable
.mx_UserSettings_notifTable
{
display: table;
}
.mx_UserSettings_notifTable .mx_Spinner {
position: absolute;
}
.mx_UserSettings_profileTable
{
display: table;
float: left;
}
.mx_UserSettings_profileTableRow
{
display: table-row;
}
.mx_UserSettings_profileLabelCell
{
padding-bottom: 21px;
display: table-cell;
font-weight: bold;
padding-right: 24px;
}
.mx_UserSettings_profileInputCell {
display: table-cell;
padding-bottom: 21px;
width: 240px;
}
.mx_UserSettings_profileInputCell input,
.mx_UserSettings_profileInputCell .mx_EditableText
{
display: inline-block;
border: 0px;
border-bottom: 1px solid rgba(151, 151, 151, 0.5);
padding: 0px;
width: 240px;
color: rgba(74, 74, 74, 0.9);
font-family: 'Open Sans', Helvetica, Arial, Sans-Serif;
font-size: 16px;
}
.mx_UserSettings_addThreepid {
display: table-cell;
padding-left: 0.5em;
position: relative;
cursor: pointer;
}
.mx_UserSettings_changePasswordButton {
float: right;
margin-right: 32px;
margin-left: 32px;
}
.mx_UserSettings_logout {
float: right;
margin-right: 32px;
margin-left: 32px;
}
.mx_UserSettings_avatarPicker {
margin-left: 32px;
margin-right: 32px;
float: right;
cursor: pointer;
}
.mx_UserSettings_avatarPicker_img .mx_BaseAvatar_image {
object-fit: cover;
}
.mx_UserSettings_avatarPicker_edit {
text-align: center;
margin-top: 10px;
}
.mx_UserSettings_avatarPicker_edit > input {
display: none;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -17,6 +17,18 @@ limitations under the License.
.mx_Login {
width: 100%;
height: 100%;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
overflow: auto;
}
.mx_Login h2 {
@@ -28,8 +40,10 @@ limitations under the License.
.mx_Login_box {
width: 300px;
min-height: 450px;
padding-top: 50px;
padding-bottom: 50px;
margin: auto;
padding-top: 100px;
}
.mx_Login_logo {
@@ -41,11 +55,19 @@ limitations under the License.
border-radius: 3px;
border: 1px solid #c7c7c7;
font-weight: 300;
font-size: 14px;
font-size: 13px;
padding: 9px;
margin-bottom: 14px;
}
.mx_Login_fieldLabel {
margin-top: -10px;
margin-left: 8px;
margin-bottom: 14px;
font-size: 13px;
opacity: 0.8;
}
.mx_Login_submit {
margin-top: 35px;
margin-bottom: 24px;
@@ -54,16 +76,17 @@ limitations under the License.
height: 40px;
border: 0px;
background-color: #76cfa6;
font-size: 16px;
font-size: 15px;
color: #fff;
}
.mx_Login_label {
font-size: 14px;
font-size: 13px;
opacity: 0.8;
}
.mx_Login_checkbox {
.mx_Login_checkbox,
.mx_Login_radio {
margin-right: 10px;
}
@@ -71,7 +94,7 @@ limitations under the License.
display: block;
text-align: center;
width: 100%;
font-size: 14px;
font-size: 13px;
opacity: 0.8;
}
@@ -82,8 +105,9 @@ limitations under the License.
.mx_Login_links {
display: block;
text-align: center;
margin-top: 15px;
width: 100%;
font-size: 14px;
font-size: 13px;
opacity: 0.8;
}
@@ -91,6 +115,21 @@ limitations under the License.
color: #4a4a4a;
}
.mx_Login_prompt {
padding-top: 15px;
padding-bottom: 15px;
font-size: 13px;
}
.mx_Login_forgot {
font-size: 13px;
opacity: 0.8;
}
.mx_Login_forgot:link {
color: #4a4a4a;
}
.mx_Login_loader {
position: absolute;
left: 50%;

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,21 +14,21 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_MatrixToolbar {
text-align: center;
background-color: #ff0064;
.mx_BaseAvatar {
position: relative;
}
.mx_BaseAvatar_initial {
position: absolute;
z-index: 1;
color: #fff;
font-weight: bold;
padding: 6px;
text-align: center;
speak: none;
pointer-events: none;
font-weight: normal;
}
.mx_MatrixToolbar button {
margin-left: 12px;
.mx_BaseAvatar_image {
border-radius: 40px;
vertical-align: top;
}
.mx_MatrixToolbar_close {
float: right;
margin-top: 3px;
margin-right: 12px;
cursor: pointer;
}

View File

@@ -0,0 +1,24 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_SetDisplayNameDialog_input {
border-radius: 3px;
border: 1px solid #f0f0f0;
padding: 9px;
color: #454545;
background-color: #fff;
font-size: 15px;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@ limitations under the License.
.mx_ServerConfig_help:link {
opacity: 0.8;
font-size: 14px;
font-size: 13px;
font-weight: 300;
color: #4a4a4a;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,7 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_MImageTile_thumbnail {
.mx_MImageBody {
display: block;
}
.mx_MImageBody_thumbnail {
max-width: 100%;
/*
background-color: #fff;
border: 2px solid #fff;
@@ -22,16 +27,20 @@ limitations under the License.
*/
}
.mx_MImageTile_download {
color: #80cef4;
.mx_MImageBody_download {
color: #76cfa6;
cursor: pointer;
}
.mx_MImageTile_download a {
color: #80cef4;
.mx_MImageBody_download a {
color: #76cfa6;
text-decoration: none;
}
.mx_MImageTile_download img {
padding-right: 8px;
}
.mx_MImageBody_download object {
margin-left: -16px;
padding-right: 4px;
margin-top: -4px;
vertical-align: middle;
pointer-events: none;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_UserSettings {
width: 720px;
margin-left: auto;
margin-right: auto;
.mx_MNoticeBody {
white-space: pre-wrap;
opacity: 0.6;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,7 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_MTextTile {
.mx_MTextBody {
white-space: pre-wrap;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,3 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_TextualEvent {
opacity: 0.5;
overflow-y: hidden;
}

View File

@@ -0,0 +1,109 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_EntityTile {
display: table-row;
position: relative;
color: #454545;
cursor: pointer;
}
.mx_EntityTile_invite {
display: table-cell;
vertical-align: middle;
margin-left: 10px;
width: 26px;
}
.mx_EntityTile_avatar {
display: table-cell;
padding-left: 3px;
padding-right: 12px;
padding-top: 4px;
padding-bottom: 4px;
vertical-align: middle;
width: 36px;
height: 36px;
position: relative;
}
.mx_EntityTile_power {
position: absolute;
width: 16px;
height: 17px;
top: 0px;
right: 6px;
}
.mx_EntityTile_name {
display: table-cell;
vertical-align: middle;
overflow: hidden;
font-size: 14px;
text-overflow: ellipsis;
}
.mx_EntityTile_details {
display: table-cell;
padding-right: 14px;
vertical-align: middle;
}
.mx_EntityTile_name_hover {
font-size: 13px;
overflow: hidden;
text-overflow: ellipsis;
}
.mx_EntityTile_chevron {
margin-top: 8px;
margin-right: -4px;
margin-left: 6px;
float: right;
}
.mx_EntityTile_ellipsis .mx_EntityTile_name {
font-style: italic;
font-color: #454545;
}
.mx_EntityTile_invitePlaceholder .mx_EntityTile_name {
font-style: italic;
font-color: #454545;
}
.mx_EntityTile_unavailable .mx_EntityTile_avatar,
.mx_EntityTile_unavailable .mx_EntityTile_name,
.mx_EntityTile_unavailable .mx_EntityTile_name_hover
{
opacity: 0.66;
}
.mx_EntityTile_offline .mx_EntityTile_avatar,
.mx_EntityTile_offline .mx_EntityTile_name,
.mx_EntityTile_offline .mx_EntityTile_name_hover
{
opacity: 0.25;
}
.mx_EntityTile_unknown .mx_EntityTile_avatar,
.mx_EntityTile_unknown .mx_EntityTile_name,
.mx_EntityTile_unknown .mx_EntityTile_name_hover
{
opacity: 0.25;
}

View File

@@ -0,0 +1,214 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_EventTile {
max-width: 100%;
clear: both;
margin-top: 24px;
margin-left: 65px;
}
.mx_EventTile_avatar {
padding-left: 18px;
padding-right: 12px;
margin-left: -73px;
margin-top: -2px;
float: left;
position: relative;
top: 0px;
cursor: pointer;
}
.mx_EventTile_continuation {
margin-top: 8px ! important;
}
.mx_EventTile .mx_SenderProfile {
color: #454545;
opacity: 0.5;
display: inline-block;
font-size: 13px;
overflow-y: hidden;
cursor: pointer;
}
.mx_EventTile .mx_MessageTimestamp {
color: #acacac;
font-size: 11px;
}
.mx_EventTile_line {
position: relative;
/* ideally should be 100px, but 95px gives us a max thumbnail size of 800x600, which is nice */
margin-right: 95px;
}
/* all the overflow-y: hidden; are to trap Zalgos -
but they introduce an implicit overflow-x: auto.
so make that explicitly hidden too to avoid random
horizontal scrollbars occasionally appearing, like in
https://github.com/vector-im/vector-web/issues/1154
*/
.mx_EventTile_content {
display: block;
overflow-y: hidden;
overflow-x: hidden;
}
/* Various markdown overrides */
.mx_EventTile_content .markdown-body {
font-family: inherit ! important;
white-space: normal ! important;
line-height: inherit ! important;
color: inherit;
font-size: 15px;
}
/* have to use overlay rather than auto otherwise Linux and Windows
Chrome gets very confused about vertical spacing:
https://github.com/vector-im/vector-web/issues/754
*/
.mx_EventTile_content .markdown-body pre {
overflow-x: overlay;
overflow-y: visible;
}
.mx_EventTile_content .markdown-body h1,
.mx_EventTile_content .markdown-body h2,
.mx_EventTile_content .markdown-body h3,
.mx_EventTile_content .markdown-body h4,
.mx_EventTile_content .markdown-body h5,
.mx_EventTile_content .markdown-body h6
{
font-family: inherit ! important;
}
.mx_EventTile_content .markdown-body a {
color: #76cfa6;
}
.mx_EventTile_content .markdown-body .hljs {
display: inline ! important;
}
/* end of overrides */
/* this is used for the tile for the event which is selected via the URL.
* TODO: ultimately we probably want some transition on here.
*/
.mx_EventTile_selected {
border-left: #76cfa6 5px solid;
margin-left: 53px;
padding-left: 7px;
}
.mx_EventTile_searchHighlight {
background-color: #76cfa6;
color: #fff;
border-radius: 5px;
padding-left: 2px;
padding-right: 2px;
cursor: pointer;
}
.mx_EventTile_searchHighlight a {
background-color: #76cfa6;
color: #fff;
}
.mx_EventTile_sending {
color: #ddd;
}
.mx_EventTile_notSent {
color: #f44;
}
.mx_EventTile_highlight,
.mx_EventTile_highlight .markdown-body
{
color: #FF0064;
}
.mx_EventTile_contextual {
opacity: 0.4;
}
.mx_EventTile_msgOption {
float: right;
text-align: right;
z-index: 1;
position: relative;
width: 90px;
height: 1px; /* Hack to stop the height of this pushing the messages apart. Replaces marigin-top: -6px. This interacts better with a read marker being in between. Content overflows. */
margin-right: 10px;
}
.mx_EventTile_msgOption a {
text-decoration: none;
}
.mx_EventTile .mx_MessageTimestamp {
display: block;
visibility: hidden;
text-align: right;
white-space: nowrap;
}
.mx_EventTile_last .mx_MessageTimestamp {
visibility: visible;
}
.mx_EventTile:hover .mx_MessageTimestamp {
visibility: visible;
}
.mx_EventTile_editButton {
position: absolute;
display: inline-block;
visibility: hidden;
}
.mx_EventTile:hover .mx_EventTile_editButton {
visibility: visible;
}
.mx_EventTile.menu .mx_EventTile_editButton {
visibility: visible;
}
.mx_EventTile.menu .mx_MessageTimestamp {
visibility: visible;
}
.mx_EventTile_readAvatars {
position: relative;
display: inline-block;
width: 14px;
height: 14px;
}
.mx_EventTile_readAvatars .mx_BaseAvatar {
position: absolute;
display: inline-block;
}
.mx_EventTile_readAvatarRemainder {
color: #acacac;
font-size: 11px;
position: absolute;
}

View File

@@ -0,0 +1,65 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_LinkPreviewWidget {
margin-top: 15px;
margin-right: 15px;
margin-bottom: 15px;
display: -webkit-flex;
display: flex;
border-left: 4px solid #ddd;
color: #888;
}
.mx_LinkPreviewWidget_image {
-webkit-flex: 0 0 100px;
flex: 0 0 100px;
margin-left: 15px;
text-align: center;
cursor: pointer;
}
.mx_LinkPreviewWidget_caption {
margin-left: 15px;
-webkit-flex: 1 1 auto;
flex: 1 1 auto;
}
.mx_LinkPreviewWidget_title {
display: inline;
font-weight: bold;
}
.mx_LinkPreviewWidget_siteName {
display: inline;
}
.mx_LinkPreviewWidget_description {
margin-top: 8px;
white-space: normal;
word-break: break-word;
}
.mx_LinkPreviewWidget_cancel {
visibility: hidden;
cursor: pointer;
-webkit-flex: 0 0 40px;
flex: 0 0 40px;
}
.mx_LinkPreviewWidget:hover .mx_LinkPreviewWidget_cancel {
visibility: visible;
}

View File

@@ -0,0 +1,74 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_MemberInfo {
margin-top: 20px;
height: 100%;
}
.mx_MemberInfo h2 {
margin-top: 6px;
}
.mx_MemberInfo_cancel {
float: right;
margin-right: 18px;
cursor: pointer;
}
.mx_MemberInfo_avatar {
clear: both;
}
.mx_MemberInfo_avatar .mx_BaseAvatar {
cursor: not-allowed;
}
.mx_MemberInfo_avatar .mx_BaseAvatar.mx_BaseAvatar_image {
cursor: pointer;
}
.mx_MemberInfo_profile {
margin-bottom: 16px;
}
.mx_MemberInfo h3 {
text-transform: uppercase;
color: #3d3b39;
font-weight: 600;
font-size: 13px;
margin-top: 16px;
margin-bottom: 14px;
}
.mx_MemberInfo_profileField {
font-color: #999999;
font-size: 13px;
position: relative;
background-color: #fff;
}
.mx_MemberInfo_buttons {
margin-bottom: 16px;
}
.mx_MemberInfo_field {
cursor: pointer;
font-size: 13px;
color: #76cfa6;
margin-left: 8px;
line-height: 23px;
}

View File

@@ -0,0 +1,103 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_MemberList {
height: 100%;
margin-top: 12px;
margin-right: 20px;
-webkit-flex: 1;
flex: 1;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
flex-direction: column;
-webkit-flex-direction: column;
}
.mx_MemberList .mx_Spinner {
flex: 0;
-webkit-flex: 0;
}
.mx_MemberList_chevron {
position: absolute;
right: 35px;
margin-top: -15px;
}
.mx_MemberList_border {
overflow-y: auto;
order: 1;
-webkit-flex: 1 1 0;
flex: 1 1 0px;
}
.mx_MemberList .mx_SearchableEntityList {
order: 1;
flex: 0 0 auto;
-webkit-flex: 0 0 auto;
}
.mx_MemberList .mx_SearchableEntityList_expanded {
flex: 1 0 0;
-webkit-flex: 1 0 0;
}
.mx_MemberList_joined {
order: 2;
flex: 1 0 0;
-webkit-flex: 1 0 0;
overflow-y: auto;
}
/*
.mx_MemberList_invited {
order: 3;
flex: 0 0 100px;
-webkit-flex: 0 0 100px;
overflow-y: auto;
}
*/
.mx_MemberList_invited h2 {
text-transform: uppercase;
color: #3d3b39;
font-weight: 600;
font-size: 13px;
padding-left: 3px;
padding-right: 12px;
margin-top: 8px;
margin-bottom: 4px;
}
/* we have to have display: table in order for the horizontal wrapping to work */
.mx_MemberList_wrapper {
display: table;
table-layout: fixed;
width: 100%;
}
.mx_MemberList_outerWrapper {
height: 0px;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -15,70 +15,107 @@ limitations under the License.
*/
.mx_MessageComposer_wrapper {
max-width: 720px;
height: 50px;
max-width: 960px;
vertical-align: middle;
margin: auto;
background-color: #fff;
border-radius: 25px;
border: 1px solid #a9dbf4;
border-top: 1px solid #e5e5e5;
}
.mx_MessageComposer_row {
display: table-row;
width: 100%;
height: 50px;
}
.mx_MessageComposer .mx_MessageComposer_avatar {
display: table-cell;
padding-left: 5px;
padding-right: 10px;
height: 50px;
padding-left: 10px;
padding-right: 28px;
vertical-align: middle;
}
.mx_MessageComposer .mx_MessageComposer_avatar img {
margin-top: 5px;
border-radius: 20px;
background-color: #dbdbdb;
.mx_MessageComposer .mx_MessageComposer_avatar .mx_BaseAvatar {
display: block;
}
.mx_MessageComposer_composecontrols {
width: 100%;
}
.mx_MessageComposer_noperm_error {
display: table-cell;
width: 100%;
vertical-align: middle;
height: 60px;
text-align: center;
font-style: italic;
color: #888;
}
.mx_MessageComposer_input {
display: table-cell;
width: 100%;
vertical-align: middle;
height: 50px;
height: 60px;
}
.mx_MessageComposer_input textarea {
display: block;
font-size: 15px;
width: 100%;
height: 1.2em;
padding-top: 0.7em;
padding-bottom: 0.7em;
padding: 0px;
margin-top: 6px;
margin-bottom: 6px;
border: 0px;
resize: none;
outline: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
box-shadow: none;
color: #454545;
background-color: #fff;
/* needed for FF */
font-family: 'Lato', Helvetica, Arial, Sans-Serif;
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
}
/* hack for FF as vertical alignment of custom placeholder text is broken */
.mx_MessageComposer_input textarea::-moz-placeholder {
line-height: 100%;
color: #76cfa6;
opacity: 1.0;
}
.mx_MessageComposer_input textarea::-webkit-input-placeholder {
color: #76cfa6;
}
.mx_MessageComposer_upload {
.mx_MessageComposer_upload,
.mx_MessageComposer_hangup,
.mx_MessageComposer_voicecall,
.mx_MessageComposer_videocall {
display: table-cell;
vertical-align: middle;
padding-right: 15px;
padding-left: 10px;
padding-right: 10px;
cursor: pointer;
}
.mx_MessageComposer_upload img {
.mx_MessageComposer_upload object,
.mx_MessageComposer_hangup object,
.mx_MessageComposer_voicecall object,
.mx_MessageComposer_videocall object {
pointer-events: none;
}
.mx_MessageComposer_videocall {
padding-right: 10px;
padding-top: 4px;
}
.mx_MessageComposer_voicecall {
padding-right: 10px;
padding-top: 4px;
}
.mx_MessageComposer_upload object {
margin-top: 5px;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_MNoticeTile {
.mx_PresenceLabel {
font-size: 11px;
opacity: 0.5;
}
}

View File

@@ -0,0 +1,263 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/* add 20px to the height of the header when editing */
.mx_RoomHeader_editing {
-webit-flex: 0 0 93px ! important;
flex: 0 0 93px ! important;
}
.mx_RoomHeader_wrapper {
max-width: 960px;
margin: auto;
height: 70px;
-webkit-align-items: center;
align-items: center;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
.mx_RoomHeader_leftRow {
margin-left: -2px;
-webkit-box-ordinal-group: 1;
-moz-box-ordinal-group: 1;
-ms-flex-order: 1;
-webkit-order: 1;
order: 1;
-webkit-flex: 1;
flex: 1;
}
.mx_RoomHeader_spinner {
height: 36px;
-webkit-box-ordinal-group: 2;
-moz-box-ordinal-group: 2;
-ms-flex-order: 2;
-webkit-order: 2;
order: 2;
padding-left: 12px;
padding-right: 12px;
}
.mx_RoomHeader_textButton {
height: 36px;
background-color: #76cfa6;
border-radius: 36px;
margin-right: 8px;
color: #fff;
line-height: 34px;
margin-top: -2px;
text-align: center;
-webkit-box-ordinal-group: 2;
-moz-box-ordinal-group: 2;
-ms-flex-order: 2;
-webkit-order: 2;
order: 2;
cursor: pointer;
/*
-webkit-flex: 0 0 90px;
flex: 0 0 90px;
*/
padding-left: 12px;
padding-right: 12px;
}
.mx_RoomHeader_cancelButton {
-webkit-box-ordinal-group: 2;
-moz-box-ordinal-group: 2;
-ms-flex-order: 2;
-webkit-order: 2;
order: 2;
cursor: pointer;
padding-left: 12px;
padding-right: 12px;
}
.mx_RoomHeader_rightRow {
margin-top: 4px;
background-color: #fff;
-webkit-box-ordinal-group: 3;
-moz-box-ordinal-group: 3;
-ms-flex-order: 3;
-webkit-order: 3;
order: 3;
}
.mx_RoomHeader_info {
display: table-cell;
width: 100%;
vertical-align: middle;
}
.mx_RoomHeader_simpleHeader {
line-height: 70px;
color: #454545;
font-size: 22px;
font-weight: bold;
overflow: hidden;
margin-left: 63px;
text-overflow: ellipsis;
width: 100%;
}
.mx_RoomHeader_simpleHeader .mx_RoomHeader_cancelButton {
float: right;
}
.mx_RoomHeader_name {
vertical-align: middle;
width: 100%;
height: 31px;
overflow: hidden;
color: #454545;
font-weight: bold;
font-size: 22px;
padding-left: 19px;
padding-right: 16px;
/* why isn't text-overflow working? */
text-overflow: ellipsis;
border-bottom: 1px solid transparent;
}
.mx_RoomHeader_nametext {
display: inline-block;
}
.mx_RoomHeader_settingsHint {
color: #a2a2a2 ! important;
}
.mx_RoomHeader_searchStatus {
display: inline-block;
font-weight: normal;
opacity: 0.6;
}
.mx_RoomHeader_settingsButton {
display: inline-block;
position: relative;
bottom: 10px;
left: 4px;
}
.mx_RoomHeader_settingsButton object {
pointer-events: none;
}
.mx_RoomHeader_name,
.mx_RoomHeader_avatar,
.mx_RoomHeader_avatarPicker,
.mx_RoomHeader_avatarPicker_edit {
cursor: pointer;
}
.mx_RoomHeader_name:hover div:not(.mx_RoomHeader_editable) {
color: #76cfa6;
}
.mx_RoomHeader_leaveButton {
margin-top: -1px;
}
.mx_RoomHeader_placeholder {
color: #a2a2a2 ! important;
}
.mx_RoomHeader_editable {
border-bottom: 1px solid #c7c7c7 ! important;
min-width: 150px;
cursor: text;
}
.mx_RoomHeader_editable:focus {
border-bottom: 1px solid #76CFA6 ! important;
outline: none;
box-shadow: none;
}
.mx_RoomHeader_topic {
vertical-align: bottom;
float: left;
max-height: 42px;
color: #A2A2A2;
font-weight: 300;
font-size: 13px;
margin-left: 19px;
margin-right: 16px;
overflow: hidden;
text-overflow: ellipsis;
border-bottom: 1px solid transparent;
}
.mx_RoomHeader_avatar {
display: table-cell;
width: 48px;
height: 50px;
vertical-align: middle;
}
.mx_RoomHeader_avatar .mx_BaseAvatar_image {
object-fit: cover;
}
.mx_RoomHeader_avatarPicker_edit {
position: absolute;
margin-left: 16px;
margin-top: 4px;
}
.mx_RoomHeader_avatarPicker_edit > label {
cursor: pointer;
}
.mx_RoomHeader_avatarPicker_edit > input {
display: none;
}
.mx_RoomHeader_button {
display: table-cell;
vertical-align: top;
padding-left: 8px;
padding-right: 8px;
cursor: pointer;
}
.mx_RoomHeader_button object {
pointer-events: none;
}
.mx_RoomHeader_voipButton {
display: table-cell;
}
.mx_RoomHeader_voipButtons {
margin-top: 18px;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,14 +14,22 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_RoomDropTarget {
font-size: 14px;
text-align: center;
margin-left: 8px;
margin-right: 8px;
padding-top: 16px;
padding-bottom: 16px;
background-color: #fbfbfb;
border: 1px dashed #d7d7d7;
border-radius: 8px;
.mx_RoomList {
padding-top: 8px;
padding-bottom: 12px;
min-height: 400px;
}
.mx_RoomList_expandButton {
margin-left: 8px;
cursor: pointer;
padding-left: 12px;
padding-right: 12px;
}
/* Evil hacky override until Chrome fixes drop and drag table cells
and we can correctly fix horizontal wrapping in the sidebar again */
.mx_RoomList_scrollbar .gm-scroll-view {
overflow-x: hidden ! important;
overflow-y: scroll ! important;
}

View File

@@ -0,0 +1,68 @@
/*
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_RoomPreviewBar {
text-align: center;
height: 176px;
-webkit-align-items: center;
align-items: center;
flex-direction: column;
-webkit-flex-direction: column;
justify-content: center;
-webkit-justify-content: center;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
.mx_RoomPreviewBar_wrapper {
}
.mx_RoomPreviewBar_invite_text {
color: #454545;
}
.mx_RoomPreviewBar_join_text {
color: #ff0064;
}
.mx_RoomPreviewBar_preview_text {
margin-top: 25px;
color: #a4a4a4;
}
.mx_RoomPreviewBar_join_text a {
text-decoration: underline;
cursor: pointer;
}
.mx_RoomPreviewBar_warning {
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
padding: 8px;
}
.mx_RoomPreviewBar_warningIcon {
padding: 12px;
}

View File

@@ -0,0 +1,187 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_RoomSettings {
margin-left: 65px;
margin-bottom: 20px;
}
.mx_RoomSettings_powerLevels {
display: table;
}
.mx_RoomSettings_powerLevel {
display: table-row;
}
.mx_RoomSettings_powerLevelKey,
.mx_RoomSettings_powerLevel .mx_PowerSelector {
display: table-cell;
padding-bottom: 5px;
}
.mx_RoomSettings_powerLevelKey {
text-align: right;
padding-right: 0.3em;
}
.mx_RoomSettings h3 {
text-transform: uppercase;
color: #3d3b39;
font-weight: 600;
font-size: 13px;
margin-top: 36px;
margin-bottom: 10px;
}
.mx_RoomSettings .mx_RoomSettings_toggles label {
margin-bottom: 8px;
display: block;
}
.mx_RoomSettings .mx_RoomSettings_toggles input[type="checkbox"],
.mx_RoomSettings .mx_RoomSettings_toggles input[type="radio"] {
margin-right: 7px;
}
.mx_RoomSettings .mx_RoomSettings_tags input[type="checkbox"] {
margin-left: 1em;
margin-right: 7px;
}
.mx_RoomSettings .mx_RoomSettings_tags {
margin-bottom: 8px;
}
.mx_RoomSettings .mx_RoomSettings_roomColor {
display: inline-block;
position: relative;
width: 37px;
height: 37px;
border: 1px solid #979797;
margin-right: 13px;
}
.mx_RoomSettings .mx_RoomSettings_roomColor_selected {
position: absolute;
left: 10px;
top: 4px;
}
.mx_RoomSettings .mx_RoomSettings_roomColorPrimary {
height: 10px;
position: absolute;
bottom: 0px;
width: 100%;
}
.mx_RoomSettings .mx_RoomSettings_aliasLabel {
margin-bottom: 8px;
}
.mx_RoomSettings .mx_RoomSettings_aliasesTable {
margin-top: 12px;
margin-bottom: 0px;
margin-left: 56px;
display: table;
}
.mx_RoomSettings .mx_RoomSettings_aliasesTableRow {
display: table-row;
margin-bottom: 16px;
}
.mx_RoomSettings .mx_RoomSettings_alias {
max-width: 400px;
margin-bottom: 16px;
/*
commented out so margin applies
display: table-cell; */
}
.mx_RoomSettings .mx_RoomSettings_addAlias,
.mx_RoomSettings .mx_RoomSettings_deleteAlias {
display: table-cell;
padding-left: 0.5em;
position: relative;
cursor: pointer;
}
.mx_RoomSettings .mx_RoomSettings_addAlias img,
.mx_RoomSettings .mx_RoomSettings_deleteAlias img {
visibility: hidden;
}
.mx_RoomSettings .mx_RoomSettings_aliasesTableRow:hover .mx_RoomSettings_addAlias img,
.mx_RoomSettings .mx_RoomSettings_aliasesTableRow:hover .mx_RoomSettings_deleteAlias img {
visibility: visible;
}
.mx_RoomSettings_warning {
color: #ff0064;
font-weight: bold;
margin-top: 8px;
margin-bottom: 8px;
}
.mx_RoomSettings_editable {
border: 0px;
border-bottom: 1px solid #c7c7c7;
padding: 0px;
min-width: 240px;
}
.mx_RoomSettings_editable:focus {
border-bottom: 1px solid #76CFA6;
outline: none;
box-shadow: none;
}
.mx_RoomSettings_deleteAlias,
.mx_RoomSettings_addAlias {
display: table-cell;
visibility: visible;
}
.mx_RoomSettings_deleteAlias:hover,
.mx_RoomSettings_addAlias:hover {
visibility: visible;
}
.mx_RoomSettings_aliasPlaceholder {
color: #a2a2a2;
}
.mx_RoomSettings_buttons {
text-align: right;
margin-bottom: 16px;
}
.mx_RoomSettings_button {
display: inline;
border: 0px;
height: 36px;
border-radius: 36px;
font-weight: 400;
font-size: 15px;
color: #fff;
background-color: #76cfa6;
width: auto;
margin: auto;
padding: 6px;
padding-left: 1em;
padding-right: 1em;
}

View File

@@ -0,0 +1,132 @@
/*
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_RoomTile {
cursor: pointer;
/* This fixes wrapping of long room names, but breaks drag & drop previews */
/* display: table-row; */
font-size: 13px;
position: relative;
}
.mx_RoomTile_avatar {
display: table-cell;
padding-right: 11px;
padding-top: 6px;
padding-bottom: 6px;
padding-left: 18px;
width: 24px;
height: 24px;
position: relative;
vertical-align: middle;
}
.mx_RoomTile_name {
display: table-cell;
width: 100%;
vertical-align: middle;
overflow: hidden;
word-break: break-word;
padding-right: 15px;
color: rgba(69, 69, 69, 0.8);
}
.mx_RoomTile_ellipsis .mx_RoomTile_name {
font-style: italic;
color: #454545;
}
.mx_RoomTile_invite {
/* color: rgba(69, 69, 69, 0.5);
*/
}
.collapsed .mx_RoomTile_name {
display: none;
}
.collapsed .mx_RoomTile_badge {
margin-top: -15px;
right: 7px;
}
.mx_RoomTile_badge {
min-width: 12px;
height: 16px;
position: absolute;
right: 16px;
top: 50%;
margin-top: -8px;
border-radius: 16px;
color: #fff;
font-weight: bold;
font-size: 11px;
text-align: center;
padding: 0px 4px 0px 4px;
}
.mx_RoomTile_unreadNotify .mx_RoomTile_badge {
background-color: #76cfa6;
}
.mx_RoomTile_highlight .mx_RoomTile_badge {
background-color: #ff0064;
}
.mx_RoomTile_unread,
.mx_RoomTile_highlight {
font-weight: bold;
}
/* 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;
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_arrow {
position: absolute;
right: 0px;
}
.mx_RoomTile:hover {
}

View File

@@ -0,0 +1,81 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_SearchableEntityList {
display: flex;
display: -webkit-flex;
flex-direction: column;
-webkit-flex-direction: column;
}
.mx_SearchableEntityList_query {
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
border-radius: 3px;
border: 1px solid #f0f0f0;
padding: 9px;
color: #454545;
background-color: #fff;
margin-left: 3px;
font-size: 15px;
margin-bottom: 8px;
width: 189px;
}
.mx_SearchableEntityList_query::-moz-placeholder {
color: #454545;
opacity: 0.5;
font-size: 12px;
}
.mx_SearchableEntityList_query::-webkit-input-placeholder {
color: #454545;
opacity: 0.5;
font-size: 12px;
}
.mx_SearchableEntityList_listWrapper {
flex: 1;
-webkit-flex: 1;
overflow-y: auto;
}
.mx_SearchableEntityList_list {
display: table;
table-layout: fixed;
width: 100%;
}
.mx_SearchableEntityList_list .mx_EntityTile_chevron {
display: none;
}
.mx_SearchableEntityList_hrWrapper {
width: 100%;
flex: 0 0 auto;
-webkit-flex: 0 0 auto;
}
.mx_SearchableEntityList hr {
height: 1px;
border: 0px;
color: #e1dddd;
background-color: #e1dddd;
margin-right: 15px;
margin-top: 11px;
margin-bottom: 11px;
}

View File

@@ -0,0 +1,54 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_TabCompleteBar {
overflow: hidden;
}
.mx_TabCompleteBar_item {
display: inline-block;
margin-right: 15px;
margin-bottom: 2px;
cursor: pointer;
}
.mx_TabCompleteBar_command {
margin-right: 8px;
background-color: #76CFA6;
padding-left: 8px;
padding-right: 8px;
padding-top: 2px;
padding-bottom: 2px;
margin-bottom: 6px;
border-radius: 30px;
}
.mx_TabCompleteBar_command .mx_TabCompleteBar_text {
opacity: 1.0;
vertical-align: initial;
color: #fff;
}
.mx_TabCompleteBar_item img {
margin-right: 8px;
vertical-align: middle;
}
.mx_TabCompleteBar_text {
color: #4a4a4a;
vertical-align: middle;
opacity: 0.5;
}

View File

@@ -0,0 +1,45 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_TopUnreadMessagesBar {
margin: auto; /* centre horizontally */
max-width: 960px;
padding-top: 5px;
padding-bottom: 5px;
border-bottom: 1px solid #e5e5e5;
}
.mx_TopUnreadMessagesBar_scrollUp {
display: inline;
cursor: pointer;
}
.mx_TopUnreadMessagesBar_scrollUp img {
padding-left: 10px;
padding-right: 31px;
vertical-align: middle;
}
.mx_TopUnreadMessagesBar_scrollUp span {
opacity: 0.5;
}
.mx_TopUnreadMessagesBar_close {
float: right;
padding-right: 14px;
padding-top: 3px;
cursor: pointer;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,14 +16,15 @@ limitations under the License.
.mx_IncomingCallBox {
text-align: center;
border: 1px solid #a9dbf4;
border: 1px solid #a4a4a4;
border-radius: 8px;
background-color: #fff;
position: absolute;
position: fixed;
z-index: 1000;
left: 235px;
top: 155px;
padding: 6px;
margin-top: -3px;
margin-left: -20px;
width: 200px;
}
.mx_IncomingCallBox_chevron {
@@ -39,14 +40,15 @@ limitations under the License.
}
.mx_IncomingCallBox_buttons {
display: table-row;
display: flex;
display: -webkit-flex;
}
.mx_IncomingCallBox_buttons_cell {
vertical-align: middle;
display: table-cell;
padding: 6px;
width: 50%;
flex: 1;
-webkit-flex: 1;
}
.mx_IncomingCallBox_buttons_decline,
@@ -57,6 +59,7 @@ limitations under the License.
line-height: 36px;
border-radius: 36px;
color: #fff;
margin: auto;
}
.mx_IncomingCallBox_buttons_decline {

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -31,9 +31,15 @@ limitations under the License.
}
.mx_VideoView_localVideoFeed {
width: 20%;
width: 25%;
height: 25%;
position: absolute;
left: 16px;
bottom: 28px;
left: 10px;
bottom: 10px;
z-index: 100;
}
.mx_VideoView_localVideoFeed video {
width: auto;
height: 100%;
}

View File

@@ -1,112 +0,0 @@
/*
Copyright 2015 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_EventTile {
max-width: 100%;
clear: both;
margin-top: 32px;
margin-left: 56px;
}
.mx_EventTile_avatar {
padding-left: 12px;
padding-right: 12px;
margin-left: -64px;
margin-top: -7px;
float: left;
}
.mx_EventTile_avatar img {
background-color: #dbdbdb;
border-radius: 20px;
border: 0px;
}
.mx_EventTile_continuation {
margin-top: 8px ! important;
}
.mx_EventTile .mx_SenderProfile {
color: #454545;
opacity: 0.5;
font-size: 14px;
margin-bottom: 4px;
display: block;
}
.mx_EventTile .mx_MessageTimestamp {
color: #454545;
opacity: 0.5;
font-size: 14px;
float: right;
}
.mx_EventTile_content {
padding-right: 100px;
display: block;
}
.mx_EventTile_notice .mx_MessageTile_content {
opacity: 0.5;
}
.mx_EventTile_sending {
color: #ddd;
}
.mx_EventTile_notSent {
color: #f11;
}
.mx_EventTile_highlight {
color: #FF0064;
}
.mx_EventTile_msgOption {
float: right;
}
.mx_MessageTimestamp {
display: none;
}
.mx_EventTile_last .mx_MessageTimestamp {
display: block;
}
.mx_EventTile:hover .mx_MessageTimestamp {
display: block;
}
.mx_EventTile_editButton {
float: right;
display: none;
border: 0px;
outline: none;
margin-right: 3px;
}
.mx_EventTile:hover .mx_EventTile_editButton {
display: inline-block;
}
.mx_EventTile.menu .mx_EventTile_editButton {
display: inline-block;
}
.mx_EventTile.menu .mx_MessageTimestamp {
display: inline-block;
}

View File

@@ -1,134 +0,0 @@
/*
Copyright 2015 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_MemberTile {
display: table-row;
height: 49px;
position: relative;
}
.mx_MemberTile_avatar {
display: table-cell;
padding-left: 14px;
padding-right: 12px;
padding-top: 3px;
padding-bottom: 3px;
vertical-align: middle;
width: 40px;
height: 40px;
position: relative;
}
.mx_MemberTile_inviteTile {
cursor: pointer;
}
.mx_MemberTile_inviteEditing {
display: initial ! important;
}
.mx_MemberTile_inviteEditing .mx_MemberTile_avatar {
display: none;
}
.mx_MemberTile_inviteEditing .mx_MemberTile_name {
width: 200px;
}
.mx_MemberTile_inviteEditing .mx_MemberTile_name input {
border-radius: 3px;
border: 1px solid #c7c7c7;
font-weight: 300;
font-size: 14px;
padding: 9px;
margin-top: 6px;
margin-left: 14px;
}
.mx_MemberTile_power {
position: absolute;
width: 48px;
height: 48px;
left: 10px;
top: -1px;
}
.mx_MemberTile_name {
display: table-cell;
vertical-align: middle;
overflow: hidden;
text-overflow: ellipsis;
}
.mx_MemberTile_details {
display: table-cell;
padding-right: 14px;
vertical-align: middle;
}
.mx_MemberTile_hover {
background-color: #f0f0f0;
font-size: 12px;
color: #747474;
}
.mx_MemberTile_userId {
font-weight: bold;
overflow: hidden;
text-overflow: ellipsis;
}
.mx_MemberTile_leave {
cursor: pointer;
margin-top: 8px;
margin-right: -4px;
margin-left: 6px;
float: right;
}
/*
.mx_MemberTile_nameWrapper {
display: table-cell;
vertical-align: middle;
overflow: hidden;
text-overflow: ellipsis;
}
.mx_MemberTile_nameSpan {
}
*/
.mx_MemberTile_unavailable .mx_MemberTile_avatar,
.mx_MemberTile_unavailable .mx_MemberTile_name,
.mx_MemberTile_unavailable .mx_MemberTile_nameSpan
{
opacity: 0.66;
}
.mx_MemberTile_offline .mx_MemberTile_avatar,
.mx_MemberTile_offline .mx_MemberTile_name,
.mx_MemberTile_offline .mx_MemberTile_nameSpan
{
opacity: 0.25;
}
.mx_MemberTile_zalgo {
font-family: Helvetica, Arial, Sans-Serif;
}
.mx_MemberTile:hover .mx_MessageTimestamp {
display: block;
}

View File

@@ -1,173 +0,0 @@
/*
Copyright 2015 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_RoomHeader {
}
.mx_RoomHeader_wrapper {
max-width: 720px;
margin: auto;
height: 88px;
border-bottom: 1px solid #a8dbf3;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
.mx_RoomHeader_leftRow {
height: 48px;
margin-top: 18px;
-webkit-box-ordinal-group: 1;
-moz-box-ordinal-group: 1;
-ms-flex-order: 1;
-webkit-order: 1;
order: 1;
-webkit-flex: 1;
flex: 1;
}
.mx_RoomHeader_textButton {
height: 48px;
margin-top: 18px;
background-color: #80cef4;
border-radius: 48px;
margin-right: 8px;
color: #fff;
line-height: 48px;
text-align: center;
-webkit-box-ordinal-group: 2;
-moz-box-ordinal-group: 2;
-ms-flex-order: 2;
-webkit-order: 2;
order: 2;
cursor: pointer;
/*
-webkit-flex: 0 0 90px;
flex: 0 0 90px;
*/
padding-left: 12px;
padding-right: 12px;
}
.mx_RoomHeader_rightRow {
height: 48px;
margin-top: 18px;
background-color: #fff;
border-radius: 48px;
border: 1px solid #a9dbf4;
-webkit-box-ordinal-group: 3;
-moz-box-ordinal-group: 3;
-ms-flex-order: 3;
-webkit-order: 3;
order: 3;
}
.mx_RoomHeader_info {
display: table-cell;
height: 48px;
vertical-align: middle;
}
.mx_RoomHeader_simpleHeader {
line-height: 88px;
color: #80cef4;
font-weight: 400;
font-size: 20px;
overflow: hidden;
text-overflow: ellipsis;
}
.mx_RoomHeader_name {
vertical-align: middle;
height: 28px;
color: #80cef4;
font-weight: 400;
font-size: 20px;
padding-left: 16px;
padding-right: 16px;
text-overflow: ellipsis;
}
.mx_RoomHeader_nameEditing {
padding-left: 16px;
padding-right: 16px;
margin-top: -5px;
}
.mx_RoomHeader_name input, .mx_RoomHeader_nameInput {
border-radius: 3px;
width: 260px;
border: 1px solid #c7c7c7;
font-weight: 300;
font-size: 14px;
padding: 9px;
}
.mx_RoomHeader_nameInput {
margin-top: 6px;
}
.mx_RoomHeader_topic {
vertical-align: bottom;
float: left;
max-height: 38px;
color: #70b5d7;
font-weight: 300;
padding-left: 16px;
padding-right: 16px;
overflow: hidden;
text-overflow: ellipsis;
}
.mx_RoomHeader_avatar {
display: table-cell;
width: 48px;
height: 50px;
vertical-align: middle;
}
.mx_RoomHeader_avatar img {
border-radius: 24px;
}
.mx_RoomHeader_button {
height: 48px;
display: table-cell;
vertical-align: middle;
padding-left: 8px;
padding-right: 8px;
}
.mx_RoomHeader_button img {
cursor: pointer;
}
.mx_RoomHeader_voipButton {
display: table-cell;
}
.mx_RoomHeader_voipButtons {
margin-top: 18px;
}

View File

@@ -1,70 +0,0 @@
/*
Copyright 2015 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_RoomSettings {
max-height: 250px;
padding-top: 12px;
}
.mx_RoomSettings_settings {
display: table;
margin: 5px 0;
}
.mx_RoomSettings_settings > div {
display: table-row;
}
.mx_RoomSettings_settings > div > * {
display: table-cell;
margin: 0 10px;
}
.mx_RoomSettings input,
.mx_RoomSettings textarea {
border-radius: 3px;
border: 1px solid #c7c7c7;
font-weight: 300;
font-size: 14px;
padding: 9px;
margin-top: 6px;
}
.mx_RoomSettings_description {
width: 330px;
}
.mx_RoomSettings_buttons {
text-align: right;
margin-bottom: 16px;
}
.mx_RoomSettings_button {
display: inline;
border: 0px;
height: 36px;
border-radius: 36px;
font-weight: 400;
font-size: 16px;
color: #fff;
background-color: #80cef4;
width: auto;
margin: auto;
padding: 6px;
padding-left: 1em;
padding-right: 1em;
}

View File

@@ -1,104 +0,0 @@
/*
Copyright 2015 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_RoomTile {
cursor: pointer;
display: table-row;
color: #818794;
}
.mx_RoomTile_avatar {
display: table-cell;
padding-right: 10px;
padding-top: 3px;
padding-bottom: 3px;
padding-left: 10px;
vertical-align: middle;
width: 36px;
height: 36px;
position: relative;
}
.mx_RoomTile_avatar img {
border-radius: 20px;
background-color: #dbdbdb;
}
.mx_RoomTile_name {
display: table-cell;
vertical-align: middle;
overflow: hidden;
text-overflow: ellipsis;
padding-right: 16px;
}
.collapsed .mx_RoomTile_name {
display: none;
}
/*
.mx_RoomTile_nameBadge {
display: table;
width: 100%;
height: 50px;
}
.mx_RoomTile_badgeCell {
display: table-cell;
vertical-align: middle;
width: 26px;
}
.mx_RoomTile_badge {
background-color: #80cef4;
color: #fff;
border-radius: 26px;
font-weight: 400;
font-size: 14px;
line-height: 28px;
width: 26px;
height: 26px;
text-align: center;
}
*/
.mx_RoomTile_badge {
background-color: #ff0064;
border: 3px solid #fff;
border-radius: 16px;
width: 9px;
height: 9px;
position: absolute;
right: 9px;
bottom: 3px;
}
.mx_RoomTile_unread,
.mx_RoomTile_highlight,
.mx_RoomTile_invited
{
font-weight: bold;
color: #000;
}
.mx_RoomTile_selected {
background-color: #f3f8fa;
color: #80cef4;
font-weight: bold;
}
.mx_RoomTile:hover {
}

View File

@@ -1,3 +0,0 @@
.mx_ViewSource pre {
text-align: left;
}

View File

@@ -0,0 +1,19 @@
.mx_CompatibilityPage {
width: 100%;
height: 100%;
background-color: #e55;
}
.mx_CompatibilityPage_box {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
width: 500px;
height: 300px;
border: 1px solid;
padding: 10px;
background-color: #fcc;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -34,16 +34,21 @@ limitations under the License.
cursor: pointer;
}
.mx_LeftPanel .mx_RoomList {
.mx_LeftPanel_callView {
}
.mx_LeftPanel .mx_RoomList_scrollbar {
-webkit-box-ordinal-group: 1;
-moz-box-ordinal-group: 1;
-ms-flex-order: 1;
-webkit-order: 1;
order: 1;
overflow-y: auto;
-webkit-flex: 1 1 0;
flex: 1 1 0;
overflow-y: auto;
}
.mx_LeftPanel .mx_BottomLeftMenu {
@@ -53,17 +58,40 @@ limitations under the License.
-webkit-order: 3;
order: 3;
-webkit-flex: 0 0 170px;
flex: 0 0 170px;
border-top: 1px solid #f3f8fa;
border-top: 1px solid rgba(0, 0, 0, 0.1);
margin-left: 18px;
margin-right: 18px;
-webkit-flex: 0 0 60px;
flex: 0 0 60px;
}
.mx_LeftPanel .mx_BottomLeftMenu .mx_RoomTile {
color: #378bb4;
.mx_LeftPanel .mx_BottomLeftMenu_options {
margin-top: 18px;
}
.mx_LeftPanel .mx_BottomLeftMenu .mx_BottomLeftMenu_options {
margin-top: 12px;
width: 100%;
}
.mx_BottomLeftMenu_options object {
pointer-events: none;
}
.mx_LeftPanel .mx_BottomLeftMenu_createRoom,
.mx_LeftPanel .mx_BottomLeftMenu_directory,
.mx_LeftPanel .mx_BottomLeftMenu_settings {
display: inline-block;
cursor: pointer;
}
.collapsed .mx_BottomLeftMenu_createRoom,
.collapsed .mx_BottomLeftMenu_directory,
.collapsed .mx_BottomLeftMenu_settings {
margin-left: 0px ! important;
padding-top: 3px ! important;
padding-bottom: 3px ! important;
}
.mx_LeftPanel .mx_BottomLeftMenu_directory {
margin-left: 10px;
}
.mx_LeftPanel .mx_BottomLeftMenu_settings {
float: right;
}

Some files were not shown because too many files have changed in this diff Show More