Compare commits

...

866 Commits

Author SHA1 Message Date
David Baker 59fe9279d1 0.8.3 2016-10-12 11:49:58 +01:00
David Baker 046c9ef920 Prepare changelog for v0.8.3 2016-10-12 11:49:57 +01:00
David Baker bca22f26c5 js-sdk & react-sdk release versions 2016-10-12 11:49:21 +01:00
Richard van der Hoff 2b68b88b14 Merge pull request #2453 from vector-im/rav/center_images_in_dialog_buttons
Centre images in dialog buttons
2016-10-11 19:09:46 +01:00
Richard van der Hoff 97cedfc712 Centre images in dialog buttons
Some dialogs put a spinner in the button... need to line them up.
2016-10-11 17:50:49 +01:00
Matthew Hodgson 86cb3e9376 Merge pull request #2448 from aviraldg/fix-quote
Only show quote option if RTE is enabled
2016-10-11 14:39:42 +01:00
Aviral Dasgupta 42993a78ed Only show quote option if RTE is enabled 2016-10-11 19:07:15 +05:30
Richard van der Hoff 2a5ca9d3df Merge pull request #2443 from vector-im/dbkr/matrix_network_join_button
Fix join button for 'matrix' networks
2016-10-10 11:40:32 +01:00
David Baker 323bd79d0e Fix join button for 'matrix' networks
Fixes https://github.com/vector-im/vector-web/issues/2435
2016-10-10 11:21:20 +01:00
Matthew Hodgson 60adbffacf try to fix the create room label 2016-10-10 02:38:38 +01:00
Richard van der Hoff f827a2963e Merge pull request #2422 from vector-im/dbkr/fix_no_freenode_rooms
Don't stop paginating if no rooms match
2016-10-06 10:39:45 +01:00
David Baker 5e293c0f45 Don't stop paginating if no rooms match
Always show the scrollpanel otherwise we stop paginating if there
are no matching rooms in the first request (as per comment).

Fixes no freenode rooms being shown.
2016-10-05 18:06:43 +01:00
David Baker cd7adfed0a Back to develop react & js sdk 2016-10-05 16:59:25 +01:00
David Baker 902bf3a0a6 0.8.2 2016-10-05 16:55:45 +01:00
David Baker f736e5243c Prepare changelog for v0.8.2 2016-10-05 16:55:44 +01:00
David Baker fb2c2ed09a Use released version of react-sdk & js-sdk 2016-10-05 16:54:24 +01:00
David Baker ea38968be9 Merge pull request #2379 from vector-im/dbkr/join_3p_location
Add native joining of 3p networks to room dir
2016-10-05 14:00:21 +01:00
David Baker 562b047362 Typo 2016-10-05 13:49:30 +01:00
David Baker 381c9009fb Doc roomDirectory config section 2016-10-04 16:21:39 +01:00
David Baker c0a4574069 For single instance, allow domain present & match 2016-10-04 15:30:46 +01:00
David Baker de9bf4bb47 Actually use variable 2016-10-04 15:18:07 +01:00
Richard van der Hoff c57bfccb9e Merge pull request #2406 from vector-im/dbkr/linkify_213
Update to linkify 2.1.3
2016-10-04 11:59:07 +01:00
David Baker 52cae92dd7 Update to linkify 2.1.3
To pull in https://github.com/SoapBox/linkifyjs/pull/166
2016-10-04 11:28:28 +01:00
David Baker b80b08f04f Specify width on icons & comment 2016-10-04 11:14:36 +01:00
David Baker 304e5b997a PR Freedback 2016-10-04 11:04:01 +01:00
David Baker 6b4dbfbd62 Change default brand to Riot
& update sample config
2016-10-04 10:23:38 +01:00
David Baker 000ca35727 Don't pop up errors when this API fails for guests 2016-10-03 16:30:57 +01:00
David Baker 776fe2ad70 Different way of getting fields for 3p location
Try to match protocol insance from 'domain' field and use its
fields for all but the last field. Assume the last takes the user
input.
2016-10-03 13:42:55 +01:00
Richard van der Hoff 602727b7ad Merge pull request #2383 from vector-im/dbkr/sign_in_not_log_in
Use 'Sign In' / 'Sign Out' universally
2016-09-30 11:31:15 +01:00
Richard van der Hoff 56deea9f10 Merge pull request #2382 from vector-im/dbkr/networkdropdown_size_jump
Prevent network dropdown resizing slightly
2016-09-30 10:59:15 +01:00
Richard van der Hoff 8e0be29c13 Merge pull request #2380 from vector-im/dbkr/roomdir_no_results
Room directory: indicate when there are no results
2016-09-30 10:23:23 +01:00
David Baker b71b1b5535 Use more variables 2016-09-30 09:39:30 +01:00
Matthew Hodgson 5b3524f174 better wordwrap on RightPanels 2016-09-29 17:41:34 +01:00
David Baker f9a70a8b04 Use 'Sign In' / 'Sign Out' universally
Rather than a mix of 'sign in/out' and 'log in/out'
2016-09-29 17:40:19 +01:00
David Baker b652ea5024 Prevent network dropdown resizing slightly
Dropdown resized by 2px when opened
2016-09-29 16:49:44 +01:00
David Baker 2a37a0cb19 Room directory: indicate when there are no results
Fixes https://github.com/vector-im/vector-web/issues/2250
2016-09-29 15:45:45 +01:00
David Baker 761600f325 Add native joining of 3p networks to room dir
Use the 3rd party location lookup API to accept third-party locations
in their native form and look up the corresponding portal room for
that location.

Also give the network dropdown some placeholder text.

Fixes https://github.com/vector-im/vector-web/issues/2374
2016-09-29 15:30:54 +01:00
David Baker 65f14c7d21 Stop random rooms appearing when switching network
in the public room directory
2016-09-28 14:18:40 +01:00
David Baker 864ba52bc5 Relative img paths please 2016-09-28 12:03:35 +01:00
David Baker fdb5020c0c Oops, fix undefined variable 2016-09-28 11:56:07 +01:00
Richard van der Hoff 62344b5194 Merge pull request #2362 from vector-im/dbkr/roomdir_filter_3pnetworks
Room dir: New filtering & 3rd party networks
2016-09-28 11:38:03 +01:00
David Baker 0db12fcd22 Move method & don't wastefullt create elements
Put did update with the other react interface methods & don't
bother creating the 'current_value' if we throw it away later.
2016-09-28 11:05:14 +01:00
David Baker 455ee4f91b Argh, tabs 2016-09-28 11:04:54 +01:00
David Baker 5ca391f914 Replace double truth test with something sane
Also typo
2016-09-28 11:04:13 +01:00
David Baker a32abae5a3 Don't use _matrix as default if there isn't one 2016-09-28 10:58:01 +01:00
David Baker b2dd3ecf3a Add the _matrix network to the sample config 2016-09-28 10:44:29 +01:00
David Baker cc7017b62d Emptry commit to force re-test 2016-09-28 10:22:29 +01:00
David Baker f852e8a01d Update sample config 2016-09-28 10:13:35 +01:00
David Baker 6ff1c30a4b Fix spurious fill requests when switching networks
Ignore responses for old servers too, don't trigger a backfill request
when we re-render before refresh. Also a few more comments.
2016-09-28 10:08:03 +01:00
David Baker 85ea45a64a Room dir: New filtering & 3rd party networks
Changes filtering on 3rd party networks to divide into portal / non portal rooms and not show portal rooms by default. Adds a special '_matrix' network for all rooms that aren't portal rooms.

Also adds ability to query 3rd party directory servers.
2016-09-27 19:39:20 +01:00
Matthew Hodgson 7b258bc229 it's called Riot 2016-09-27 12:27:12 +01:00
Richard van der Hoff 5ba3499f56 Merge pull request #2359 from vector-im/dbkr/linkify_version
Update linkify version
2016-09-27 11:30:16 +01:00
David Baker f4a6a3c4b2 Update linkify version
Fixes https://github.com/vector-im/vector-web/issues/2357
In addition, https://github.com/matrix-org/matrix-react-sdk/pull/500 will make sure failures like this are obvious.
2016-09-27 10:40:02 +01:00
David Baker 5967dc4983 Merge pull request #2339 from vector-im/dbkr/directory_search_box
Directory search join button
2016-09-26 15:43:39 +01:00
David Baker bf58c340bc Oops, missed the ref 2016-09-26 15:30:42 +01:00
David Baker dc0b15bdfa Remove unused variable / function 2016-09-26 14:17:36 +01:00
Matthew Hodgson be6fbc2432 let's stick with the vector-web GA target for riot-web 2016-09-25 13:24:07 +01:00
David Baker 51a5542446 Make tests pass 2016-09-23 18:20:31 +01:00
David Baker 3938abc5dd add webkit vendor prefixed properties
for mavericks safari
2016-09-23 17:18:52 +01:00
David Baker 4961a97ed4 More css:
* Make join button more buttony
 * Fix size of dropdown, allow search box to expand
 * Use flexbox within search box to input can fill the rest of the space
2016-09-23 16:33:28 +01:00
David Baker fb477fad1e Less hardcoded CSS 2016-09-23 15:58:28 +01:00
David Baker a070bccffb Hacky hardcoded css for join button 2016-09-23 15:26:08 +01:00
David Baker 8e1105b12a Oops, wrong function 2016-09-23 15:25:13 +01:00
David Baker 93e4a04118 Chrome manifest branding 2016-09-23 14:26:09 +01:00
David Baker 6e3313b461 More missed rebranding 2016-09-23 14:24:47 +01:00
David Baker 2e77b0a3c7 Use directory search box component 2016-09-23 13:48:44 +01:00
David Baker 16c22e07b8 Missed some mstile icons 2016-09-23 13:46:46 +01:00
David Baker 99b0f9eb7c Back to develop 2016-09-21 17:33:27 +01:00
David Baker 5248bdd974 0.8.1 2016-09-21 17:30:41 +01:00
David Baker 157ae836c0 Prepare changelog for v0.8.1 2016-09-21 17:30:40 +01:00
David Baker 2639d10f97 Pin to released js-sdk & react-sdk 2016-09-21 17:29:44 +01:00
David Baker cc5c636fa5 Back to develop versions 2016-09-21 12:03:59 +01:00
David Baker c4a2df75eb 0.8.0 2016-09-21 12:02:41 +01:00
David Baker 06c4cae016 Prepare changelog for v0.8.0 2016-09-21 12:02:41 +01:00
David Baker 3eed711b34 Use released versions 2016-09-21 12:01:59 +01:00
David Baker d9c51832ab Use 2x res logo to work with hidpi displays 2016-09-21 11:09:00 +01:00
David Baker 5011d3b158 Only show version bar if on develop
Or rather, if the version string is in the right format it to work.
2016-09-20 14:33:25 +01:00
David Baker c10b11a22c Separate GA tracking ID for riot 2016-09-19 17:46:54 +01:00
David Baker a5ee48d857 Swap out unknown user icons 2016-09-19 16:42:07 +01:00
David Baker 343fc1b164 Update GA hostnames 2016-09-19 16:22:42 +01:00
David Baker 55fde43d5d All the logos. 2016-09-19 15:52:39 +01:00
David Baker 940eaf2b7d The times, they are a changin' 2016-09-19 15:32:39 +01:00
David Baker 855ecbe11d Update twitter / blog 2016-09-19 15:18:49 +01:00
David Baker fc8f3eb0ee Just change favicon for now 2016-09-19 14:55:08 +01:00
David Baker df90921d6c More s/Vector/Riot/ 2016-09-19 14:50:17 +01:00
David Baker 0f2c41dddc Merge pull request #2285 from vector-im/dbkr/rebrand
Dbkr/rebrand
2016-09-19 13:37:02 +01:00
David Baker 1c76870dcf Remove failed commenting 2016-09-19 13:36:04 +01:00
David Baker a99c9f4db2 Keep order of blog / twitter the same 2016-09-19 13:35:31 +01:00
David Baker 7e5373e194 Stick with VectorCo twitter for now 2016-09-19 13:34:49 +01:00
David Baker 560174b99f Keep width on logo 2016-09-19 13:34:01 +01:00
David Baker d2947a637a Better. 2016-09-19 13:31:01 +01:00
David Baker 8e4dcd9b41 Rebrand 2016-09-19 13:29:49 +01:00
Matthew Hodgson 9391dc6c2a aargh 2016-09-19 07:41:32 -04:00
Matthew Hodgson f19044fef2 re-apply new scalar CSS 2016-09-19 06:59:24 -04:00
Kegsay 60179aab52 Merge pull request #2282 from vector-im/kegan/close-scalar
Listen for close_scalar and close the dialog box when received
2016-09-19 10:47:36 +01:00
Kegan Dougal de38a32969 Listen for close_scalar and close the dialog box when received 2016-09-19 10:37:19 +01:00
Kegsay 5f6cc9b37b Merge pull request #2281 from vector-im/revert-2280-matthew/scalar-lipstick
Revert "improve lipstick and support scalar logout"
2016-09-19 10:17:54 +01:00
Kegsay e2fc2b1b09 Revert "improve lipstick and support scalar logout" 2016-09-19 10:16:50 +01:00
Kegsay 1d97272874 Merge pull request #2280 from vector-im/matthew/scalar-lipstick
improve lipstick and support scalar logout
2016-09-19 09:27:07 +01:00
Richard van der Hoff 69da6a6dd8 Changelog test
empty commit to test the changelog
2016-09-19 00:14:19 +01:00
Richard van der Hoff 6cb7ffcd3b Another go at fixing the damn changelog
html_url is in the top-level 'commit' object, not in commit.commit.

Also factor some code out for legibility. Seriously, what's with stuffing
everything into inline functions?
2016-09-18 23:56:55 +01:00
Richard van der Hoff 0ab1dacb1e Merge remote-tracking branch 'origin/pull/2071/head' into rav/fix_changelog_links 2016-09-18 23:33:17 +01:00
Matthew Hodgson af230b5fa8 improve lipstick and support scalar logout 2016-09-18 02:57:15 +01:00
Matthew Hodgson 4720da3f8e Merge pull request #2241 from vector-im/dbkr/paginate_publicrooms
Paginate Room Directory
2016-09-17 15:46:21 +01:00
Matthew Hodgson e2b3fc3519 only show invite button for rooms you're in 2016-09-17 03:02:14 +01:00
Matthew Hodgson ab3c1509c5 switch to 3-digit formatting for counts 2016-09-17 02:39:31 +01:00
Matthew Hodgson 91dd029483 don't let guests invite 2016-09-17 02:05:01 +01:00
David Baker 53fd3f52fa Oops, onChange doesn't catch the enter key 2016-09-16 20:56:14 +01:00
David Baker d0618c4f49 Update test now that /publicRooms is a post 2016-09-16 20:49:28 +01:00
David Baker 0bce7f3102 Merge remote-tracking branch 'origin/develop' into dbkr/paginate_publicrooms 2016-09-16 20:16:33 +01:00
David Baker 3d97061d78 Check if we need to fetch more rooms after filter 2016-09-16 19:59:06 +01:00
David Baker 50f05db29e Don't show loading spinner if just paginating 2016-09-16 19:29:56 +01:00
David Baker 2fdec51a5b Wait a bit before sending filter requests
avoid hammering the server with requests for each keystroke
2016-09-16 18:53:18 +01:00
David Baker 6d332256b5 Ignore results of old requests 2016-09-16 18:48:47 +01:00
David Baker 2b6fbb038a Show headers while loading
& show spinner whilst waiting for filter requests
2016-09-16 18:41:29 +01:00
David Baker 48fb578952 Empty commit to test /develop redeploy 2016-09-16 18:31:47 +01:00
David Baker 7fc4b1cb35 Actually ad the arg to argparse 2016-09-16 18:26:46 +01:00
David Baker 4725fa4c2d Missed a comma 2016-09-16 18:21:33 +01:00
David Baker 5acb6b0b37 Merge pull request #2240 from vector-im/dbkr/redeploy_config
Make redeploy script symlink config
2016-09-16 18:19:34 +01:00
David Baker 838608afab Make redeploy script symlink config 2016-09-16 18:15:15 +01:00
David Baker a11516a984 Make publicrooms use the new paginating API
Also do filtering on the server

WIP: This breaks the network dropdown
2016-09-16 17:33:28 +01:00
Matthew Hodgson 196b352b9a Merge pull request #2210 from vector-im/markjh/megolm
Update the version of olm to 1.3.0
2016-09-16 17:30:51 +01:00
Richard van der Hoff e8a12e7ddc Revert "fix instructions"
This reverts commit 6a13155013.
2016-09-16 17:27:52 +01:00
David Baker 135c22c99d Merge pull request #2219 from vector-im/dbkr/directory_network_selector
Directory network selector
2016-09-16 17:09:23 +01:00
Matthew Hodgson 6a13155013 fix instructions 2016-09-16 17:08:27 +01:00
Matthew Hodgson 6e2a371017 fix MemberInfo layout 2016-09-16 14:36:26 +01:00
Matthew Hodgson de26d1a8ce Merge pull request #2235 from vector-im/wmwragg/two-state-sublist-headers
Wmwragg/two state sublist headers
2016-09-16 14:08:00 +01:00
wmwragg 7af765976b Notification counts now done correctly, as well as highlights 2016-09-16 13:25:39 +01:00
David Baker 8f6d98886c Use real matrix.org network in sample config 2016-09-16 11:44:33 +01:00
wmwragg 72e108c4f9 More robust badge positioning 2016-09-16 11:34:16 +01:00
wmwragg e2b695827e Refactor to reuse RoomSubList chevron styling 2016-09-16 11:02:09 +01:00
wmwragg 4b50a8a56e Refactored so the RoomSubList overflow element use RoomSubList CSS 2016-09-16 10:57:55 +01:00
wmwragg 737d1d8843 Changed the overflow tile styling, but there is no collpased state or mention count yet 2016-09-16 10:48:52 +01:00
Matthew Hodgson eea9e366b8 un-revert 5282796d84 as it wasn't to blame 2016-09-16 10:38:54 +01:00
wmwragg 24d0b95cb2 Corrected the tooltip text colour to match the design 2016-09-16 08:15:27 +01:00
wmwragg 77085882fa quick tidy of CSS 2016-09-16 08:08:31 +01:00
wmwragg 9375ebfb75 Fixed broken tooltip positioning again 2016-09-16 08:06:17 +01:00
Matthew Hodgson e2f94c8722 improve scroll cosmetics 2016-09-16 03:26:59 +01:00
Matthew Hodgson b0fd65f442 fix ff rhs scroll 2016-09-16 03:26:45 +01:00
Matthew Hodgson f56a6039e8 fix droptarget margins 2016-09-16 02:54:03 +01:00
Matthew Hodgson c44994c0ee fix tinter for LeftPanel 2016-09-16 02:53:57 +01:00
Matthew Hodgson eeb91374cf highlight my device 2016-09-15 19:42:36 +01:00
David Baker cd4564d3d3 Make the matrix.org section be everything
(ie. every alias on the matrix.org HS, so currently everything, since we don't pull in any other directories)
2016-09-15 18:56:04 +01:00
David Baker 190cd884b5 Add roomDirectory to sample config 2016-09-15 18:42:00 +01:00
Matthew Hodgson 1741cc915e revert accidental commit 5282796d84 as folks say everything broke 2016-09-15 17:50:47 +01:00
wmwragg 37fc73b1ea Setting correct initial state 2016-09-15 17:31:15 +01:00
David Baker c1e83da35d Put network list config into config file 2016-09-15 17:20:13 +01:00
wmwragg 5282796d84 Added back the overflow tile and two state room sub lists, rather than the three state currently 2016-09-15 17:17:45 +01:00
Matthew Hodgson 866164c4d9 Merge pull request #2222 from vector-im/wmwragg/correct-incoming-call-positioning
Wmwragg/correct incoming call positioning
2016-09-15 15:59:14 +01:00
wmwragg 5ceb1e641f Placing the incomingCallBox in the sticky element, so it sticks when the header sticks 2016-09-15 15:34:11 +01:00
David Baker f3cbb9fe90 Make the network dropdown work 2016-09-15 15:18:12 +01:00
Matthew Hodgson fe4371bf45 Merge pull request #2211 from vector-im/wmwragg/remove-old-filter
Wmwragg/remove old filter
2016-09-15 15:01:37 +01:00
wmwragg cde3f33db3 Added incomingCallBox to header and removed from roomTile 2016-09-15 14:37:53 +01:00
Matthew Hodgson 82e257b4ea make DM naming consistent 2016-09-15 13:23:17 +01:00
wmwragg 3907da064e Removed no longer used MultiInviteDialog, as it's now been replaced with the ChatInviteDialog 2016-09-15 11:46:35 +01:00
wmwragg f43530e1ef Tweaked font size to match the design spec 2016-09-15 11:39:21 +01:00
Mark Haines f6fb1561d7 Update the version of olm to 1.3.0 2016-09-15 11:33:37 +01:00
wmwragg a1e3ec1d19 Added query to CSS and removed nolonger used SearchableEntityList 2016-09-15 11:30:46 +01:00
David Baker 43b87e1f82 Add network selector that doesn't do anything yet 2016-09-15 11:29:27 +01:00
Matthew Hodgson 2a85b2271c tweak MemberInfo CSS 2016-09-15 02:44:34 +01:00
Matthew Hodgson cb2c2c1b36 basic verification UI 2016-09-15 01:55:59 +01:00
Matthew Hodgson c5a52d89be Merge pull request #2198 from vector-im/wmwragg/multi-invite-bugfix
Wmwragg/multi invite bugfix
2016-09-14 22:06:44 +01:00
wmwragg efa574c452 The invite group, will no longer be shown when the directory listing is being shown 2016-09-14 17:13:06 +01:00
wmwragg 66ef5213b8 Increased hitbox area to the whole invite section, not just the icon 2016-09-14 14:32:30 +01:00
wmwragg 370612135f The scrollbars are nolonger always visible for the AddressSelector and ChatInviteDialog invite list 2016-09-14 13:55:10 +01:00
Matthew Hodgson ec05d1b9bd improve e2e and scalar settings UI 2016-09-14 02:07:23 +01:00
Matthew Hodgson 089951012b actually, sod it, let's just call it Start chat 2016-09-13 19:42:35 +01:00
Matthew Hodgson c6a9614372 Merge pull request #2181 from vector-im/wmwragg/chat-multi-invite
Wmwragg/chat multi invite
2016-09-13 19:31:05 +01:00
Matthew Hodgson a623430c2b Merge pull request #2182 from vector-im/matthew/right-panel-collapse
shuffle bottomleftmenu around a bit
2016-09-13 19:08:54 +01:00
Matthew Hodgson b247c8a87f rename 'start chat' tooltip 2016-09-13 19:08:43 +01:00
wmwragg 56606c01a0 Added valid but unknown mx user 2016-09-13 17:09:01 +01:00
Matthew Hodgson eb2a55445c Merge pull request #2175 from aviraldg/feature-autocomplete-behaviour
Improve autocomplete behaviour (styling)
2016-09-13 16:17:14 +01:00
wmwragg 3fe8b503e5 Fixed over collapse on Safari, and now hide the RHS footer Invite when collapsed 2016-09-13 14:57:58 +01:00
wmwragg bdee2d3b28 Shifting icon to center of collapsed section 2016-09-13 14:44:54 +01:00
wmwragg 15ee2578c5 Tweak to font colour 2016-09-13 14:36:13 +01:00
wmwragg f8c9a28194 Updated to correct invite icon 2016-09-13 14:33:19 +01:00
wmwragg 768f11fe58 Added new Invite button in the RHS footer 2016-09-13 14:27:23 +01:00
wmwragg acdcb21830 Fixed weird margin bug when LHS panel is collapsed 2016-09-13 13:32:50 +01:00
wmwragg 1530568354 Merge branch 'develop' into wmwragg/chat-multi-invite 2016-09-13 12:38:45 +01:00
Matthew Hodgson 7b25f4e069 wip for collapsable RHS 2016-09-13 12:18:09 +01:00
Aviral Dasgupta cbab2c142b Autocomplete restyling 2016-09-13 15:43:59 +05:30
Aviral Dasgupta 81bbc05028 Merge branch 'develop' of github.com:vector-im/vector-web into develop 2016-09-13 15:42:36 +05:30
wmwragg f59dbe40ec Added error checking, and UI 2016-09-13 11:03:27 +01:00
Matthew Hodgson 562c3b0e04 fix notif icon 2016-09-13 10:32:40 +01:00
Matthew Hodgson f119a57952 dedicated dialog box for E2E messages 2016-09-12 23:42:43 +01:00
Matthew Hodgson c6fa1e2e21 show e2e icon by default 2016-09-12 20:02:22 +01:00
Matthew Hodgson 0bdc026b05 E2E CSS 2016-09-12 18:50:32 +01:00
Matthew Hodgson 20eb28f052 fix e2e icon placement 2016-09-12 17:38:27 +01:00
wmwragg bfd3ef0e44 Limit the invite area in height 2016-09-12 17:31:49 +01:00
wmwragg abda8c77ad Added styling for unknown addresses 2016-09-12 17:25:38 +01:00
Matthew Hodgson 9e5d090ddb Merge pull request #2163 from vector-im/matthew/e2e
First wave of E2E visuals
2016-09-12 17:20:23 +01:00
wmwragg 906be376c9 Refactored AddressTile to use string address rather than user object, so it can user email as well mx userId 2016-09-12 16:51:42 +01:00
Matthew Hodgson 695930efa5 e2e icons 2016-09-12 16:50:53 +01:00
Matthew Hodgson 7f2c74e7a8 Merge branch 'develop' into matthew/e2e 2016-09-12 16:32:58 +01:00
Matthew Hodgson f299572dc7 Merge pull request #2113 from vector-im/matthew/notif-panel
FilePanel and NotificationPanel support
2016-09-12 15:57:51 +01:00
Aviral Dasgupta d65b791b2b bump draft-js to 0.8.1 (as with matrix-react-sdk) 2016-09-12 18:31:22 +05:30
wmwragg 2bf177dbcc Refactored the queryList into seperate AddressSelector component 2016-09-12 13:01:08 +01:00
Matthew Hodgson 5775552bab css for e2e look & feel 2016-09-12 01:38:03 +01:00
Matthew Hodgson dd4617a7c6 bring back small avatars for info msgs otherwise the design breaks 2016-09-11 23:01:28 +01:00
Matthew Hodgson 64dedef2c7 fix wordwrap on new panels 2016-09-11 21:55:57 +01:00
Matthew Hodgson 89f8ff4988 Merge branch 'develop' into matthew/notif-panel 2016-09-11 02:37:30 +01:00
Matthew Hodgson 3a8c94de5a CSS for notif & file panel 2016-09-11 02:15:03 +01:00
Matthew Hodgson dd39813cc2 show context menus on hoverover 2016-09-11 02:14:52 +01:00
Matthew Hodgson e6c4273404 Merge pull request #2151 from vector-im/dbkr/memberinfo_createroom_cursor_pointer
Cursor: pointer on member info create room button
2016-09-09 22:33:37 +01:00
David Baker e1c32536ff Cursor: pointer on member info create room button 2016-09-09 19:23:12 +01:00
David Baker 013f68519e Merge pull request #2147 from vector-im/dbkr/memberinfo_list_rooms
Support for adding DM rooms to the MemberInfo Panel
2016-09-09 17:30:35 +01:00
David Baker ab9786cc02 Merge remote-tracking branch 'origin/develop' into dbkr/memberinfo_list_rooms 2016-09-09 16:27:00 +01:00
David Baker 57804f4e02 Support for common rooms in MemberInfo
Renames RoomDNDView to DNDRoomTile which now provides a separate DNDRoomTile component rather than
clobberring RoomTile, so we can use a draggable one where we want a draggable one and a non-draggable
one where we don't want it to be draggable. RoomTile main is still polluted with DND stuff, but is
now optional.

Remove BottomLeftMenuTile because it was no longer used in the bottom left menu. Just include
the equivalent markup directly in the one place we now use it (in MemberTile in react-sdk).
2016-09-09 16:15:45 +01:00
Matthew Hodgson c4421f6bc7 Merge pull request #2139 from vector-im/wmwragg/one-to-one-indicators
Wmwragg/one to one indicators
2016-09-09 15:08:20 +01:00
wmwragg 965d9aaf47 Lowered the Avatar menu background, so the Direct Message indicator is in front of it 2016-09-09 14:56:20 +01:00
wmwragg 2476f87e1d Positional tweaks for the new Direct Message indicator 2016-09-09 14:47:26 +01:00
wmwragg cd36800426 New direct message indicator CSS 2016-09-09 14:42:11 +01:00
wmwragg 18eb9d9330 Made sure the z-index was correct for the new little green men 2016-09-09 14:36:21 +01:00
Matthew Hodgson 7e379e9877 Merge pull request #2136 from vector-im/wmwragg/room-directory-back
Added back the Directory listing button, with new tootlip
2016-09-09 14:08:19 +01:00
Matthew Hodgson f2ca249b44 Merge pull request #2134 from vector-im/wmwragg/chat-invite-dialog-fix
wmwragg/chat invite dialog fix
2016-09-09 14:08:09 +01:00
wmwragg 09ce3a79ec Added back the Directory listing button, with new tootlip 2016-09-09 12:23:50 +01:00
wmwragg bfa59c6c04 Increased the width of the query list container to take account of scrollbars 2016-09-09 11:42:57 +01:00
Matthew Hodgson e75148e799 Merge branch 'develop' into matthew/notif-panel 2016-09-09 11:20:10 +01:00
Matthew Hodgson 8376f0d75a Merge pull request #2110 from vector-im/wmwragg/one-to-one-chat
Wmwragg/one to one chat
2016-09-09 10:46:01 +01:00
David Baker bf02a21c7d Re-add icons-people (I accidentally deleted it) 2016-09-09 10:30:17 +01:00
wmwragg ac365622b8 Align the RoomTile tooltips with the BottomLeftMenu tooltips 2016-09-09 07:10:12 +01:00
wmwragg 7cb48e0d2d Refactor so that the tooltip positional tweaks can be done in CSS rather than passed in as parameters 2016-09-09 06:56:54 +01:00
wmwragg 38ac520e1e Fixed name vertical overflow 2016-09-08 17:19:59 +01:00
Matthew Hodgson 6182ce48c9 fix (c) 2016-09-08 15:27:55 +01:00
David Baker 9e771ddd07 Merge pull request #2111 from vector-im/dbkr/toggle_dm_room
Support toggling DM status of rooms
2016-09-08 14:11:30 +01:00
David Baker 74aef1fdad Comment delay 2016-09-08 13:58:53 +01:00
Matthew Hodgson 8860c9c7fd Merge pull request #2082 from aviraldg/feature-rte-formatbar
Formatting toolbar for RTE message composer.
2016-09-08 13:54:39 +01:00
Matthew Hodgson a8d7d23dd6 implement NotifPanel css 2016-09-08 03:03:10 +01:00
Matthew Hodgson f5ce053f42 hook up the NotifPanel button 2016-09-08 03:02:50 +01:00
Aviral Dasgupta d833c7632d Add strikethrough and <hr> styles 2016-09-08 02:47:31 +05:30
Aviral Dasgupta 22bf6e7969 RTE format bar enhancements 2016-09-07 22:52:37 +05:30
David Baker a1f8116e3b Support toggling DM status of rooms
on context menu
2016-09-07 17:47:47 +01:00
wmwragg 1d32dd72ed Fixed typing error 2016-09-07 17:30:53 +01:00
wmwragg a3b77475c7 Merge branch 'develop' into wmwragg/one-to-one-chat 2016-09-07 17:23:43 +01:00
wmwragg 761552430c Dialog buttons have a pointer cursor now 2016-09-07 17:14:27 +01:00
wmwragg cc720b9797 Design tweaks for alignment 2016-09-07 17:08:24 +01:00
wmwragg 75c81b369f Mouse actions on the queryList added, as well as better queryListElement styling 2016-09-07 16:19:30 +01:00
Matthew Hodgson 7c74b0124b explicit props for RightPanel at last 2016-09-07 15:43:29 +01:00
wmwragg 48501d91d2 Added justification for the AddressTile, when requested 2016-09-07 10:55:31 +01:00
Matthew Hodgson aefef2ba56 FilePanel css 2016-09-07 02:16:09 +01:00
Richard van der Hoff 31dd49ffd7 Bump to olm 1.2.0 2016-09-06 22:33:21 +01:00
wmwragg ace0e01d86 Tweak on the textarea to prevent the input area jumping a couple of pixels in size between textarea and AddressTile 2016-09-06 17:21:28 +01:00
wmwragg c0ce7663a9 Initial highlighting selected address - styling not final 2016-09-06 16:39:38 +01:00
wmwragg e3d5ca34c8 Circumventing autofill by using a textarea rather than an input type=text 2016-09-06 16:15:36 +01:00
wmwragg 1fb53565ef Added scrolling to queryList 2016-09-06 15:46:09 +01:00
wmwragg a41a8d32b8 Basic address list created, and UX tweaks for interaction 2016-09-06 15:24:37 +01:00
Richard van der Hoff 835d13c696 Another go at using latest Olm
The previous attempt failed due to npm shenanigans. Let's have another go,
without the "help" of npm.
2016-09-06 13:24:06 +01:00
wmwragg 6153e795bf Correct AddressTile and ChatInviteDialog styling 2016-09-06 11:33:56 +01:00
Matthew Hodgson d12498f418 right cursor for roomsettings colours 2016-09-06 11:29:50 +01:00
David Baker c0eb69963d Merge pull request #2092 from vector-im/rav/use_development_olm
jenkins.sh: install olm from jenkins artifacts
2016-09-06 11:11:05 +01:00
Matthew Hodgson 1f19ee88c6 make FilePanel work, superficially at least 2016-09-06 01:45:12 +01:00
Matthew Hodgson 24351537d2 we have nothing to hide 2016-09-06 01:19:48 +01:00
Richard van der Hoff d309a7a67b jenkins.sh: install olm from jenkins artifacts
Use the latest version of olm, as provided by jenkins, rather than the most
recent release.
2016-09-05 18:54:10 +01:00
wmwragg f6f68bc348 Initial AddressTile added 2016-09-05 17:28:23 +01:00
Aviral Dasgupta d6a324ede7 Formatting toggle, markdown indicator, quoting 2016-09-05 17:39:32 +05:30
wmwragg 7378904f00 Adding back the BottomLeftMenuTile component, as it turns out it's still used in the RightPanel 2016-09-05 12:43:04 +01:00
wmwragg 059f5198e5 Merge branch 'develop' into wmwragg/one-to-one-chat 2016-09-05 12:07:21 +01:00
wmwragg 2acbad36a6 Initial commit of the new ChatInviteDialog 2016-09-05 12:03:43 +01:00
wmwragg 519dd16135 Added the correct styling back for the dialog buttons, that got regressed somewhere 2016-09-05 10:50:58 +01:00
wmwragg fb103cb9e1 Rename the action to make it clearer what it is doing 2016-09-05 10:27:54 +01:00
Richard van der Hoff 5e9a95fdfe Merge pull request #2085 from vector-im/rav/e2e_devices
e2e device CSS
2016-09-05 00:43:52 +01:00
Aviral Dasgupta b8610ab466 RTE formatbar (wip) 2016-09-04 21:03:00 +05:30
Richard van der Hoff ee3fdbee5b e2e device CSS
CSS to make the deviceinfo stuff a little bit closer to the designs
2016-09-04 13:42:33 +01:00
wmwragg 2d827a75a6 Sending the top and left position tweaks with the action 2016-09-04 12:16:01 +01:00
wmwragg 50bb4edd1c Small refactor, to make it clearer whats happening 2016-09-04 08:54:15 +01:00
wmwragg e52f5b5d08 Removed unrequired positional tweak props 2016-09-04 08:49:43 +01:00
wmwragg fd81ce126b Code tidy up 2016-09-04 08:40:43 +01:00
wmwragg 7ae821e2b5 Removed nolonger needed conditional test, as the parent will always exist 2016-09-04 08:39:32 +01:00
wmwragg cb98e2421e Removed the nolonger required methods 2016-09-04 07:56:32 +01:00
wmwragg 5417385c83 Tolltip thweak to not require the passing in of the parent 2016-09-04 07:41:48 +01:00
wmwragg c2d8067523 Testing to see if having the header badges when collapsed is usable 2016-09-03 14:55:35 +01:00
wmwragg 52bd61a2f0 When collapsed a long hover on the header now shows the full tag name and room count 2016-09-03 14:48:10 +01:00
wmwragg aee56a5bd1 z-index tweak for badge, so it does sit aboce the header 2016-09-03 14:47:36 +01:00
wmwragg 7f52fa74a4 Better comments, and syntax tweak 2016-09-03 14:14:11 +01:00
wmwragg d1dd4bd3d8 Updated tooltip styling to be better inline with the design 2016-09-03 13:57:49 +01:00
wmwragg ab9f48cd47 Restyled tooltip to better match the design 2016-09-03 13:44:00 +01:00
Matthew Hodgson c597f05e71 Merge branch 'develop' into matthew/notif-panel 2016-09-03 13:33:37 +01:00
wmwragg 80e6cd6d7c Further tweaks to the tooltip to better handle its position, and simplify it's use 2016-09-03 12:44:09 +01:00
wmwragg cb101b0a3b Allow better updating if the tooltip is designed to stick around, rather than just appearing on hover 2016-09-02 18:50:47 +01:00
wmwragg bf4e3364b4 Tweak of the RoomTooltip to use DOM element for the parent rather than a React component 2016-09-02 18:41:27 +01:00
Matthew Hodgson 0494dff545 Merge branch 'master' into develop 2016-09-02 17:23:02 +01:00
Remi Rampin d5865421bd Open commits in new window/tab from changelog 2016-09-02 12:22:51 -04:00
Remi Rampin 8578203073 Open HTML commit page for changelog entries 2016-09-02 12:22:15 -04:00
Matthew Hodgson e63e6e7016 0.7.5-r3 2016-09-02 17:21:30 +01:00
Matthew Hodgson dec62ab92c bump react-sdk 2016-09-02 17:20:23 +01:00
Matthew Hodgson 67d38bfab8 Prepare changelog for v0.7.5-r3 2016-09-02 17:20:08 +01:00
wmwragg d2e2c726eb Refactor of the RoomTooltip, so that it is easier to use, and also works with Safari 2016-09-02 15:45:43 +01:00
Matthew Hodgson 00d53e4824 css for conf join 2016-09-02 15:38:40 +01:00
Matthew Hodgson 4ce80a0837 fix dialog css 2016-09-02 14:39:44 +01:00
Richard van der Hoff 9aa59fa358 Merge pull request #2069 from vector-im/rav/update_olm
Bump to olm 1.1.0
2016-09-02 12:02:27 +01:00
Richard van der Hoff 6c8a492637 Bump to olm 1.1.0
Olm 1.0.0 made broken OlmAccounts.
2016-09-02 12:01:27 +01:00
Matthew Hodgson 9709a38250 merge master 2016-09-01 22:38:40 +01:00
Matthew Hodgson 06ca94c1e6 0.7.5-r2 2016-09-01 22:29:36 +01:00
Matthew Hodgson 67255e3f84 Prepare changelog for v0.7.5-r2 2016-09-01 22:29:36 +01:00
Matthew Hodgson a20962ac14 bump to react-sdk v0.6.5-r1 2016-09-01 22:28:39 +01:00
Matthew Hodgson b4cf86a362 fix padding-top for unread msgs 2016-09-01 17:00:52 +01:00
wmwragg bf8d7050cc New People icon in place of Directory icon, and placeholder functionality 2016-09-01 16:46:51 +01:00
Matthew Hodgson 49e5fa41ad fix overscroll on view source 2016-09-01 16:06:50 +01:00
Matthew Hodgson e069d808f8 Merge pull request #2056 from jansol/develop
Improve readability of the changelog dialog
2016-09-01 15:16:46 +01:00
Jan Solanti e85674711c Improve readability of the changelog dialog 2016-09-01 15:13:09 +03:00
Matthew Hodgson 7a89328ccb file upload when on call 2016-09-01 00:38:37 +01:00
Matthew Hodgson e77e6c2af0 fix typing notif layout 2016-09-01 00:35:07 +01:00
Matthew Hodgson ad26631874 fix icon layout 2016-09-01 00:33:45 +01:00
Matthew Hodgson cc75eb8b0e fix statusbar height and behaviour during voip calls 2016-09-01 00:14:51 +01:00
Matthew Hodgson 735da3c15e show ongoing audio call in LeftPanel CSS 2016-09-01 00:14:32 +01:00
Matthew Hodgson 56dfdbeb6b call noisy notifs... noisy 2016-09-01 00:14:01 +01:00
Matthew Hodgson eaf47ea05c show ongoing audio call in LeftPanel 2016-09-01 00:13:49 +01:00
Matthew Hodgson 37c46cf02f add a top-level remote audio element for https://github.com/vector-im/vector-web/issues/1271 and https://github.com/vector-im/vector-web/issues/621 2016-08-31 21:51:20 +01:00
Matthew Hodgson 9d72a7cb35 get adding FilePanel 2016-08-31 11:57:45 +01:00
Matthew Hodgson a047f81b84 Merge branch 'develop' into matthew/notif-panel 2016-08-30 23:39:00 +01:00
Richard van der Hoff a2694113d3 Merge pull request #2009 from vector-im/rav/enable_react_checks
Turn react consistency checks back on in develop builds
2016-08-30 14:57:49 +01:00
Matthew Hodgson 0aae88d753 nudge jenkins 2016-08-30 14:40:30 +01:00
Matthew Hodgson c7eba0f292 repin deps to dev 2016-08-30 13:52:35 +01:00
Matthew Hodgson 1bc1fc7e55 Merge pull request #2028 from vector-im/wmwragg/direct-chat-sublist
Wmwragg/direct chat sublist
2016-08-30 12:56:29 +01:00
wmwragg b91a0dd7a5 Increased truncation limit to 10 2016-08-30 12:14:32 +01:00
wmwragg 45a813b795 Fixed historical scetion not scrolling up when clicked if not hidden and stuck 2016-08-30 11:56:16 +01:00
wmwragg 7b7a77bad0 Merge branch 'develop' into wmwragg/direct-chat-sublist 2016-08-30 11:22:31 +01:00
wmwragg ff3ad47be7 Code clean up, and better comments, along with z-index fixes for scrollbar and avatar menu 2016-08-30 10:45:59 +01:00
wmwragg f2e8607433 Over scroll of bottom sticky headers should be fixed, and expansion of hidden stuck headers should now work 2016-08-28 19:14:54 +01:00
Matthew Hodgson b96ab58eb3 merge develop 2016-08-28 18:49:49 +01:00
Matthew Hodgson 5f233d75f2 0.7.5-r1 2016-08-28 18:09:20 +01:00
Matthew Hodgson eb88245fe7 Prepare changelog for v0.7.5-r1 2016-08-28 18:09:20 +01:00
Matthew Hodgson 45c013f2f2 0.7.5 2016-08-28 18:07:33 +01:00
Matthew Hodgson 05f8b49eec Prepare changelog for v0.7.5 2016-08-28 18:07:32 +01:00
Matthew Hodgson ef8f9ecbf3 pin matrix-js-sdk and matrix-react-sdk deps for release 2016-08-28 17:36:57 +01:00
wmwragg 93fff53e29 Added back the border spacing, as it wasn't the issue 2016-08-28 16:22:56 +01:00
wmwragg 4ae424f37a Removed the 2px border at top of labels to see if that has any effect on bottom stickies overscroll on matthews machine 2016-08-28 14:48:29 +01:00
Matthew Hodgson 36a608952d make /user URLs work 2016-08-28 14:04:25 +01:00
wmwragg 900b4b4cf8 Added a border to the top of the sections to better seperate them when they are stuck together 2016-08-28 13:44:52 +01:00
wmwragg b782e7b9ad Bottom line of the scroll area (well the top line of the bottom left menu) is now tinted same colour as the section headers 2016-08-28 13:22:14 +01:00
wmwragg 8d4268754e Fixed the stickies notification count to limit it to 99+ 2016-08-28 12:03:05 +01:00
Matthew Hodgson 9b8e127e23 switch to using matrix.to for permalinks 2016-08-28 02:11:57 +01:00
Matthew Hodgson 88dba1bf6c CSS for room settings leave button 2016-08-27 23:59:26 +01:00
Matthew Hodgson 8d7daf61b9 fix CSS namespacing 2016-08-27 23:59:15 +01:00
Matthew Hodgson ee1fae8ced fix RoomTagContextMenu so it works on historical rooms 2016-08-27 23:58:35 +01:00
Matthew Hodgson 13983900c0 clarify electron instructions 2016-08-27 22:21:52 +01:00
Matthew Hodgson 881739b478 try to unbreak jenkins >:( 2016-08-27 01:54:19 +01:00
Matthew Hodgson e06caa9ca1 mention not just a problem for Vector 2016-08-27 00:13:56 +01:00
Matthew Hodgson efc5462131 warn people to put their Matrix HS on a separate domain 2016-08-27 00:13:20 +01:00
Matthew Hodgson 2199fe5cbf unbreak changelog 2016-08-27 00:06:00 +01:00
Matthew Hodgson 30f774cf9c add whitespace padding to composer RHS 2016-08-27 00:00:09 +01:00
Matthew Hodgson be9aa44ca8 fix NPE checking tag order 2016-08-26 23:49:07 +01:00
wmwragg dc4459083f Fixed the LHS panel not collapsing but most of the content doing so 2016-08-26 16:22:59 +01:00
Matthew Hodgson 2f375e4f67 DIE ZALGO 2016-08-26 16:08:56 +01:00
Matthew Hodgson 879c325b83 DIE ZALGO 2016-08-26 16:08:15 +01:00
wmwragg 7ad3f4a577 Better comments 2016-08-26 15:53:31 +01:00
wmwragg 5b9d3b119f Click on stuck header scrolls to that header, collapses expands for none stuck header 2016-08-26 15:08:47 +01:00
wmwragg 5467fd89d8 Getting click to not collapse expand when header stuck 2016-08-26 14:35:40 +01:00
wmwragg d2937c2aed Setting correct heights and widths for label and container 2016-08-26 11:02:12 +01:00
wmwragg a0236a9b76 Code tidy-up and better name for label container class 2016-08-26 09:57:02 +01:00
Matthew Hodgson c6d4eb7fd3 try to make the changelog commit links suck less 2016-08-26 00:40:21 +01:00
wmwragg 4cb1f8a226 Initial pass at sticky headers for the LHS panel section labels 2016-08-25 19:46:15 +01:00
Matthew Hodgson abca5faf78 pin linkifyjs to precisely 2.0.0-beta4, as 2.0.0-beta9 breaks links as per https://github.com/vector-im/vector-web/issues/2010 2016-08-25 18:30:35 +01:00
Richard van der Hoff 21ffe22375 Turn react consistency checks back on in develop builds
The react checks are useful on /develop, to catch programming errors earlier,
and the original reason for turning them off (so that we could meaningfully
compare performance between /develop and /beta) is no longer so
relevant.

This reverts commit b5f029d10e.
2016-08-25 17:06:12 +01:00
Richard van der Hoff 64bbebb135 Merge pull request #2007 from vector-im/rav/travis
Add .travis.yml
2016-08-25 14:33:32 +01:00
Richard van der Hoff ebad3da6dd Use node v6 for travis 2016-08-25 14:26:56 +01:00
Richard van der Hoff 4633d16a6b Merge branch 'develop' into rav/travis 2016-08-25 14:26:20 +01:00
Richard van der Hoff df026aede2 Switch to node 6
... because 4 is ooold, and I'd like to use the same version on travis.
2016-08-25 14:25:05 +01:00
Richard van der Hoff d495a5b747 Merge branch 'rav/fix_build' into develop 2016-08-25 12:23:48 +01:00
Richard van der Hoff 042a6b58c4 Remove redundant whatwg import
This has been rewritten to use browser-request rather than whatwg, so remove
the import, which was causing the build to fail on npm 2. (It worked, for the
wrong reasons, on npm 3.)
2016-08-25 12:14:49 +01:00
Richard van der Hoff d87cf6c02b Transpile the react-sdk before running travis tests 2016-08-25 12:12:20 +01:00
Richard van der Hoff 0c99c5563f Add .travis.yml 2016-08-25 11:56:49 +01:00
Matthew Hodgson 3934e37f77 Merge pull request #1972 from aviraldg/feature-changelog
add fancy changelog dialog
2016-08-24 18:02:00 +01:00
Matthew Hodgson 2ee4fa484e Merge pull request #1978 from aviraldg/feature-autocomplete-improvements
Update autocomplete design
2016-08-24 14:48:06 +01:00
Richard van der Hoff bc7948d75f Merge remote-tracking branch 'origin/master' into develop 2016-08-24 10:24:35 +01:00
Richard van der Hoff 5348b8a980 Merge pull request #2001 from vector-im/rav/fix_readme_lies
Update encryption info in README
2016-08-24 10:22:38 +01:00
Richard van der Hoff f2936dc15c Update encryption info in README 2016-08-23 18:07:07 +01:00
Matthew Hodgson 864f9747f0 Merge pull request #2000 from vector-im/wmwragg/chat-message-presentation
Added event/info message avatars back in
2016-08-23 17:14:21 +01:00
wmwragg 3ea62eb73a Added event/info message avatars back in 2016-08-23 15:57:53 +01:00
Matthew Hodgson 2fae966884 notification panel WIP 2016-08-23 14:28:10 +01:00
Matthew Hodgson f888ec6e81 notification panel WIP 2016-08-23 14:27:58 +01:00
wmwragg d2e8201d79 Making sure that the sub list count always stays up to date, including when people read the outstanding notifications 2016-08-23 13:24:02 +01:00
wmwragg 65d7d01dfa Merge branch 'develop' into wmwragg/direct-chat-sublist 2016-08-23 12:49:43 +01:00
wmwragg 2cf2df20f6 Added updating of count when room tile notification state changed 2016-08-23 12:40:15 +01:00
Matthew Hodgson 1d1f89e0de Merge pull request #1987 from vector-im/wmwragg/chat-message-presentation
Wmwragg/chat message presentation
2016-08-23 12:19:58 +01:00
wmwragg ee73bc3aa4 Refactor of the badge logic, and also added no badges when zero notifications 2016-08-23 11:35:03 +01:00
wmwragg d3fa680373 Added all the notification states to the sub list count logic 2016-08-23 11:14:45 +01:00
wmwragg ef9d6d45b6 Merge branch 'develop' into wmwragg/direct-chat-sublist 2016-08-23 10:54:05 +01:00
wmwragg a980864886 Initial sub list notifications count. Still needs propagation of muting/unmuting etc. events from room tile up to sub list 2016-08-23 10:47:17 +01:00
wmwragg ca4d506391 Header wording for capped truncation count updated 2016-08-22 22:47:00 +01:00
Aviral Dasgupta 554c33a883 Extract autocomplete styling to CSS 2016-08-23 00:36:01 +05:30
Aviral Dasgupta 56813eb11e remove whatwg-fetch and use browser-request 2016-08-22 23:59:32 +05:30
wmwragg 4d5e3bc22b Initial tag section header badge 2016-08-22 17:25:43 +01:00
wmwragg ff55a951c9 Number of rooms added to header of sections 2016-08-22 17:02:52 +01:00
wmwragg 895172d498 Added catch to help get the Historical and any other weird sections into a sound state, so the states can then change correctly from then on 2016-08-22 16:42:08 +01:00
wmwragg 71f73d8df2 Collapsing and truncation initial state and onClick event logic 2016-08-22 15:50:36 +01:00
wmwragg 97daca4b31 Initial restyle of the sub lists and room lists 2016-08-22 14:10:06 +01:00
wmwragg e9eafc3380 Further tweak 2016-08-22 11:15:49 +01:00
wmwragg 600a1cae79 Read avatars position tweaked, now that the spacing has changed 2016-08-22 11:13:42 +01:00
wmwragg 0b1fc1b925 Avatar and Sender Profile alignment, along with reducing the distance between initial messages and the previous one 2016-08-22 10:45:00 +01:00
wmwragg bdaa9faea0 Added the font-size back in, as the textarea gets overidden otherwise 2016-08-19 18:03:12 +01:00
wmwragg dbadb07adf Moved the font-size into the .mx_MessageComposer_input so that it sets the size for RTE as well as normal composer 2016-08-19 17:57:24 +01:00
wmwragg 4a2c899d05 Merge branch 'develop' into wmwragg/chat-message-presentation 2016-08-19 17:22:26 +01:00
wmwragg 85084f5fd7 Fixed spacing on multiline messages 2016-08-19 16:46:15 +01:00
wmwragg 78692c83a6 Removal of the mini avatars for action (info) messages 2016-08-19 16:37:45 +01:00
wmwragg 173e6011e8 Alignment tweak to the readAvatars 2016-08-19 11:12:06 +01:00
wmwragg 9e542ba232 Alignment adjustment so that the readAvatars sit in the center of the top line in a new message 2016-08-19 10:58:51 +01:00
wmwragg 5005675561 Some CSS tidy-up, and fix for readAvatars when the message is not classed as a continuation, but is an info message 2016-08-18 22:50:40 +01:00
wmwragg 29759ca71e Initial pass at the /me and action messages, without name highlighting, and missing avatar for continuation messages after a /me or action message 2016-08-18 21:54:07 +01:00
Aviral Dasgupta be28a96d8d add fancy changelog dialog 2016-08-18 22:53:47 +05:30
Matthew Hodgson 9b5e5c9acb squidge video icon a bit 2016-08-18 16:48:28 +01:00
David Baker fbbbd44dc3 Merge pull request #1982 from vector-im/dbkr/make_notif_silder_work
Make the notification slider work
2016-08-18 15:24:14 +01:00
David Baker 0bb3eaaf67 Use constants 2016-08-18 13:46:47 +01:00
David Baker e48d68a449 PR feedback 2016-08-18 13:11:57 +01:00
wmwragg 67175c5a72 Positional tweaks, and font standardisation, so all browser now use ttf, so sizing is the same across all browsers 2016-08-18 11:15:42 +01:00
David Baker 6b0aeefc66 RoomNotifs.js moved to react-sdk
Since it's now used in RoomTile. Remove the vector prefix since it's no longer really a 'vector' thing
2016-08-17 18:29:38 +01:00
Aviral Dasgupta 9a7f5388d9 Update autocomplete design 2016-08-17 17:27:01 +05:30
wmwragg d1649771cc Images now slighlty set in so they don't appear under the context button, and give a margin to the right of the image 2016-08-16 17:41:54 +01:00
wmwragg 08e5f61b10 Image button now has cursor set to pointer 2016-08-16 17:41:09 +01:00
wmwragg 012f085f33 alignment tweaks and persistent highlight when meni clicked, plus menu button no longer an input item 2016-08-16 17:33:37 +01:00
wmwragg 9f570152e5 Altered message composer size to match that of the message timeline messages 2016-08-16 16:20:38 +01:00
wmwragg 3099ef68a9 Added linked message styling 2016-08-16 16:17:15 +01:00
wmwragg f0bac3a3b0 Design tweaks 2016-08-16 16:03:10 +01:00
David Baker cd0ed879e3 Make the slider work
Still WIP though: need to make vector work with the 'contains display name' rule being an override
2016-08-16 15:54:28 +01:00
wmwragg 95418089f3 Updating timestamp format 2016-08-16 15:01:25 +01:00
wmwragg 650a0f1c1f Added context button, and initial highlighting and readReceipts positioning 2016-08-16 11:58:52 +01:00
wmwragg 757e885abc Initial reposition of the read avatars 2016-08-16 10:59:04 +01:00
wmwragg 2c8e7782c5 Initial reposition of the timestamp 2016-08-16 10:26:14 +01:00
Matthew Hodgson d3eccc1d6f add rel='noopener' wherever we do target='_blank' because https://mathiasbynens.github.io/rel-noopener/ 2016-08-15 21:38:21 +01:00
David Baker 40aee5b03d Merge pull request #1966 from vector-im/rav/use_cpx_to_copy_olm
Use cpx to copy olm.js, and add watcher
2016-08-15 13:10:27 +01:00
Richard van der Hoff 4c9ade5ecb Use cpx to copy olm.js, and add watcher
We are now using `cpx` to copy the emojione files, so we might as well use it
for olm.js, rather than rolling our own - particularly since that makes it easy
to add a watcher for `npm start`.

We have to add a `-L` to the `cpx` invocation, otherwise, if olm is a
symlink (as is useful for development), cpx ends up watching the symlink, which
obviously never changes.
2016-08-15 12:16:08 +01:00
Richard van der Hoff 1d435890af Unpin react-sdk and js-sdk 2016-08-15 12:15:24 +01:00
Richard van der Hoff 8a2b2daad7 Revert "Unpin react-sdk and js-sdk"
I messed this up and removed staticfiles.js by accident

This reverts commit 21334cab28.
2016-08-15 12:13:58 +01:00
Richard van der Hoff 21334cab28 Unpin react-sdk and js-sdk 2016-08-15 12:11:35 +01:00
David Baker a17df609f3 Read all 4 different notif states
Can't yet set loud / mute
2016-08-12 15:19:34 +01:00
David Baker 0afdf5d8e4 Merge pull request #1959 from vector-im/rav/device_display_name
Make up a device display name
2016-08-12 11:48:12 +01:00
Richard van der Hoff 17733a66f9 rename MatrixChat defaultDeviceDisplayName prop 2016-08-12 11:40:25 +01:00
Richard van der Hoff 3a819a29b7 Make up a device display name
Pass a default device name into react-sdk
2016-08-12 11:01:39 +01:00
David Baker 9d77fab18f 0.7.4-r1 2016-08-12 10:11:40 +01:00
David Baker 3650c3f08b Prepare changelog for v0.7.4-r1 2016-08-12 10:11:39 +01:00
David Baker 5512fd4220 Bump to matrix-react-sdk 0.6.4-r1 2016-08-12 10:09:53 +01:00
David Baker 678393e2bd Add note about file table overflows 2016-08-12 09:59:56 +01:00
David Baker 25d8a7999f 0.7.4 2016-08-11 17:47:17 +01:00
David Baker 014f7ade86 Prepare changelog for v0.7.4 2016-08-11 17:47:16 +01:00
David Baker 2b671fcafc js-sdk & react sdk released 2016-08-11 17:45:10 +01:00
David Baker df5b243e75 Merge pull request #1954 from vector-im/dbkr/fix_messagecomposer_style
Don't show border on composer when not in RTE mode
2016-08-11 16:47:00 +01:00
David Baker 5e43f2752a Don't show border on composer when not in RTE mode
This breaks the opacity animation (so remove the transition) but the extra border was making the border on the composer too thick.
2016-08-11 16:30:53 +01:00
David Baker 0cb14ba5ec Don't force scrollbar on multi-invite 2016-08-11 15:11:31 +01:00
Matthew Hodgson d65477891e Merge pull request #1941 from vector-im/wmwragg/room-tag-menu
Wmwragg/room tag menu
2016-08-11 09:00:48 -05:00
Richard van der Hoff bb1854814c Merge pull request #1951 from vector-im/dbkr/dont_redirect_email_verify
Don't redirect to mobile app if verifying 3pid
2016-08-11 12:50:06 +01:00
Richard van der Hoff 9e15bda803 comment typo 2016-08-11 12:49:57 +01:00
David Baker e7ac66ad04 Don't redirect to mobile app if verifying 3pid
Fixes https://github.com/vector-im/vector-web/issues/1933
2016-08-11 12:44:49 +01:00
David Baker 4a0a911f3b Merge pull request #1950 from vector-im/rav/clear_test_localstorage
Make sure that we clear localstorage before *all* tests
2016-08-11 12:34:37 +01:00
David Baker 7286aeb013 Merge pull request #1942 from vector-im/dbkr/multi_invite
Basic CSS for multi-invite dialog
2016-08-11 12:34:13 +01:00
Richard van der Hoff 244265d52b Make sure that we clear localstorage before *all* tests
This was causing flaky tests, as sometimes the joining test would inherit an
"mx_is_guest" setting from a previous test run.
2016-08-11 11:42:29 +01:00
David Baker ab93e96a1f Merge pull request #1947 from vector-im/rav/token_login_tests
More tests for the loading process:
2016-08-11 11:16:27 +01:00
David Baker 5a17d8b450 Merge pull request #1946 from vector-im/rav/rav/refactor_token_login
Support for refactored login token handling
2016-08-11 10:52:32 +01:00
David Baker 43e3662e60 Merge pull request #1935 from aviraldg/fix-emoji
Various fixes and improvements to emojification.
2016-08-11 10:22:46 +01:00
Aviral Dasgupta 19d5063814 Merge branch 'develop' into fix-emoji 2016-08-11 14:51:17 +05:30
Richard van der Hoff da7a556629 More tests for the loading process:
1. Check that localstorage is correctly updated on successful login (test for
   https://github.com/matrix-org/matrix-react-sdk/pull/404)

2. Check that the saved HS isused for guest registration (test for
   https://github.com/matrix-org/matrix-react-sdk/pull/405)

3. Test loginToken handling (test for
   https://github.com/matrix-org/matrix-react-sdk/pull/406 /
   https://github.com/vector-im/vector-web/pull/1946)
2016-08-11 02:00:27 +01:00
Richard van der Hoff c2cb4dff4c Support for refactored login token handling
loginToken handling is now done by the session loader, so we need to pass in
the queryparams to MatrixChat.

Also, MatrixChat no longer automatically reloads the page to drop the
querystring, so we have to do that ourselves (doing it in index.js allows
tokenlogin to be tested).
2016-08-11 01:55:51 +01:00
Richard van der Hoff dd6868c255 Fix joining test
This had been broken by
https://github.com/matrix-org/matrix-react-sdk/pull/399. Change the way we
populate the matrixclient used for the joining tests.
2016-08-10 22:39:53 +01:00
David Baker b411a2e489 Merge remote-tracking branch 'origin/develop' into dbkr/multi_invite 2016-08-10 18:35:36 +01:00
wmwragg 28343aaa33 Aignment tweak for the room tag menu so the icons better align 2016-08-10 17:44:49 +01:00
David Baker 3f615c6664 Basic CSS for multi-invite dialog 2016-08-10 17:12:20 +01:00
wmwragg 804b17fbf1 Teaks to the CSS for the new ellipsis icon, and resizing the avatar back to 24px from 25px, as needs to be even number for the Text letter to align vertically 2016-08-10 17:00:06 +01:00
wmwragg 9798e14733 Menu colour now changeable, and leave room item hooked up. Some additional CSS tweaks to fit current design changes 2016-08-10 16:35:22 +01:00
Richard van der Hoff b742342062 Merge pull request #1938 from vector-im/rav/more_loading_tests
More app-loading tests
2016-08-10 16:02:01 +01:00
wmwragg f8fa19ed47 Room tag menu dohickey on the avatar on hover 2016-08-10 15:04:02 +01:00
Richard van der Hoff fe4bb3e413 More app-loading tests
1. fix the 'Clean load' tests which had been broken by
https://github.com/matrix-org/matrix-react-sdk/pull/399: make sure we clear
localStorage between tests.

2. Test the session rehydration properly by setting the localStorage rather
than setting up the MatrixClientPeg before loading the app.

3. Add some tests for the auto-guest-registration flows.
2016-08-10 14:37:30 +01:00
wmwragg ff13782ab5 Added set icons 2016-08-10 12:06:03 +01:00
wmwragg b1dd7efed8 Fixed weird lightening of fonts on a refresh of page on safari 2016-08-10 11:51:23 +01:00
wmwragg 699a58e0b3 Fix for historic and new undefined order issues 2016-08-10 11:39:10 +01:00
David Baker 6a19655886 Merge pull request #1936 from vector-im/rav/loading_tests
Some tests of the application load process
2016-08-10 10:53:23 +01:00
Richard van der Hoff afc889ff4d Some tests of the application load process 2016-08-10 00:15:04 +01:00
Richard van der Hoff b06c9f037e gitignore copied olm.js 2016-08-10 00:09:26 +01:00
wmwragg 1c812b340d Initial pass at handling room tags that don't have an order element, but need one manual ordering 2016-08-09 19:20:27 +01:00
Aviral Dasgupta bd9f5d3e06 Various fixes and improvements to emojification.
- Use locally hosted emoji
- Emojify SenderProfile and m.emote
- Fix emoji spacing
2016-08-09 21:44:09 +05:30
wmwragg cf8164bcc3 New icons 2016-08-08 18:11:18 +01:00
wmwragg 33612b7076 New dekete icon and ignoring olm.js 2016-08-08 17:11:08 +01:00
wmwragg 5a97786cc6 Initial pass of the tag menu, still lots of tweaking and bugfixing to do, but most of the mechanics are there now 2016-08-08 16:55:02 +01:00
Matthew Hodgson ee2329d236 make scrollbars bigger on hoverover 2016-08-07 21:35:41 +01:00
Matthew Hodgson 66f80b2239 let MemberInfo scroll if you have loads of E2E devices 2016-08-07 20:50:56 +01:00
David Baker 62ebeb9fd8 Merge pull request #1930 from vector-im/dbkr/enable_labs
Add 'enable labs' setting to sample config
2016-08-05 17:25:29 +01:00
wmwragg 72ba708bfe Menu separator styling 2016-08-05 16:35:59 +01:00
David Baker d0d7f2d2d2 Add 'enable labs' setting to sample config 2016-08-05 16:14:03 +01:00
wmwragg b3459be707 Initial RoomTagContextMenu wired in 2016-08-05 15:49:03 +01:00
David Baker d1e22d50f0 Merge pull request #1928 from vector-im/matthew/scalar
Matthew/scalar
2016-08-05 15:44:03 +01:00
David Baker bf46c3cfab Merge remote-tracking branch 'origin/develop' into matthew/scalar 2016-08-05 15:37:38 +01:00
wmwragg 7880734d77 Merge branch 'develop' into wmwragg/room-tag-menu 2016-08-05 15:26:42 +01:00
wmwragg 5ce1aba493 Created initial RoomTagContextMenu component 2016-08-05 15:23:07 +01:00
Richard van der Hoff c929076a83 Merge pull request #1929 from vector-im/dbkr/fix_unit_tests_replaceUsingCreds
Fix unit tests
2016-08-05 15:20:50 +01:00
Matthew Hodgson 99625067fe Merge pull request #1926 from vector-im/wmwragg/mute-mention-state-fix
Wmwragg/mute mention state fix
2016-08-05 14:44:48 +01:00
David Baker c9ab977d73 Fix unit tests
ReplaceUsingAccessToken was, uh, replaced with replacedUsingCreds
2016-08-05 14:38:10 +01:00
wmwragg b99e7598f9 notification menu now has cickable radio buttons 2016-08-04 17:05:19 +01:00
wmwragg b9e06bcf66 Moved mute state to mentions only 2016-08-04 16:17:47 +01:00
Matthew Hodgson eb108c7866 Merge branch 'develop' into matthew/scalar 2016-08-04 13:41:04 +01:00
Richard van der Hoff a190862ed3 Merge pull request #1919 from vector-im/dbkr/deactivate_account
CSS for deactivate account dialog
2016-08-04 10:32:41 +01:00
Matthew Hodgson 34a31a71fd increase weight of unread rooms as it's the only way to tell if you have unread messages, and the weight difference is currently too subtle 2016-08-03 22:54:01 +01:00
Matthew Hodgson 7774756ed1 fix lightbox on chrome 52: https://github.com/vector-im/vector-web/issues/1706 2016-08-03 17:19:36 +01:00
Matthew Hodgson ee9f78d156 slightly better volume labels 2016-08-03 15:49:32 +01:00
Matthew Hodgson 70754db27a Merge pull request #1900 from vector-im/wmwragg/mention-state-menu
Wmwragg/mention state menu
2016-08-03 15:22:49 +01:00
wmwragg 16f8143f3e synced prefix flex with flex 2016-08-03 14:45:31 +01:00
wmwragg be1f014294 Speech bubble tail shifted slightly, as the badge is now larger 2016-08-03 14:22:47 +01:00
wmwragg f53f9af1c5 Badge width fixed, and hover state for badge now only on badge itself. 2016-08-03 14:11:17 +01:00
David Baker 58b1d62976 CSS for deactivate account dialog
(Inc some generic CSS for error & danger fields)
2016-08-03 11:38:19 +01:00
wmwragg 8e0f7f18a0 Design update to match the new Zeplin designs 2016-08-03 11:21:00 +01:00
Matthew Hodgson 75ea62f351 Merge pull request #1913 from Half-Shot/develop
Fix UnknownBody styling for #1901
2016-08-02 16:21:29 +01:00
wmwragg ee8572559f Fixed small collapsed state hover issue with badges 2016-08-02 15:45:11 +01:00
wmwragg f640be90ad Container height shrunk, so it doesn't bump the avatars when collapsed. Also search box gutters fixed 2016-08-02 15:00:47 +01:00
wmwragg 472acd4792 New design for long names 2016-08-02 14:46:31 +01:00
David Baker 8087e99808 Merge pull request #1914 from vector-im/rav/no_webpack_olm
Exclude olm from the webpack
2016-08-02 13:07:56 +01:00
Richard van der Hoff 51b74251f9 Exclude olm from the webpack
Olm takes *ages* to webpack, and it doesn't compress well. So, serve it as a
separate asset to the browser.
2016-08-02 12:44:23 +01:00
Will Hunt 8c7aede0cc Style UnknownBody with `white-space: pre-wrap;` 2016-08-02 11:13:46 +01:00
Matthew Hodgson 2829d95705 Merge pull request #1912 from vector-im/wmwragg/button-updates
Wmwragg/button updates
2016-08-01 20:37:15 +01:00
Matthew Hodgson 28057fd086 improve upgrade-to-app warning on mobile app 2016-08-01 18:36:08 +01:00
wmwragg 2e3ad3206c New video call icon 2016-08-01 16:46:13 +01:00
wmwragg 4f94cf5dfb New voice and video call icons 2016-08-01 16:44:58 +01:00
Matthew Hodgson 51e8c28ab6 Merge pull request #1828 from vector-im/wmwragg/button-updates
Wmwragg/button updates
2016-08-01 15:42:33 +01:00
David Baker 0f73228d55 Merge pull request #1909 from vector-im/rav/devices_panel
CSS for device management UI
2016-08-01 14:28:08 +01:00
David Baker d21e4fb86a Merge pull request #1908 from vector-im/rav/silence_warning
Fix a warning from RoomSubList
2016-08-01 14:27:35 +01:00
Richard van der Hoff 645db7fa2f CSS for device management UI 2016-08-01 13:46:14 +01:00
Richard van der Hoff 0d4f35bed1 Fix a warning from RoomSubList
`selectedRoom` is *not* required, and we often don't have one, so get warnings.
2016-08-01 13:44:04 +01:00
Richard van der Hoff 2123fec8ed Merge pull request #1907 from vector-im/rav/fix_notification_warning_display
Fix notifications warning layout
2016-08-01 10:46:23 +01:00
Richard van der Hoff 3860488bb5 Fix notifications warning layout
For some reason, Chrome doesn't seem to make the central div in the
notifications warning wide enough, so it ends up wrapping. Fix this by making
the central div expand across the available space, instead of letting the
container for the close button do it.

Fixes https://github.com/vector-im/vector-web/issues/1687
2016-08-01 10:31:58 +01:00
wmwragg ef5ea46830 Consistent collapsed height across browsers 2016-08-01 09:53:57 +01:00
Matthew Hodgson d4faacf462 clear up IS ambiguity and close https://github.com/vector-im/vector-web/issues/1720 2016-07-31 23:42:34 +01:00
wmwragg 4a7d2901ac Positional tweaks for the name, badge and context menu, to better match design in both normal and collapsed states 2016-07-30 12:52:14 +01:00
wmwragg f382946138 Merge up from develop 2016-07-30 12:07:34 +01:00
wmwragg bb93a59cfb fixed unread hightlight font weight for room name 2016-07-29 13:49:28 +01:00
wmwragg 0ad84fd7b0 Better comments 2016-07-29 10:59:54 +01:00
wmwragg 87bddcd8ce Preliminary fix for showing muted state when collapsed - keep faded avatar, but don't show the mute icon 2016-07-29 10:50:50 +01:00
wmwragg 18701a2dae CSS tweaks to get the collapsed mute state properly working 2016-07-29 10:01:42 +01:00
wmwragg 2f65064688 CSS bugfix to stop incorrect letter spaceing on room names 2016-07-28 17:44:17 +01:00
wmwragg 2f08f2441f CSS tweaks for muted dohickey positioning 2016-07-28 17:41:01 +01:00
wmwragg 6c4c0bf57a Initial feature set complete, but the state and CSS need to be simplified 2016-07-28 17:35:25 +01:00
wmwragg 55a10ee275 Mute state handled corrcectly 2016-07-28 17:25:28 +01:00
wmwragg 49545ce0c2 Leaving the fail promise section blank as a todo, with explanitary comment 2016-07-28 15:29:57 +01:00
wmwragg b87058508e When a use clicks the state they want, after the change has been made it pasues breifly before closing, so that the user can see their state change has taken place. 2016-07-28 15:28:05 +01:00
Matthew Hodgson fd53f10fbd improve the getting started instructions and plug the electron apps 2016-07-28 16:05:21 +02:00
wmwragg 6329e274ab Extra polish to get styling looking like the design 2016-07-28 14:20:24 +01:00
wmwragg b5fdaac947 Final spacing tweaks to get it aligned with the design 2016-07-27 18:06:47 +01:00
wmwragg 22bf74dc65 Tweaks to get icons to line up better, still need to space labels correctly 2016-07-27 18:01:43 +01:00
wmwragg d376df478a Initial context menu with all it's elements 2016-07-27 17:43:35 +01:00
wmwragg 53f4da1d30 Refactor so that chevron and menu can be positioned independantly 2016-07-27 16:09:26 +01:00
David Baker e34db7b8c6 Merge pull request #1883 from vector-im/rav/remove_relayoutonupdate
Remove relayoutOnUpdate prop on gemini-scrollbar
2016-07-27 15:55:27 +01:00
wmwragg 074bbc7149 Added the two additiona states that don't yet exist on the backend, as faded and disabled options 2016-07-27 12:25:44 +01:00
Richard van der Hoff 4b33164ab6 Remove relayoutOnUpdate prop on gemini-scrollbar
The latest gemini-scrollbar makes relayoutOnUpdate redundant, so update to it
and remove the properties.
2016-07-27 11:41:27 +01:00
wmwragg dab707a893 Additional refactor to further modularise the context menus 2016-07-27 11:26:36 +01:00
wmwragg 5cf164fcc1 Re-modularised the context menus 2016-07-27 10:40:57 +01:00
wmwragg 37a7ce809a Added two new icons for notifications states 2016-07-27 10:40:19 +01:00
wmwragg 15f9f5dbe8 Doing the state change via onClick events rather than radio buttons, as they were causeing untraceable react errros for some reason 2016-07-26 17:24:45 +01:00
wmwragg 187818aaa0 Radio buttons now added, and only none guests can modify notfication state 2016-07-26 10:34:03 +01:00
wmwragg 30b1e7078f Contextual menu restyling 2016-07-25 18:04:16 +01:00
wmwragg 791980cd1f Menu context dohickey now sticks when menu shown 2016-07-25 17:19:06 +01:00
wmwragg 6c19504c8b Merge branch 'wmwragg/mention-state-indicator-round-3' into wmwragg/mention-state-menu
# resolved Conflicts:
#	src/skins/vector/css/vector-web/views/rooms/RoomTooltip.css
2016-07-25 16:45:25 +01:00
wmwragg 497ebce88a Corrected vertical alignment of membership button 2016-07-25 13:16:51 +01:00
wmwragg 2768cd2010 Initial unstyled mentions state notifier context menu 2016-07-22 17:30:09 +01:00
wmwragg 204e42494a The default props doesn't seem to be working, hardcoded 'LABEL' for now. OnClick closes menu 2016-07-22 16:11:42 +01:00
wmwragg 72b4a86eed Tweaked the tooltip to be better aligned. Also added the fading of the room name if too long 2016-07-22 14:59:02 +01:00
wmwragg ce5311191f Tweaked tooltip z-index 2016-07-22 11:30:41 +01:00
wmwragg 7eff6d968e Tweak to z-index as the tooltip was occasionally getting occluded. 2016-07-22 11:16:04 +01:00
David Baker d01e2506f5 Merge pull request #1842 from vector-im/rav/bump_dependency_versions
Bump dependency versions
2016-07-22 10:53:55 +01:00
Richard van der Hoff 53fe372a0c Bump to react 15.2.1
This should also stop npm complaining about invalid peerDependencies.
2016-07-22 10:47:09 +01:00
Richard van der Hoff 4cb04d1e40 Bump to latest react-gemini-scrollbar
I've updated our forks of the gemini-scrollbar project to latest upstream.
2016-07-22 10:46:38 +01:00
wmwragg 24e021b91f Badge dohickey shown on name hover and badge hover 2016-07-21 18:19:52 +01:00
wmwragg e988f5ca3b Badge visual tweaks 2016-07-21 17:54:33 +01:00
wmwragg 633a3f4867 New component for testing 2016-07-21 17:44:05 +01:00
wmwragg df163d8cb7 Clean up of the CSS, and refactor to better match current code 2016-07-21 14:33:27 +01:00
wmwragg 73bb317925 Slight tweak to the name padding so there is a little less space above and below the name 2016-07-21 12:19:11 +01:00
wmwragg ad74d264a3 Selected room highlight teaked to better fit previous design 2016-07-21 11:37:40 +01:00
wmwragg e9db975d7d Redone assets, with lighter weight to match design 2016-07-21 10:25:42 +01:00
Matthew Hodgson 0958a6bb62 Merge pull request #1835 from vector-im/wmwragg/mention-state-indicator-round-2
Wmwragg/mention state indicator round 2
2016-07-20 18:01:54 +01:00
wmwragg f3586a79c2 Final CSS tweaks for the hover and collapsed states 2016-07-20 17:10:23 +01:00
wmwragg 882d09bf85 Initial reworking of the RoomTile CSS 2016-07-20 12:46:44 +01:00
Matthew Hodgson 25eb2e2daf Merge pull request #1822 from vector-im/wmwragg/spinner-fix
Wmwragg/spinner fix
2016-07-19 12:54:15 +01:00
Matthew Hodgson d8d9912f2d Merge pull request #1823 from vector-im/wmwragg/mention-state-indicator
Wmwragg/mention state indicator
2016-07-19 12:19:36 +01:00
wmwragg 8a28da1986 Fixed white space issues 2016-07-19 12:13:29 +01:00
wmwragg 384425582a Fixed wonky white space 2016-07-19 11:47:32 +01:00
wmwragg b87b356722 Added fixed SCG assets 2016-07-19 11:43:15 +01:00
Matthew Hodgson 6ae0dda9d3 give FF higher billing 2016-07-18 18:26:03 +01:00
Matthew Hodgson 6c680ff424 improve spacing 2016-07-18 18:25:50 +01:00
Matthew Hodgson c6b455f470 improve spacing 2016-07-18 18:24:30 +01:00
wmwragg f6d7052928 Oixel tweak so that it work properly in firefox 2016-07-18 16:38:29 +01:00
wmwragg 2ee1a9c440 Explanatory text about specificity 2016-07-18 16:20:44 +01:00
wmwragg 8fd12d530d Added the hightlight badge restyling 2016-07-18 14:57:03 +01:00
wmwragg 3f7bd48c0a Made the collapsed badge smaller than the uncollapsed one, basically the same size as it was originally 2016-07-18 14:27:14 +01:00
wmwragg 28108476bd Added an overide for the view source so that it behaves correctly with the new Modal. Also tweaked the spinner overide 2016-07-18 10:31:17 +01:00
Matthew Hodgson 722cedc92e CSS for generic user settings at last 2016-07-18 01:33:43 +01:00
Matthew Hodgson f182e32e3d typo 2016-07-18 01:33:36 +01:00
wmwragg 3cfcc13387 Initial fix for Dialog Spinners 2016-07-17 21:20:11 +01:00
wmwragg 953bb64e0b Some quick initial tweaks to the badge icon 2016-07-17 21:18:47 +01:00
Matthew Hodgson 54f4443428 fix single emoji sizing 2016-07-17 18:30:06 +01:00
Matthew Hodgson a039450d10 Merge pull request #1809 from vector-im/revert-1799-feature-inline-link-preview
Revert "Presentation for inline link"
2016-07-15 16:54:39 +01:00
Matthew Hodgson 1e963a6c3a Revert "Presentation for inline link" 2016-07-15 16:54:27 +01:00
Matthew Hodgson 80ad45df06 spell out that vector should not depend on the public net 2016-07-15 15:57:59 +01:00
Matthew Hodgson 348f133e77 add mx_EventTile_body class for the body span in events, and fix the naming scheme of '.emoji-body' 2016-07-15 15:03:42 +01:00
Matthew Hodgson cd865bbe8f Merge pull request #1806 from vector-im/wmwragg/modal-restyle
Wmwragg/modal restyle
2016-07-15 15:01:01 +01:00
wmwragg e668d7685d Fixed light box colour, reset back to black. 2016-07-15 14:54:15 +01:00
Matthew Hodgson 6607bee91a Merge pull request #1799 from ribot/feature-inline-link-preview
Presentation for inline link
2016-07-15 13:51:54 +01:00
wmwragg 3a89a5af0b Increasing the specificity of the CSS so that primary input submit buttons are styled correctly 2016-07-15 12:33:56 +01:00
Stefan Pearson 35e3621ae7 removes overflow comments 2016-07-15 12:21:05 +01:00
wmwragg 040ef73886 Simple refactor of the primary indicator, now it's a class. Also added a global selector to remove the ugly firefox dotted line highlight 2016-07-15 11:22:10 +01:00
David Baker 74c9ac0872 Merge pull request #1798 from vector-im/dbkr/offline_user_colour
CSS for offline user colours
2016-07-14 18:29:28 +01:00
wmwragg adbad509f4 Updated to highlight the primary button in the dialog, i.e. the first one 2016-07-14 17:59:06 +01:00
David Baker 15a97a653f CSS for offline user colours 2016-07-14 17:43:43 +01:00
Stefan Pearson 9fb97a6b10 presentation for inline link 2016-07-14 17:08:25 +01:00
wmwragg 579f210cfc Initial Modal dialog restyling 2016-07-14 16:55:41 +01:00
wmwragg 2fb1e156ed Modal background restyled 2016-07-14 15:41:23 +01:00
wmwragg 707ddc61bf Mergeing up from develop 2016-07-14 12:43:25 +01:00
wmwragg 09e861637f Simplification of the css 2016-07-14 12:04:31 +01:00
wmwragg 1f43f904d5 Search icon updated in header, and all icons spacing and positioning teaked 2016-07-14 11:33:07 +01:00
Matthew Hodgson 446f74b3dd Merge pull request #1776 from vector-im/wmwragg/typography-updates
Wmwragg/typography updates
2016-07-14 11:00:40 +01:00
wmwragg d2391f999e Adding back in .DS_Store, but to ignore in any directory 2016-07-14 10:42:39 +01:00
wmwragg e1779ca8bc Deleteing .DS_Store files before adding to gitignore 2016-07-14 10:41:41 +01:00
wmwragg 65371c9a39 Adding ignoring of mac .DS_Store files to all directories 2016-07-14 10:32:30 +01:00
wmwragg a4dc844338 Added truetype font fallback for browsers that don't support WOFF2 format, i.e. safari 2016-07-14 10:24:16 +01:00
wmwragg 0a4af647c8 Header and footer buttons updated to new versions 2016-07-13 17:46:07 +01:00
wmwragg 503bf541c7 Tweak to the close button css to keep the close button inline with the search box 2016-07-13 14:34:20 +01:00
wmwragg 1fbc249de5 Updated Filter room icon 2016-07-13 14:23:46 +01:00
wmwragg 959dcd0c49 Updated BottomLeftMenu buttons to the new ones 2016-07-13 14:10:44 +01:00
wmwragg ef4f2f10d9 Updated that RightPanel members icon, highlight and numbers 2016-07-13 13:56:59 +01:00
David Baker 19dbd85d44 Merge pull request #1766 from vector-im/rav/use_right_olm
webpack: always use the olm from vector-web
2016-07-13 09:48:08 +01:00
Richard van der Hoff ef4b604caf webpack: always use the olm from vector-web
Fixes an error when matrix-js-sdk is symlinked into node_modules, which meant
that we would (try to) use the version of olm from js-sdk instead of
vector-web (https://github.com/vector-im/vector-web/issues/1765).
2016-07-12 23:10:53 +01:00
Aviral Dasgupta 74f459f8a4 feat: bump emoji-body font-size down to 48px 2016-07-12 20:37:51 +05:30
Matthew Hodgson fef81748bb major update to dev guidelines 2016-07-11 18:25:58 +01:00
Richard van der Hoff 3e53879adc Bump to olm 1.0.0
Fixes https://github.com/vector-im/vector-web/issues/1719
2016-07-11 14:53:51 +01:00
David Baker 145e61b00f Merge pull request #1718 from aviraldg/feature-emojione
feat: large emoji support
2016-07-05 10:08:15 +01:00
Aviral Dasgupta 49dd93ffab feat: large emoji support 2016-07-05 04:04:34 +05:30
David Baker 7174879ac9 Merge pull request #1717 from aviraldg/feature-autocomplete
Autocomplete
2016-07-04 18:16:22 +01:00
Matthew Hodgson 486adb717b Merge pull request #1670 from Half-Shot/patch-1
#1664 Set a maximum height for codeblocks
2016-06-24 19:16:50 +01:00
David Baker 773f592c3f Merge pull request #1688 from vector-im/rav/device_blocking
CSS for device blocking
2016-06-23 18:24:40 +01:00
Richard van der Hoff 2ca9d87b95 CSS for device blocking
A bunch of updates to the device info:

* format as a table
* make the buttons green, because the old way was super confusing
* instead make the status indicator red/orange/green.
2016-06-23 17:32:33 +01:00
David Baker 4bc4292ceb Rooms may not have aliases 2016-06-23 11:12:25 +01:00
David Baker cbb72c2f29 Merge pull request #1685 from vector-im/dbkr/fix_room_directory
Fix joining rooms by typing the alias
2016-06-23 10:21:03 +01:00
David Baker 5f477b313b Unused variable 2016-06-23 10:20:11 +01:00
David Baker d45e44d01c Fix joining rooms by typing the alias
Fixes regression introduced by https://github.com/vector-im/vector-web/pull/1680
2016-06-23 10:11:46 +01:00
Richard van der Hoff c12839dc7b Merge pull request #1680 from vector-im/dbkr/delete_alias
Add ability to delete an alias from room directory
2016-06-22 17:25:27 +01:00
David Baker c35c9f7c3a PR feedback 2016-06-22 16:20:06 +01:00
David Baker ff5c7072d7 Mark the room as private (unlisted) too
Also clean up RoomDirectory a bit and just pass the room object around rather than the name / alias, so now we don't have to look up the room by ID again.
2016-06-22 14:52:55 +01:00
Matthew Hodgson eca453ee5a reposition Login spinner 2016-06-21 19:49:55 +01:00
David Baker ad2541299f Add ability to delete an alias from room directory
Hidden behind shift-click for now, but we're going to need to do this a lot to moderate the public room list.
2016-06-21 16:47:40 +01:00
Aviral Dasgupta dc840fdf48 updated selection styling 2016-06-21 19:02:18 +05:30
Aviral Dasgupta 510bb5785e Merge branch 'develop' into feature-autocomplete 2016-06-21 04:09:23 +05:30
David Baker 9556795611 Merge pull request #1678 from vector-im/rav/olmify_develop_again
package.json: add olm as optionalDependency
2016-06-20 15:28:06 +01:00
Richard van der Hoff 4c6fa740f3 package.json: add olm as optionalDependency
Add olm as an optionalDependency to vector, so that the webpack config can find
it and include it in the bundle.
2016-06-20 15:10:19 +01:00
David Baker f4a3e9a39b Merge pull request #1675 from vector-im/rav/olmify_develop
Another go at enabling olm on vector.im/develop
2016-06-20 14:38:00 +01:00
Richard van der Hoff bb820bebd1 README: fix some lies
Take out a few misleading things from the readme.
2016-06-20 14:36:40 +01:00
Richard van der Hoff 664f809362 webpack: Use require to look for olm
Since https://github.com/matrix-org/matrix-js-sdk/pull/141, the jenkins build
does pull in the olm module, but because it's using npm v2, buries it deep in
node_modules. Rather than using the `fs` module to hunt for it, just try to
`require` it in the webpack config.
2016-06-20 14:35:33 +01:00
Aviral Dasgupta 034c045b37 Styling for autocomplete 2016-06-20 13:53:18 +05:30
Matthew Hodgson 4dfb0e9a90 Merge branch 'develop' into matthew/scalar 2016-06-19 22:40:58 +01:00
Matthew Hodgson 654429dbdb improve wording on 'search room names' 2016-06-18 21:12:32 +01:00
Will Hunt c7d0214aaa #1664 Set a maximum height for codeblocks 2016-06-18 12:21:34 +01:00
David Baker 607923b58f Fix test since we peek by room ID, not alias 2016-06-17 17:49:36 +01:00
David Baker 895fb63d5d Merge pull request #1661 from vector-im/rav/unverify_device
CSS for unverify button
2016-06-17 17:00:26 +01:00
David Baker b172018d08 Merge pull request #1660 from vector-im/rav/crypto_css_fix
CSS fix for rooms with crypto enabled
2016-06-17 16:58:47 +01:00
Richard van der Hoff 95a0bc92d6 CSS for unverify button
(supports change in react-sdk)
2016-06-17 16:25:39 +01:00
Matthew Hodgson a90492e393 fix CSS 2016-06-17 16:14:14 +01:00
Aviral Dasgupta ec7067e7bd Autocomplete style 2016-06-17 04:58:39 +05:30
David Baker 42b7410a5d Merge pull request #1652 from vector-im/rav/fix_karma_olm_warning
Karma: fix warning by ignoring olm
2016-06-16 11:16:00 +01:00
Richard van der Hoff 4cfcdfa040 Merge pull request #1639 from vector-im/dbkr/fix_peeking
Update for react-sdk dbkr/fix_peeking branch
2016-06-16 11:13:29 +01:00
Richard van der Hoff 795986f146 Karma: fix warning by ignoring olm
If olm is not installed, the webpack build for the karma tests gives an ugly
error. None of the tests currently care if olm is installed or not, so fix this
for now by just ignoring the olm module.
2016-06-16 07:41:34 +01:00
Richard van der Hoff d38c338f89 Merge pull request #1641 from vector-im/dbkr/update_readme
Update README.md
2016-06-15 17:10:02 +01:00
David Baker a373849b5b Give better instructions for modifying config. 2016-06-15 11:03:52 +01:00
Richard van der Hoff 8cd4637316 Merge pull request #1643 from vector-im/dbkr/fix_karma
Fix karma tests
2016-06-14 16:38:14 +01:00
David Baker 0635a6f562 Fix karma tests
As we now use draft-js: https://github.com/facebook/fbjs/issues/133#event-617440260
2016-06-14 16:32:07 +01:00
David Baker a8cee87c08 js-sdk doesn't have a build step 2016-06-14 15:53:13 +01:00
David Baker a7598ea815 Mention copying sample file here too 2016-06-14 15:52:03 +01:00
David Baker 22cef7a6a0 Copy config.json first 2016-06-14 15:41:55 +01:00
David Baker e507339324 Merge pull request #1553 from aviraldg/feature-rte
Rich Text Editor
2016-06-14 15:27:35 +01:00
David Baker b643d8ff6a Update README.md
To reflect the fact that you can now sensibly deploy from a package (ie. be able to configure the app). Make the first thing be downloading a prebuilt package so people who only read the first part don't end up running npm start in production and complain about needing npm.
2016-06-14 15:12:35 +01:00
David Baker 3547bd8d00 Update for react-sdk dbkr/fix_peeking branch
With the react-sdk update, this does nothing functionally since the room ID would just
have been ignored, but update this to correctly supply only one of ID/alias.
2016-06-14 13:02:34 +01:00
Aviral Dasgupta ab1f37b0bb Merge pull request #1 from pferreir/pr/1553
Basic Markdown highlighting
2016-06-12 04:55:05 +05:30
Pedro Ferreira eb37032d8a Markdown: styles for bold/italics 2016-06-12 01:04:22 +02:00
Aviral Dasgupta f6ed21559a RTE mode switch styling & cleanup 2016-06-11 15:54:43 +05:30
Richard van der Hoff a5986ade51 Merge pull request #1615 from vector-im/dbkr/directory_join_by_alias
Fix RoomDirectory to join by alias whenever possible.
2016-06-10 15:23:07 +01:00
David Baker d7504aeda5 Switch to new view_room 2016-06-10 15:13:41 +01:00
Aviral Dasgupta b2459b2dc6 Merge branch 'develop' of github.com:vector-im/vector-web into feature-rte 2016-06-10 04:43:06 +05:30
Aviral Dasgupta 819e06e2cd MessageComposer styling for Draft 2016-06-10 04:41:59 +05:30
David Baker b7f1a3db57 gitignore config.json now it isn't versioned 2016-06-09 18:51:25 +01:00
David Baker a030e46c69 Use join_room_by_alias in RoomDirectory
This still doesn't actually cause the room to be joined by alias though, so still need to fix that
2016-06-09 17:13:02 +01:00
David Baker f61cfbc542 Fix RoomDirectory to join by alias whenever possible. 2016-06-09 16:41:01 +01:00
Richard van der Hoff c4b7571c45 Merge pull request #1612 from vector-im/dbkr/optional_config
Make the config optional
2016-06-09 10:40:58 +01:00
Richard van der Hoff 4dd477e064 index.js: fix comment typo
Fix dave's typo for him
2016-06-09 10:38:51 +01:00
David Baker f595f6f141 This check shouldn't be here with the || 2016-06-09 10:25:49 +01:00
David Baker 24602119c5 This doesn't actually need to be global
(because the rendering isn't in a render method here)
2016-06-09 09:59:37 +01:00
David Baker 3040d0a474 Comment typo 2016-06-09 09:57:44 +01:00
David Baker e4ea00ca23 Return here, else we'll call resolve too 2016-06-09 09:56:57 +01:00
David Baker 4fc311da90 Style fix 2016-06-09 09:56:11 +01:00
Richard van der Hoff 7894e52529 Merge pull request #1610 from vector-im/rav/device_verification
CSS support for device verification
2016-06-08 21:37:35 +01:00
Richard van der Hoff 7999a70cab Switch to dev versions of react-sdk and js-sdk 2016-06-08 21:36:45 +01:00
David Baker f6aa9a7ea4 Make the config optional
Accept 404 errors from getting the config and start MatrixChat with no config, make other errors display a simple error message to prevent a completely blank page if the config does fail to load.
2016-06-08 18:46:21 +01:00
David Baker b3ae9cc9d4 Merge pull request #1609 from vector-im/dbkr/SdkConfig
Don't use SdkConfig
2016-06-08 17:34:18 +01:00
Richard van der Hoff 5f29729e82 Make unverified encrypted events red and verified ones green 2016-06-08 17:03:54 +01:00
Richard van der Hoff e24851456a CSS for the MemberDeviceInfo view 2016-06-08 17:03:28 +01:00
David Baker 1e40fd750f Don't use SdkConfig
instead take brand from a prop
2016-06-08 14:55:47 +01:00
Richard van der Hoff ed1554f4af index.js: fix wording in android popup 2016-06-07 22:01:56 +01:00
David Baker c6cf5febd5 Merge pull request #1516 from vith/static-config-json
serve config.json statically instead of bundling it
2016-06-06 19:15:35 +01:00
David Baker f9aaf7d903 Use the SdkConfig interface
rather than pulling in config.json directly.

json-loader appears to still be necessary due to some horrendous json dependency in the depths of sanitize-html.
2016-06-06 19:13:30 +01:00
Matthew Hodgson a2e73cceee Merge branch 'develop' into matthew/scalar 2016-06-06 10:24:39 +01:00
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
Aviral Dasgupta 7e563b89c7 initial version of rich text editor 2016-05-27 10:17:01 +05:30
Jason Papakostas 6a6118e136 serve config.json statically instead of bundling it
issue #1344
2016-05-24 19:08:09 -05:00
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 a288c5b85d fix padding of badges 2016-05-20 12:21:45 +01:00
Matthew Hodgson c4d408d095 CSS for IntegrationsManager 2016-05-18 17:02:39 +01:00
Matthew Hodgson ac24d6707f Add integs mgt 2016-05-18 15:02:03 +01:00
Matthew Hodgson e5835d2731 typo 2016-05-18 15:01:36 +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
244 changed files with 9452 additions and 1325 deletions
+11 -7
View File
@@ -1,8 +1,12 @@
node_modules
vector/bundle.*
lib
/cert.pem
/karma-reports
/key.pem
/lib
/node_modules
/packages/
/vector/bundle.*
/vector/components.css
/vector/emojione/
/vector/config.json
/vector/olm.js
.DS_Store
key.pem
cert.pem
vector/components.css
packages/
+6
View File
@@ -0,0 +1,6 @@
language: node_js
node_js:
- 6 # node v6, to match jenkins
install:
- npm install
- (cd node_modules/matrix-react-sdk && npm run build)
+367 -1
View File
@@ -1,3 +1,369 @@
Changes in [0.8.3](https://github.com/vector-im/vector-web/releases/tag/v0.8.3) (2016-10-12)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.8.2...v0.8.3)
* Centre images in dialog buttons
[\#2453](https://github.com/vector-im/vector-web/pull/2453)
* Only show quote option if RTE is enabled
[\#2448](https://github.com/vector-im/vector-web/pull/2448)
* Fix join button for 'matrix' networks
[\#2443](https://github.com/vector-im/vector-web/pull/2443)
* Don't stop paginating if no rooms match
[\#2422](https://github.com/vector-im/vector-web/pull/2422)
Changes in [0.8.2](https://github.com/vector-im/vector-web/releases/tag/v0.8.2) (2016-10-05)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.8.1...v0.8.2)
* Add native joining of 3p networks to room dir
[\#2379](https://github.com/vector-im/vector-web/pull/2379)
* Update to linkify 2.1.3
[\#2406](https://github.com/vector-im/vector-web/pull/2406)
* Use 'Sign In' / 'Sign Out' universally
[\#2383](https://github.com/vector-im/vector-web/pull/2383)
* Prevent network dropdown resizing slightly
[\#2382](https://github.com/vector-im/vector-web/pull/2382)
* Room directory: indicate when there are no results
[\#2380](https://github.com/vector-im/vector-web/pull/2380)
* Room dir: New filtering & 3rd party networks
[\#2362](https://github.com/vector-im/vector-web/pull/2362)
* Update linkify version
[\#2359](https://github.com/vector-im/vector-web/pull/2359)
* Directory search join button
[\#2339](https://github.com/vector-im/vector-web/pull/2339)
Changes in [0.8.1](https://github.com/vector-im/vector-web/releases/tag/v0.8.1) (2016-09-21)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.8.0...v0.8.1)
Changes in [0.8.0](https://github.com/vector-im/vector-web/releases/tag/v0.8.0) (2016-09-21)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.5-r3...v0.8.0)
* Dbkr/rebrand
[\#2285](https://github.com/vector-im/vector-web/pull/2285)
* Listen for close_scalar and close the dialog box when received
[\#2282](https://github.com/vector-im/vector-web/pull/2282)
* Revert "improve lipstick and support scalar logout"
[\#2281](https://github.com/vector-im/vector-web/pull/2281)
* improve lipstick and support scalar logout
[\#2280](https://github.com/vector-im/vector-web/pull/2280)
* Fix changelog links
[\#2071](https://github.com/vector-im/vector-web/pull/2071)
* Paginate Room Directory
[\#2241](https://github.com/vector-im/vector-web/pull/2241)
* Make redeploy script symlink config
[\#2240](https://github.com/vector-im/vector-web/pull/2240)
* Update the version of olm to 1.3.0
[\#2210](https://github.com/vector-im/vector-web/pull/2210)
* Directory network selector
[\#2219](https://github.com/vector-im/vector-web/pull/2219)
* Wmwragg/two state sublist headers
[\#2235](https://github.com/vector-im/vector-web/pull/2235)
* Wmwragg/correct incoming call positioning
[\#2222](https://github.com/vector-im/vector-web/pull/2222)
* Wmwragg/remove old filter
[\#2211](https://github.com/vector-im/vector-web/pull/2211)
* Wmwragg/multi invite bugfix
[\#2198](https://github.com/vector-im/vector-web/pull/2198)
* Wmwragg/chat multi invite
[\#2181](https://github.com/vector-im/vector-web/pull/2181)
* shuffle bottomleftmenu around a bit
[\#2182](https://github.com/vector-im/vector-web/pull/2182)
* Improve autocomplete behaviour (styling)
[\#2175](https://github.com/vector-im/vector-web/pull/2175)
* First wave of E2E visuals
[\#2163](https://github.com/vector-im/vector-web/pull/2163)
* FilePanel and NotificationPanel support
[\#2113](https://github.com/vector-im/vector-web/pull/2113)
* Cursor: pointer on member info create room button
[\#2151](https://github.com/vector-im/vector-web/pull/2151)
* Support for adding DM rooms to the MemberInfo Panel
[\#2147](https://github.com/vector-im/vector-web/pull/2147)
* Wmwragg/one to one indicators
[\#2139](https://github.com/vector-im/vector-web/pull/2139)
* Added back the Directory listing button, with new tootlip
[\#2136](https://github.com/vector-im/vector-web/pull/2136)
* wmwragg/chat invite dialog fix
[\#2134](https://github.com/vector-im/vector-web/pull/2134)
* Wmwragg/one to one chat
[\#2110](https://github.com/vector-im/vector-web/pull/2110)
* Support toggling DM status of rooms
[\#2111](https://github.com/vector-im/vector-web/pull/2111)
* Formatting toolbar for RTE message composer.
[\#2082](https://github.com/vector-im/vector-web/pull/2082)
* jenkins.sh: install olm from jenkins artifacts
[\#2092](https://github.com/vector-im/vector-web/pull/2092)
* e2e device CSS
[\#2085](https://github.com/vector-im/vector-web/pull/2085)
* Bump to olm 1.1.0
[\#2069](https://github.com/vector-im/vector-web/pull/2069)
* Improve readability of the changelog dialog
[\#2056](https://github.com/vector-im/vector-web/pull/2056)
* Turn react consistency checks back on in develop builds
[\#2009](https://github.com/vector-im/vector-web/pull/2009)
* Wmwragg/direct chat sublist
[\#2028](https://github.com/vector-im/vector-web/pull/2028)
Changes in [0.7.5-r3](https://github.com/vector-im/vector-web/releases/tag/v0.7.5-r3) (2016-09-02)
==================================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.5-r2...v0.7.5-r3)
* Bump to matrix-react-sdk 0.6.5-r3 in order to fix bug #2020 (tightloop when flooded with join events)
Changes in [0.7.5-r2](https://github.com/vector-im/vector-web/releases/tag/v0.7.5-r2) (2016-09-01)
==================================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.5-r1...v0.7.5-r2)
* Bump to matrix-react-sdk 0.6.5-r1 in order to fix guest access
Changes in [0.7.5-r1](https://github.com/vector-im/vector-web/releases/tag/v0.7.5-r1) (2016-08-28)
==================================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.5...v0.7.5-r1)
* Correctly pin deps :(
Changes in [0.7.5](https://github.com/vector-im/vector-web/releases/tag/v0.7.5) (2016-08-28)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.4-r1...v0.7.5)
* re-add leave button in RoomSettings
* add /user URLs
* recognise matrix.to links and other vector links
* fix linkify dependency
* fix avatar clicking in MemberInfo
* fix RoomTagContextMenu so it works on historical rooms
* warn people to put their Matrix HS on a separate domain to Vector
* fix zalgos again
* Add .travis.yml
[\#2007](https://github.com/vector-im/vector-web/pull/2007)
* add fancy changelog dialog
[\#1972](https://github.com/vector-im/vector-web/pull/1972)
* Update autocomplete design
[\#1978](https://github.com/vector-im/vector-web/pull/1978)
* Update encryption info in README
[\#2001](https://github.com/vector-im/vector-web/pull/2001)
* Added event/info message avatars back in
[\#2000](https://github.com/vector-im/vector-web/pull/2000)
* Wmwragg/chat message presentation
[\#1987](https://github.com/vector-im/vector-web/pull/1987)
* Make the notification slider work
[\#1982](https://github.com/vector-im/vector-web/pull/1982)
* Use cpx to copy olm.js, and add watcher
[\#1966](https://github.com/vector-im/vector-web/pull/1966)
* Make up a device display name
[\#1959](https://github.com/vector-im/vector-web/pull/1959)
Changes in [0.7.4-r1](https://github.com/vector-im/vector-web/releases/tag/v0.7.4-r1) (2016-08-12)
==================================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.4...v0.7.4-r1)
* Update to matrix-react-sdk 0.6.4-r1 to fix inviting multiple people
Changes in [0.7.4](https://github.com/vector-im/vector-web/releases/tag/v0.7.4) (2016-08-11)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.3...v0.7.4)
* Don't show border on composer when not in RTE mode
[\#1954](https://github.com/vector-im/vector-web/pull/1954)
* Wmwragg/room tag menu
[\#1941](https://github.com/vector-im/vector-web/pull/1941)
* Don't redirect to mobile app if verifying 3pid
[\#1951](https://github.com/vector-im/vector-web/pull/1951)
* Make sure that we clear localstorage before *all* tests
[\#1950](https://github.com/vector-im/vector-web/pull/1950)
* Basic CSS for multi-invite dialog
[\#1942](https://github.com/vector-im/vector-web/pull/1942)
* More tests for the loading process:
[\#1947](https://github.com/vector-im/vector-web/pull/1947)
* Support for refactored login token handling
[\#1946](https://github.com/vector-im/vector-web/pull/1946)
* Various fixes and improvements to emojification.
[\#1935](https://github.com/vector-im/vector-web/pull/1935)
* More app-loading tests
[\#1938](https://github.com/vector-im/vector-web/pull/1938)
* Some tests of the application load process
[\#1936](https://github.com/vector-im/vector-web/pull/1936)
* Add 'enable labs' setting to sample config
[\#1930](https://github.com/vector-im/vector-web/pull/1930)
* Matthew/scalar
[\#1928](https://github.com/vector-im/vector-web/pull/1928)
* Fix unit tests
[\#1929](https://github.com/vector-im/vector-web/pull/1929)
* Wmwragg/mute mention state fix
[\#1926](https://github.com/vector-im/vector-web/pull/1926)
* CSS for deactivate account dialog
[\#1919](https://github.com/vector-im/vector-web/pull/1919)
* Wmwragg/mention state menu
[\#1900](https://github.com/vector-im/vector-web/pull/1900)
* Fix UnknownBody styling for #1901
[\#1913](https://github.com/vector-im/vector-web/pull/1913)
* Exclude olm from the webpack
[\#1914](https://github.com/vector-im/vector-web/pull/1914)
* Wmwragg/button updates
[\#1912](https://github.com/vector-im/vector-web/pull/1912)
* Wmwragg/button updates
[\#1828](https://github.com/vector-im/vector-web/pull/1828)
* CSS for device management UI
[\#1909](https://github.com/vector-im/vector-web/pull/1909)
* Fix a warning from RoomSubList
[\#1908](https://github.com/vector-im/vector-web/pull/1908)
* Fix notifications warning layout
[\#1907](https://github.com/vector-im/vector-web/pull/1907)
* Remove relayoutOnUpdate prop on gemini-scrollbar
[\#1883](https://github.com/vector-im/vector-web/pull/1883)
* Bump dependency versions
[\#1842](https://github.com/vector-im/vector-web/pull/1842)
* Wmwragg/mention state indicator round 2
[\#1835](https://github.com/vector-im/vector-web/pull/1835)
* Wmwragg/spinner fix
[\#1822](https://github.com/vector-im/vector-web/pull/1822)
* Wmwragg/mention state indicator
[\#1823](https://github.com/vector-im/vector-web/pull/1823)
* Revert "Presentation for inline link"
[\#1809](https://github.com/vector-im/vector-web/pull/1809)
* Wmwragg/modal restyle
[\#1806](https://github.com/vector-im/vector-web/pull/1806)
* Presentation for inline link
[\#1799](https://github.com/vector-im/vector-web/pull/1799)
* CSS for offline user colours
[\#1798](https://github.com/vector-im/vector-web/pull/1798)
* Wmwragg/typography updates
[\#1776](https://github.com/vector-im/vector-web/pull/1776)
* webpack: always use the olm from vector-web
[\#1766](https://github.com/vector-im/vector-web/pull/1766)
* feat: large emoji support
[\#1718](https://github.com/vector-im/vector-web/pull/1718)
* Autocomplete
[\#1717](https://github.com/vector-im/vector-web/pull/1717)
* #1664 Set a maximum height for codeblocks
[\#1670](https://github.com/vector-im/vector-web/pull/1670)
* CSS for device blocking
[\#1688](https://github.com/vector-im/vector-web/pull/1688)
* Fix joining rooms by typing the alias
[\#1685](https://github.com/vector-im/vector-web/pull/1685)
* Add ability to delete an alias from room directory
[\#1680](https://github.com/vector-im/vector-web/pull/1680)
* package.json: add olm as optionalDependency
[\#1678](https://github.com/vector-im/vector-web/pull/1678)
* Another go at enabling olm on vector.im/develop
[\#1675](https://github.com/vector-im/vector-web/pull/1675)
* CSS for unverify button
[\#1661](https://github.com/vector-im/vector-web/pull/1661)
* CSS fix for rooms with crypto enabled
[\#1660](https://github.com/vector-im/vector-web/pull/1660)
* Karma: fix warning by ignoring olm
[\#1652](https://github.com/vector-im/vector-web/pull/1652)
* Update for react-sdk dbkr/fix_peeking branch
[\#1639](https://github.com/vector-im/vector-web/pull/1639)
* Update README.md
[\#1641](https://github.com/vector-im/vector-web/pull/1641)
* Fix karma tests
[\#1643](https://github.com/vector-im/vector-web/pull/1643)
* Rich Text Editor
[\#1553](https://github.com/vector-im/vector-web/pull/1553)
* Fix RoomDirectory to join by alias whenever possible.
[\#1615](https://github.com/vector-im/vector-web/pull/1615)
* Make the config optional
[\#1612](https://github.com/vector-im/vector-web/pull/1612)
* CSS support for device verification
[\#1610](https://github.com/vector-im/vector-web/pull/1610)
* Don't use SdkConfig
[\#1609](https://github.com/vector-im/vector-web/pull/1609)
* serve config.json statically instead of bundling it
[\#1516](https://github.com/vector-im/vector-web/pull/1516)
Changes in [0.7.3](https://github.com/vector-im/vector-web/releases/tag/v0.7.3) (2016-06-03)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.2...v0.7.3)
* Update to react-sdk 0.6.3
Changes in [0.7.2](https://github.com/vector-im/vector-web/releases/tag/v0.7.2) (2016-06-02)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.1...v0.7.2)
* Correctly bump the dep on new matrix-js-sdk and matrix-react-sdk
Changes in [0.7.1](https://github.com/vector-im/vector-web/releases/tag/v0.7.1) (2016-06-02)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.0...v0.7.1)
* Fix accidentally committed local changes to the default config.json (doh!)
Changes in [0.7.0](https://github.com/vector-im/vector-web/releases/tag/v0.7.0) (2016-06-02)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.6.1...v0.7.0)
* 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)
@@ -48,7 +414,7 @@ Changes in vector v0.1.2 (2015-10-28)
* Better hover-over on member list
* Support CAS auth
* Many other bug fixes
Changes in vector v0.1.1 (2015-08-10)
======================================
+178 -52
View File
@@ -3,63 +3,162 @@ Vector/Web
Vector is a Matrix web client built using the Matrix React SDK (https://github.com/matrix-org/matrix-react-sdk).
Getting started
Getting Started
===============
The easiest way to test Vector is to just use the hosted copy at https://vector.im/beta.
The develop branch is continuously deployed by Jenkins at https://vector.im/develop for
those who like living dangerously.
To host your own copy of Vector, the quickest bet is to use a pre-built released version
of Vector:
1. Download the latest version from https://vector.im/packages/
1. Untar the tarball on your web server
1. Move (or symlink) the vector-x.x.x directory to an appropriate name
1. If desired, copy `config.sample.json` to `config.json` and edit it
as desired. See below for details.
1. Enter the URL into your browser and log into vector!
Important Security Note
=======================
We do not recommend running Vector from the same domain name as your Matrix
homeserver. The reason is the risk of XSS (cross-site-scripting) vulnerabilities
that could occur if someone caused Vector to load and render malicious user generated
content from a Matrix API which then had trusted access to Vector (or other apps) due
to sharing the same domain.
We have put some coarse mitigations into place to try to protect against this situation,
but it's still not good practice to do it in the first place.
See https://github.com/vector-im/vector-web/issues/1977 for more details.
Building From Source
====================
Vector is a modular webapp built with modern ES6 and requires a npm build system to build.
1. Install or update `node.js` so that your `npm` is at least at version `2.0.0`
1. Clone the repo: `git clone https://github.com/vector-im/vector-web.git`
1. Clone the repo: `git clone https://github.com/vector-im/vector-web.git`
1. Switch to the vector directory: `cd vector-web`
1. Install the prerequisites: `npm install`
1. If you are using the `develop` branch of vector, you will probably need to
rebuild one of the dependencies, due to https://github.com/npm/npm/issues/3055:
`(cd node_modules/matrix-react-sdk && npm install)`
1. Start the development builder and a testing server: `npm start`
1. Wait a few seconds for the initial build to finish (the command won't
terminate: it's running a web server for you).
1. Open http://127.0.0.1:8080/ in your browser to see your newly built Vector.
1. Configure the app by copying `config.sample.json` to `config.json` and modifying
it (see below for details)
1. `npm run package` to build a tarball to deploy. Untaring this file will give
a version-specific directory containing all the files that need to go on your
web server.
With `npm start`, any changes you make to the source files will cause a rebuild so
your changes will show up when you refresh. This development server also disables
caching, so do NOT use it in production.
Note that `npm run package` is not supported on Windows, so Windows users can run `npm
run build`, which will build all the necessary files into the `vector`
directory. The version of Vector will not appear in Settings without
using the package script. You can then mount the vector directory on your
webserver to actually serve up the app, which is entirely static content.
Configuring
config.json
===========
Configure the app by modifying the `config.json` file:
You can configure the app by copying `vector/config.sample.json` to
`vector/config.json` and customising it:
1. `default_hs_url` is the default home server url.
1. `default_is_url` is the default identity server url (this is the server used
for verifying third party identifiers like email addresses). If this is blank,
registering with an email address or adding an email address to your account
will not work.
registering with an email address, adding an email address to your account,
or inviting users via email address will not work. Matrix identity servers are
very simple web services which map third party identifiers (currently only email
addresses) to matrix IDs: see http://matrix.org/docs/spec/identity_service/unstable.html
for more details. Currently the only public matrix identity servers are https://matrix.org
and https://vector.im. In future identity servers will be decentralised.
1. `roomDirectory`: config for the public room directory. This section encodes behaviour
on the room directory screen for filtering the list by server / network type and joining
third party networks. This config section will disappear once APIs are available to
get this information for home servers. This section is optional.
1. `roomDirectory.servers`: List of other Home Servers' directories to include in the drop
down list. Optional.
1. `roomDirectory.serverConfig`: Config for each server in `roomDirectory.servers`. Optional.
1. `roomDirectory.serverConfig.<server_name>.networks`: List of networks (named
in `roomDirectory.networks`) to include for this server. Optional.
1. `roomDirectory.networks`: config for each network type. Optional.
1. `roomDirectory.<network_type>.name`: Human-readable name for the network. Required.
1. `roomDirectory.<network_type>.protocol`: Protocol as given by the server in
`/_matrix/client/unstable/thirdparty/protocols` response. Required to be able to join
this type of third party network.
1. `roomDirectory.<network_type>.domain`: Domain as given by the server in
`/_matrix/client/unstable/thirdparty/protocols` response, if present. Required to be
able to join this type of third party network, if present in `thirdparty/protocols`.
1. `roomDirectory.<network_type>.portalRoomPattern`: Regular expression matching aliases
for portal rooms to locations on this network. Required.
1. `roomDirectory.<network_type>.icon`: URL to an icon to be displayed for this network. Required.
1. `roomDirectory.<network_type>.example`: Textual example of a location on this network,
eg. '#channel' for an IRC network. Optional.
1. `roomDirectory.<network_type>.nativePattern`: Regular expression that matches a
valid location on this network. This is used as a hint to the user to indicate
when a valid location has been entered so it's not necessary for this to be
exactly correct. Optional.
You will need to re-run `npm run build` after editing `config.json`.
Running as a Desktop app
========================
Deployment
==========
In future we'll do an official distribution of Vector as an desktop app. Meanwhile,
there are a few options:
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.
@asdf:matrix.org points out that you can use nativefier and it just works(tm):
```
sudo npm install nativefier -g
nativefier https://vector.im/beta/
```
krisa has a dedicated electron project at https://github.com/krisak/vector-electron-desktop
(although you should swap out the 'vector' folder for the latest vector tarball you want to run.
Get a tarball from https://vector.im/packages or build your own - see Building From Source
above).
There's also a (much) older electron distribution at https://github.com/stevenhammerton/vector-desktop
The package script is not supported on Windows, so Windows users can run `npm
run build`, which will build all the necessary files into the `vector`
directory. Note that the version of Vector will not appear in Settings without
using the package script. You can then mount the vector directory on your
webserver to actually serve up the app, which is entirely static content.
Development
===========
For simple tweaks, you can work on any of the source files within Vector with
the setup above, and your changes will cause an instant rebuild.
Before attempting to develop on Vector you **must** read the developer guide
for `matrix-react-sdk` at https://github.com/matrix-org/matrix-react-sdk, which
also defines the design, architecture and style for Vector too.
However, much of the functionality in Vector is actually in the
`matrix-react-sdk` and `matrix-js-sdk` modules. It is possible to set these up
in a way that makes it easy to track the `develop` branches in git and to make
local changes without having to manually rebuild each time.
The idea of Vector is to be a relatively lightweight "skin" of customisations on
top of the underlying `matrix-react-sdk`. `matrix-react-sdk` provides both the
higher and lower level React components useful for building Matrix communication
apps using React.
[Be aware that there may be problems with this process under npm version 3.]
After creating a new component you must run `npm run reskindex` to regenerate
the `component-index.js` for the app (used in future for skinning)
**However, as of July 2016 this layering abstraction is broken due to rapid
development on Vector forcing `matrix-react-sdk` to move fast at the expense of
maintaining a clear abstraction between the two.** Hacking on Vector inevitably
means hacking equally on `matrix-react-sdk`, and there are bits of
`matrix-react-sdk` behaviour incorrectly residing in the `vector-web` project
(e.g. matrix-react-sdk specific CSS), and a bunch of Vector specific behaviour
in the `matrix-react-sdk` (grep for Vector). This separation problem will be
solved asap once development on Vector (and thus matrix-react-sdk) has
stabilised. Until then, the two projects should basically be considered as a
single unit. In particular, `matrix-react-sdk` issues are currently filed
against `vector-web` in github.
Please note that Vector is intended to run correctly without access to the public
internet. So please don't depend on resources (JS libs, CSS, images, fonts)
hosted by external CDNs or servers but instead please package all dependencies
into Vector itself.
Setting up a dev environment
============================
Much of the functionality in Vector is actually in the `matrix-react-sdk` and
`matrix-js-sdk` modules. It is possible to set these up in a way that makes it
easy to track the `develop` branches in git and to make local changes without
having to manually rebuild each time.
First clone and build `matrix-js-sdk`:
@@ -102,17 +201,53 @@ Finally, build and start vector itself:
+ 1013 hidden modules
```
Remember, the command will not terminate since it runs the web server
and rebuilds source files when they change.
and rebuilds source files when they change. This development server also
disables caching, so do NOT use it in production.
1. Open http://127.0.0.1:8080/ in your browser to see your newly built Vector.
When you make changes to `matrix-js-sdk` or `matrix-react-sdk`, you will need
to run `npm run build` in the relevant directory. You can do this automatically
by instead running `npm start` in each directory, to start a development
builder which will watch for changes to the files and rebuild automatically.
When you make changes to `matrix-react-sdk`, you will need to run `npm run
build` in the relevant directory. You can do this automatically by instead
running `npm start` in the directory, to start a development builder which
will watch for changes to the files and rebuild automatically.
If you add or remove any components from the Vector skin, you will need to rebuild
the skin's index by running, `npm run reskindex`.
If any of these steps error with, `file table overflow`, you are probably on a mac
which has a very low limit on max open files. Run `ulimit -Sn 1024` and try again.
You'll need to do this in each new terminal you open before building vector.
Filing issues
=============
All issues for Vector-web and Matrix-react-sdk should be filed at
https://github.com/matrix-org/matrix-react-sdk/issues
Triaging issues
===============
Issues will be triaged by the core team using the following primary set of tags:
priority:
P1: top priority; typically blocks releases.
P2: one below that
P3: non-urgent
P4/P5: bluesky some day, who knows.
bug or feature:
bug severity:
* cosmetic - feature works functionally but UI/UX is broken.
* critical - whole app doesn't work
* major - entire feature doesn't work
* minor - partially broken feature (but still usable)
* release blocker
* ui/ux (think of this as cosmetic)
* network (specific to network conditions)
* platform (platform specific)
Enabling encryption
===================
@@ -121,23 +256,14 @@ 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`.)
To enable the (very experimental) support, check the 'End-to-End Encryption'
box in the 'Labs' section of the user settings (note that the labs are disabled
on http://vector.im/beta: you will need to use http://vector.im/develop or your
own deployment of vector). The Room Settings dialog will then show an
'Encryption' setting; rooms for which you are an administrator will offer you
the option of enabling encryption. Any messages sent in that room will then be
encrypted.
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.
-4
View File
@@ -1,4 +0,0 @@
{
"default_hs_url": "https://matrix.org",
"default_is_url": "https://vector.im"
}
+14 -4
View File
@@ -5,8 +5,8 @@ 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
arg_jenkins_url, arg_extract_path, arg_should_clean, arg_symlink, arg_config_location = (
None, None, None, None, None
)
def download_file(url):
@@ -122,6 +122,9 @@ def on_receive_jenkins_poke():
create_symlink(source=os.path.join(untar_location, "vector"), linkname=arg_symlink)
if arg_config_location:
create_symlink(source=arg_config_location, linkname=os.path.join(untar_location, "vector", 'config.json'))
return jsonify({})
if __name__ == "__main__":
@@ -154,6 +157,12 @@ if __name__ == "__main__":
to the /vector directory INSIDE the tarball."
)
)
parser.add_argument(
"--config", dest="config", help=(
"Write a symlink to config.json in the extracted tarball. \
To this location."
)
)
args = parser.parse_args()
if args.jenkins.endswith("/"): # important for urljoin
arg_jenkins_url = args.jenkins
@@ -162,9 +171,10 @@ if __name__ == "__main__":
arg_extract_path = args.extract
arg_should_clean = args.clean
arg_symlink = args.symlink
arg_config_location = args.config
print(
"Listening on port %s. Extracting to %s%s. Symlinking to %s. Jenkins URL: %s" %
"Listening on port %s. Extracting to %s%s. Symlinking to %s. Jenkins URL: %s. Config location: %s" %
(args.port, arg_extract_path,
" (clean after)" if arg_should_clean else "", arg_symlink, arg_jenkins_url)
" (clean after)" if arg_should_clean else "", arg_symlink, arg_jenkins_url, arg_config_location)
)
app.run(host="0.0.0.0", port=args.port, debug=True)
+14 -2
View File
@@ -4,17 +4,29 @@ set -e
export NVM_DIR="/home/jenkins/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm use 4
nvm use 6
set -x
npm install
# apparently npm 3.10.3 on node 6.4.0 doesn't upgrade #develop target with npm install unless explicitly asked.
npm install matrix-react-sdk matrix-js-sdk
# install olm. A naive 'npm i ./olm/olm-*.tgz' fails because it uses the url
# from our package.json (or even matrix-js-sdk's) in preference.
tar -C olm -xz < olm/olm-*.tgz
rm -r node_modules/olm
cp -r olm/package node_modules/olm
# 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
npm run build:dev
# gzip up ./vector
rm vector-*.tar.gz || true # rm previous artifacts without failing if it doesn't exist
+142
View File
@@ -0,0 +1,142 @@
// 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: [
'node_modules/babel-polyfill/browser.js',
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'),
],
},
plugins: [
// olm may not be installed, so avoid webpack warnings by
// ignoring it.
new webpack.IgnorePlugin(/^olm$/),
],
devtool: 'inline-source-map',
},
});
};
+48 -17
View File
@@ -1,6 +1,6 @@
{
"name": "vector-web",
"version": "0.4.0",
"version": "0.8.3",
"description": "Vector webapp",
"author": "matrix.org",
"repository": {
@@ -12,53 +12,84 @@
"matrix-react-parent": "matrix-react-sdk",
"scripts": {
"reskindex": "reskindex -h src/header",
"build:emojione": "cpx \"node_modules/emojione/assets/svg/*\" vector/emojione/svg/",
"build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js",
"build:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css --no-watch",
"build:compile": "babel --source-maps -d lib src",
"build:bundle": "NODE_ENV=production webpack -p lib/vector/index.js vector/bundle.js",
"build": "npm run build:css && npm run build:compile && npm run build:bundle",
"build:bundle:dev": "webpack --optimize-occurence-order lib/vector/index.js vector/bundle.js",
"build:staticfiles": "cpx -v node_modules/olm/olm.js vector/",
"build": "npm run build:staticfiles && npm run build:emojione && npm run build:css && npm run build:compile && npm run build:bundle",
"build:dev": "npm run build:staticfiles && npm run build:emojione && npm run build:css && npm run build:compile && npm run build:bundle:dev",
"package": "scripts/package.sh",
"start:emojione": "cpx \"node_modules/emojione/assets/svg/*\" vector/emojione/svg/ -w",
"start:js": "webpack -w src/vector/index.js vector/bundle.js",
"start:js:prod": "NODE_ENV=production webpack -w src/vector/index.js vector/bundle.js",
"start:skins:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css",
"start:staticfiles": "cpx -Lwv node_modules/olm/olm.js vector/",
"//cache": "Note the -c 1 below due to https://code.google.com/p/chromium/issues/detail?id=508270",
"start": "parallelshell \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
"start:prod": "parallelshell \"npm run start:js:prod\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
"clean": "rimraf lib vector/bundle.css vector/bundle.js vector/bundle.js.map vector/webpack.css*",
"prepublish": "npm run build:css && npm run build:compile"
"start": "parallelshell \"npm run start:staticfiles\" \"npm run start:emojione\" \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
"start:prod": "parallelshell \"npm run start:staticfiles\" \"npm run start:emojione\" \"npm run start:js:prod\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
"clean": "rimraf lib vector/olm.js vector/bundle.css vector/bundle.js vector/bundle.js.map vector/webpack.css* vector/emojione",
"prepublish": "npm run build:css && npm run build:compile",
"test": "karma start --single-run=true --autoWatch=false --browsers PhantomJS --colors=false",
"test:multi": "karma start"
},
"dependencies": {
"babel-polyfill": "^6.5.0",
"browser-request": "^0.3.3",
"classnames": "^2.1.2",
"draft-js": "^0.8.1",
"extract-text-webpack-plugin": "^0.9.1",
"filesize": "^3.1.2",
"flux": "~2.0.3",
"gemini-scrollbar": "matrix-org/gemini-scrollbar#7dc736d",
"gemini-scrollbar": "matrix-org/gemini-scrollbar#b302279",
"gfm.css": "^1.1.1",
"highlight.js": "^9.0.0",
"linkifyjs": "^2.0.0-beta.4",
"matrix-js-sdk": "^0.5.0",
"matrix-react-sdk": "^0.3.0",
"linkifyjs": "^2.1.3",
"matrix-js-sdk": "0.6.3",
"matrix-react-sdk": "0.7.4",
"modernizr": "^3.1.0",
"q": "^1.4.1",
"react": "^0.14.2",
"react-dnd": "^2.0.2",
"react-dnd-html5-backend": "^2.0.0",
"react-dom": "^0.14.2",
"react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#869a86b",
"sanitize-html": "^1.11.1"
"react": "^15.2.1",
"react-dnd": "^2.1.4",
"react-dnd-html5-backend": "^2.1.2",
"react-dom": "^15.2.1",
"react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef",
"sanitize-html": "^1.11.1",
"ua-parser-js": "^0.7.10",
"url": "^0.11.0"
},
"devDependencies": {
"babel": "^5.8.23",
"babel-core": "^5.8.25",
"babel-loader": "^5.3.2",
"catw": "^1.0.1",
"cpx": "^1.3.2",
"css-raw-loader": "^0.1.1",
"emojione": "^2.2.3",
"expect": "^1.16.0",
"fs-extra": "^0.30.0",
"http-server": "^0.8.4",
"json-loader": "^0.5.3",
"karma": "^0.13.22",
"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-perf": "^15.0",
"react-addons-test-utils": "^15.0.1",
"rimraf": "^2.4.3",
"source-map-loader": "^0.1.5",
"webpack": "^1.12.13"
"webpack": "^1.12.14"
},
"optionalDependencies": {
"olm": "https://matrix.org/packages/npm/olm/olm-1.3.0.tgz"
}
}
+124
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
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";
}
+1
View File
@@ -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;
});
};
+11 -4
View File
@@ -19,6 +19,9 @@ limitations under the License.
* 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;
@@ -29,7 +32,13 @@ module.exports.components['structures.LeftPanel'] = require('./components/struct
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.context_menus.MessageContextMenu'] = require('./components/views/context_menus/MessageContextMenu');
module.exports.components['views.context_menus.NotificationStateContextMenu'] = require('./components/views/context_menus/NotificationStateContextMenu');
module.exports.components['views.context_menus.RoomTagContextMenu'] = require('./components/views/context_menus/RoomTagContextMenu');
module.exports.components['views.dialogs.ChangelogDialog'] = require('./components/views/dialogs/ChangelogDialog');
module.exports.components['views.directory.NetworkDropdown'] = require('./components/views/directory/NetworkDropdown');
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');
@@ -40,11 +49,9 @@ module.exports.components['views.login.VectorLoginFooter'] = require('./componen
module.exports.components['views.login.VectorLoginHeader'] = require('./components/views/login/VectorLoginHeader');
module.exports.components['views.messages.DateSeparator'] = require('./components/views/messages/DateSeparator');
module.exports.components['views.messages.MessageTimestamp'] = require('./components/views/messages/MessageTimestamp');
module.exports.components['views.messages.SenderProfile'] = require('./components/views/messages/SenderProfile');
module.exports.components['views.rooms.BottomLeftMenuTile'] = require('./components/views/rooms/BottomLeftMenuTile');
module.exports.components['views.rooms.MessageContextMenu'] = require('./components/views/rooms/MessageContextMenu');
module.exports.components['views.rooms.RoomDNDView'] = require('./components/views/rooms/RoomDNDView');
module.exports.components['views.rooms.DNDRoomTile'] = require('./components/views/rooms/DNDRoomTile');
module.exports.components['views.rooms.RoomDropTarget'] = require('./components/views/rooms/RoomDropTarget');
module.exports.components['views.rooms.RoomTooltip'] = require('./components/views/rooms/RoomTooltip');
module.exports.components['views.rooms.SearchBar'] = require('./components/views/rooms/SearchBar');
module.exports.components['views.settings.IntegrationsManager'] = require('./components/views/settings/IntegrationsManager');
module.exports.components['views.settings.Notifications'] = require('./components/views/settings/Notifications');
+79 -15
View File
@@ -17,42 +17,106 @@ limitations under the License.
'use strict';
var React = require('react');
var ReactDOM = require('react-dom');
var sdk = require('matrix-react-sdk')
var dis = require('matrix-react-sdk/lib/dispatcher');
module.exports = React.createClass({
displayName: 'BottomLeftMenu',
propTypes: {
collapsed: React.PropTypes.bool.isRequired,
},
getInitialState: function() {
return({
directoryHover : false,
roomsHover : false,
peopleHover : false,
settingsHover : false,
});
},
// Room events
onDirectoryClick: function() {
dis.dispatch({ action: 'view_room_directory' });
},
onDirectoryMouseEnter: function() {
this.setState({ directoryHover: true });
},
onDirectoryMouseLeave: function() {
this.setState({ directoryHover: false });
},
onRoomsClick: function() {
dis.dispatch({ action: 'view_create_room' });
},
onRoomsMouseEnter: function() {
this.setState({ roomsHover: true });
},
onRoomsMouseLeave: function() {
this.setState({ roomsHover: false });
},
// People events
onPeopleClick: function() {
dis.dispatch({ action: 'view_create_chat' });
},
onPeopleMouseEnter: function() {
this.setState({ peopleHover: true });
},
onPeopleMouseLeave: function() {
this.setState({ peopleHover: false });
},
// Settings events
onSettingsClick: function() {
dis.dispatch({action: 'view_user_settings'});
dis.dispatch({ action: 'view_user_settings' });
},
onRoomDirectoryClick: function() {
dis.dispatch({action: 'view_room_directory'});
onSettingsMouseEnter: function() {
this.setState({ settingsHover: true });
},
onCreateRoomClick: function() {
dis.dispatch({action: 'view_create_room'});
onSettingsMouseLeave: function() {
this.setState({ settingsHover: false });
},
getLabel: function(name) {
if (!this.props.collapsed) {
return <div className="mx_RoomTile_name">{name}</div>
}
else if (this.state.hover) {
// Get the label/tooltip to show
getLabel: function(label, show) {
if (show) {
var RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
return <RoomTooltip name={name}/>;
return <RoomTooltip className="mx_BottomLeftMenu_tooltip" label={label} />;
}
},
render: function() {
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.svg" label="Start chat" onClick={ this.onCreateRoomClick }/>
<BottomLeftMenuTile collapsed={ this.props.collapsed } img="img/directory-big.svg" label="Directory" onClick={ this.onRoomDirectoryClick }/>
<BottomLeftMenuTile collapsed={ this.props.collapsed } img="img/settings-big.svg" label="Settings" onClick={ this.onSettingsClick }/>
<div className="mx_BottomLeftMenu_people" onClick={ this.onPeopleClick } onMouseEnter={ this.onPeopleMouseEnter } onMouseLeave={ this.onPeopleMouseLeave } >
<TintableSvg src="img/icons-people.svg" width="25" height="25" />
{ this.getLabel("Start chat", this.state.peopleHover) }
</div>
<div className="mx_BottomLeftMenu_directory" onClick={ this.onDirectoryClick } onMouseEnter={ this.onDirectoryMouseEnter } onMouseLeave={ this.onDirectoryMouseLeave } >
<TintableSvg src="img/icons-directory.svg" width="25" height="25"/>
{ this.getLabel("Room directory", this.state.directoryHover) }
</div>
<div className="mx_BottomLeftMenu_createRoom" onClick={ this.onRoomsClick } onMouseEnter={ this.onRoomsMouseEnter } onMouseLeave={ this.onRoomsMouseLeave } >
<TintableSvg src="img/icons-create-room.svg" width="25" height="25" />
{ this.getLabel("Create new room", this.state.roomsHover) }
</div>
<div className="mx_BottomLeftMenu_settings" onClick={ this.onSettingsClick } onMouseEnter={ this.onSettingsMouseEnter } onMouseLeave={ this.onSettingsMouseLeave } >
<TintableSvg src="img/icons-settings.svg" width="25" height="25" />
{ this.getLabel("Settings", this.state.settingsHover) }
</div>
</div>
</div>
);
@@ -39,14 +39,14 @@ module.exports = React.createClass({
return (
<div className="mx_CompatibilityPage">
<div className="mx_CompatibilityPage_box">
<p>Sorry, your browser is <b>not</b> able to run Vector.</p>
<p>Sorry, your browser is <b>not</b> able to run Riot.</p>
<p>
Vector uses many advanced browser features, some of which are not
Riot 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>,
Please install <a href="https://www.google.com/chrome">Chrome</a> or
<a href="https://getfirefox.com">Firefox</a> for the best experience.
<a href="http://apple.com/safari">Safari</a> and
<a href="http://opera.com">Opera</a> work too.
</p>
+12 -4
View File
@@ -31,6 +31,7 @@ var LeftPanel = React.createClass({
getInitialState: function() {
return {
showCallElement: null,
searchFilter: '',
};
},
@@ -79,17 +80,22 @@ var LeftPanel = React.createClass({
if (call) {
dis.dispatch({
action: 'view_room',
room_id: call.roomId,
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";
var classes = "mx_LeftPanel mx_fadable";
if (this.props.collapsed) {
classes += " collapsed";
}
@@ -103,18 +109,20 @@ var LeftPanel = React.createClass({
var CallView = sdk.getComponent('voip.CallView');
callPreview = (
<CallView
className="mx_LeftPanel_callView" onClick={this.onCallViewClick}
className="mx_LeftPanel_callView" showVoice={true} onClick={this.onCallViewClick}
ConferenceHandler={VectorConferenceHandler} />
);
}
return (
<aside className={classes}>
<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>
+128 -25
View File
@@ -17,17 +17,26 @@ limitations under the License.
'use strict';
var React = require('react');
var sdk = require('matrix-react-sdk')
var sdk = require('matrix-react-sdk');
var Matrix = require("matrix-js-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');
var Modal = require('matrix-react-sdk/lib/Modal');
module.exports = React.createClass({
displayName: 'RightPanel',
propTypes: {
userId: React.PropTypes.string, // if showing an orphaned MemberInfo page, this is set
roomId: React.PropTypes.string, // if showing panels for a given room, this is set
collapsed: React.PropTypes.bool, // currently unused property to request for a minimized view of the panel
},
Phase : {
MemberList: 'MemberList',
FileList: 'FileList',
FilePanel: 'FilePanel',
NotificationPanel: 'NotificationPanel',
MemberInfo: 'MemberInfo',
},
@@ -45,13 +54,22 @@ module.exports = React.createClass({
},
getInitialState: function() {
return {
phase : this.Phase.MemberList
if (this.props.userId) {
var member = new Matrix.RoomMember(null, this.props.userId);
return {
phase: this.Phase.MemberInfo,
member: member,
}
}
else {
return {
phase: this.Phase.MemberList
}
}
},
onMemberListButtonClick: function() {
if (this.props.collapsed) {
if (this.props.collapsed || this.state.phase !== this.Phase.MemberList) {
this.setState({ phase: this.Phase.MemberList });
dis.dispatch({
action: 'show_right_panel',
@@ -64,6 +82,51 @@ module.exports = React.createClass({
}
},
onFileListButtonClick: function() {
if (this.props.collapsed || this.state.phase !== this.Phase.FilePanel) {
this.setState({ phase: this.Phase.FilePanel });
dis.dispatch({
action: 'show_right_panel',
});
}
else {
dis.dispatch({
action: 'hide_right_panel',
});
}
},
onNotificationListButtonClick: function() {
if (this.props.collapsed || this.state.phase !== this.Phase.NotificationPanel) {
this.setState({ phase: this.Phase.NotificationPanel });
dis.dispatch({
action: 'show_right_panel',
});
}
else {
dis.dispatch({
action: 'hide_right_panel',
});
}
},
onInviteButtonClick: function() {
if (MatrixClientPeg.get().isGuest()) {
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
Modal.createDialog(NeedToRegisterDialog, {
title: "Please Register",
description: "Guest users can't invite users. Please register to invite."
});
return;
}
// call ChatInviteDialog
dis.dispatch({
action: 'view_invite',
roomId: this.props.roomId,
});
},
onRoomStateMember: function(ev, state, member) {
// redraw the badge on the membership list
if (this.state.phase == this.Phase.MemberList && member.roomId === this.props.roomId) {
@@ -97,7 +160,7 @@ module.exports = React.createClass({
});
}
}
if (payload.action === "view_room") {
else if (payload.action === "view_room") {
if (this.state.phase === this.Phase.MemberInfo) {
this.setState({
phase: this.Phase.MemberList
@@ -108,67 +171,107 @@ module.exports = React.createClass({
render: function() {
var MemberList = sdk.getComponent('rooms.MemberList');
var NotificationPanel = sdk.getComponent('structures.NotificationPanel');
var FilePanel = sdk.getComponent('structures.FilePanel');
var TintableSvg = sdk.getComponent("elements.TintableSvg");
var buttonGroup;
var inviteGroup;
var panel;
var filesHighlight;
var membersHighlight;
var notificationsHighlight;
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) {
else if (this.state.phase == this.Phase.FilePanel) {
filesHighlight = <div className="mx_RightPanel_headerButton_highlight"></div>;
}
else if (this.state.phase == this.Phase.NotificationPanel) {
notificationsHighlight = <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);
var user_is_in_room;
if (room) {
membersBadge = <div className="mx_RightPanel_headerButton_badge">{ room.getJoinedMembers().length }</div>;
membersBadge = room.getJoinedMembers().length;
user_is_in_room = room.hasMembershipState(
MatrixClientPeg.get().credentials.userId, 'join'
);
}
if (user_is_in_room) {
inviteGroup =
<div className="mx_RightPanel_invite" onClick={ this.onInviteButtonClick } >
<div className="mx_RightPanel_icon" >
<TintableSvg src="img/icon-invite-people.svg" width="35" height="35" />
</div>
<div className="mx_RightPanel_message">Invite to this room</div>
</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 }
<div className="mx_RightPanel_headerButton_badge">{ membersBadge ? membersBadge : <span>&nbsp;</span>}</div>
<TintableSvg src="img/icons-people.svg" width="25" height="25"/>
{ membersHighlight }
</div>
<div className="mx_RightPanel_headerButton mx_RightPanel_filebutton" title="Files">
<TintableSvg src="img/files.svg" width="17" height="22"/>
<div className="mx_RightPanel_headerButton mx_RightPanel_filebutton" title="Files" onClick={ this.onFileListButtonClick }>
<div className="mx_RightPanel_headerButton_badge">&nbsp;</div>
<TintableSvg src="img/icons-files.svg" width="25" height="25"/>
{ filesHighlight }
</div>
<div className="mx_RightPanel_headerButton mx_RightPanel_notificationbutton" title="Notifications" onClick={ this.onNotificationListButtonClick }>
<div className="mx_RightPanel_headerButton_badge">&nbsp;</div>
<TintableSvg src="img/icons-notifications.svg" width="25" height="25"/>
{ notificationsHighlight }
</div>
</div>;
if (!this.props.collapsed) {
if(this.state.phase == this.Phase.MemberList) {
panel = <MemberList roomId={this.props.roomId} key={this.props.roomId} />
}
else if(this.state.phase == this.Phase.MemberInfo) {
var MemberInfo = sdk.getComponent('rooms.MemberInfo');
panel = <MemberInfo roomId={this.props.roomId} member={this.state.member} key={this.props.roomId} />
}
}
}
var classes = "mx_RightPanel";
if (!this.props.collapsed) {
if(this.props.roomId && 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 member={this.state.member} key={this.props.roomId || this.props.userId} />
}
else if (this.state.phase == this.Phase.NotificationPanel) {
panel = <NotificationPanel />
}
else if (this.state.phase == this.Phase.FilePanel) {
panel = <FilePanel roomId={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}>
<aside className={classes} style={{ opacity: this.props.opacity }}>
<div className="mx_RightPanel_header">
{ buttonGroup }
</div>
{ panel }
<div className="mx_RightPanel_footer">
{ inviteGroup }
</div>
</aside>
);
}
+505 -75
View File
@@ -21,7 +21,7 @@ var React = require('react');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var ContentRepo = require("matrix-js-sdk").ContentRepo;
var Modal = require('matrix-react-sdk/lib/Modal');
var sdk = require('matrix-react-sdk')
var sdk = require('matrix-react-sdk');
var dis = require('matrix-react-sdk/lib/dispatcher');
var GeminiScrollbar = require('react-gemini-scrollbar');
@@ -29,91 +29,361 @@ var linkify = require('linkifyjs');
var linkifyString = require('linkifyjs/string');
var linkifyMatrix = require('matrix-react-sdk/lib/linkify-matrix');
var sanitizeHtml = require('sanitize-html');
var q = require('q');
linkifyMatrix(linkify);
module.exports = React.createClass({
displayName: 'RoomDirectory',
propTypes: {
config: React.PropTypes.object,
},
getDefaultProps: function() {
return {
config: {
networks: [],
},
}
},
getInitialState: function() {
return {
publicRooms: [],
roomAlias: '',
loading: true,
network: null,
roomServer: null,
filterString: null,
}
},
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
});
componentWillMount: function() {
// precompile Regexps
this.portalRoomPatterns = {};
this.nativePatterns = {};
if (this.props.config.networks) {
for (const network of Object.keys(this.props.config.networks)) {
const network_info = this.props.config.networks[network];
if (network_info.portalRoomPattern) {
this.portalRoomPatterns[network] = new RegExp(network_info.portalRoomPattern);
}
if (network_info.nativePattern) {
this.nativePatterns[network] = new RegExp(network_info.nativePattern);
}
}
else {
self.setState({
publicRooms: data.chunk,
loading: false,
}
this.nextBatch = null;
this.filterTimeout = null;
this.scrollPanel = null;
this.protocols = null;
MatrixClientPeg.get().getThirdpartyProtocols().done((response) => {
this.protocols = response;
}, (err) => {
if (MatrixClientPeg.get().isGuest()) {
// Guests currently aren't allowed to use this API, so
// ignore this as otherwise this error is literally the
// thing you see when loading the client!
return;
}
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to get protocol list from Home Server",
description: "The Home Server may be too old to support third party networks",
});
});
// dis.dispatch({
// action: 'ui_opacity',
// sideOpacity: 0.3,
// middleOpacity: 0.3,
// });
},
componentWillUnmount: function() {
// dis.dispatch({
// action: 'ui_opacity',
// sideOpacity: 1.0,
// middleOpacity: 1.0,
// });
},
refreshRoomList: function() {
this.nextBatch = null;
this.setState({
publicRooms: [],
loading: true,
});
this.getMoreRooms().done();
},
getMoreRooms: function() {
if (!MatrixClientPeg.get()) return q();
const my_filter_string = this.state.filterString;
const my_server = this.state.roomServer;
// remember the next batch token when we sent the request
// too. If it's changed, appending to the list will corrupt it.
const my_next_batch = this.nextBatch;
const opts = {limit: 20};
if (my_server != MatrixClientPeg.getHomeServerName()) {
opts.server = my_server;
}
if (this.nextBatch) opts.since = this.nextBatch;
if (my_filter_string) opts.filter = { generic_search_term: my_filter_string } ;
return MatrixClientPeg.get().publicRooms(opts).then((data) => {
if (
my_filter_string != this.state.filterString ||
my_server != this.state.roomServer ||
my_next_batch != this.nextBatch)
{
// if the filter or server has changed since this request was sent,
// throw away the result (don't even clear the busy flag
// since we must still have a request in flight)
return;
}
this.nextBatch = data.next_batch;
this.setState((s) => {
s.publicRooms.push(...data.chunk);
s.loading = false;
return s;
});
return Boolean(data.next_batch);
}, (err) => {
if (
my_filter_string != this.state.filterString ||
my_server != this.state.roomServer ||
my_next_batch != this.nextBatch)
{
// as above: we don't care about errors for old
// requests either
return;
}
this.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
});
});
},
/**
* A limited interface for removing rooms from the directory.
* Will set the room to not be publicly visible and delete the
* default alias. In the long term, it would be better to allow
* HS admins to do this through the RoomSettings interface, but
* this needs SPEC-417.
*/
removeFromDirectory: function(room) {
var alias = get_display_alias_for_room(room);
var name = room.name || alias || "Unnamed room";
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
var desc;
if (alias) {
desc = `Delete the room alias '${alias}' and remove '${name}' from the directory?`;
} else {
desc = `Remove '${name}' from the directory?`;
}
Modal.createDialog(QuestionDialog, {
title: "Remove from Directory",
description: desc,
onFinished: (should_delete) => {
if (!should_delete) return;
var Loader = sdk.getComponent("elements.Spinner");
var modal = Modal.createDialog(Loader);
var step = `remove '${name}' from the directory.`;
MatrixClientPeg.get().setRoomDirectoryVisibility(room.room_id, 'private').then(() => {
if (!alias) return;
step = 'delete the alias.';
return MatrixClientPeg.get().deleteAlias(alias);
}).done(() => {
modal.close();
this.refreshRoomList();
}, function(err) {
modal.close();
this.refreshRoomList();
Modal.createDialog(ErrorDialog, {
title: "Failed to "+step,
description: err.toString()
});
});
self.forceUpdate();
}
});
},
showRoom: function(roomId) {
// extract the metadata from the publicRooms structure to pass
// as out-of-band data to view_room, because we get information
// here that we can't get other than by joining the room in some
// cases.
var room;
for (var i = 0; i < this.state.publicRooms.length; ++i) {
if (this.state.publicRooms[i].room_id == roomId) {
room = this.state.publicRooms[i];
break;
}
onRoomClicked: function(room, ev) {
if (ev.shiftKey) {
ev.preventDefault();
this.removeFromDirectory(room);
} else {
this.showRoom(room);
}
var oob_data = {};
},
onOptionChange: function(server, network) {
// clear next batch so we don't try to load more rooms
this.nextBatch = null;
this.setState({
// Clear the public rooms out here otherwise we needlessly
// spend time filtering lots of rooms when we're about to
// to clear the list anyway.
publicRooms: [],
roomServer: server,
network: network,
}, this.refreshRoomList);
// We also refresh the room list each time even though this
// filtering is client-side. It hopefully won't be client side
// for very long, and we may have fetched a thousand rooms to
// find the five gitter ones, at which point we do not want
// to render all those rooms when switching back to 'all networks'.
// Easiest to just blow away the state & re-fetch.
},
onFillRequest: function(backwards) {
if (backwards || !this.nextBatch) return q(false);
return this.getMoreRooms();
},
onFilterChange: function(alias) {
this.setState({
filterString: alias || null,
});
// don't send the request for a little bit,
// no point hammering the server with a
// request for every keystroke, let the
// user finish typing.
if (this.filterTimeout) {
clearTimeout(this.filterTimeout);
}
this.filterTimeout = setTimeout(() => {
this.filterTimeout = null;
this.refreshRoomList();
}, 300);
},
onFilterClear: function() {
// update immediately
this.setState({
filterString: null,
}, this.refreshRoomList);
if (this.filterTimeout) {
clearTimeout(this.filterTimeout);
}
},
onJoinClick: function(alias) {
// If we're on the 'Matrix' network (or all networks),
// just show that rooms alias
if (this.state.network == null || this.state.network == '_matrix') {
this.showRoomAlias(alias);
} else {
// This is a 3rd party protocol. Let's see if we
// can join it
const fields = this._getFieldsForThirdPartyLocation(alias, this.state.network);
if (!fields) {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Unable to join network",
description: "Riot does not know how to join a room on this network",
});
return;
}
const protocol = this._protocolForThirdPartyNetwork(this.state.network);
MatrixClientPeg.get().getThirdpartyLocation(protocol, fields).done((resp) => {
if (resp.length > 0 && resp[0].alias) {
this.showRoomAlias(resp[0].alias);
} else {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Room not found",
description: "Couldn't find a matching Matrix room",
});
}
}, (e) => {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Fetching third party location failed",
description: "Unable to look up room ID from server",
});
});
}
},
showRoomAlias: function(alias) {
this.showRoom(null, alias);
},
showRoom: function(room, room_alias) {
var payload = {action: 'view_room'};
if (room) {
oob_data = {
// Don't let the user view a room they won't be able to either
// peek or join: fail earlier so they don't have to click back
// to the directory.
if (MatrixClientPeg.get().isGuest()) {
if (!room.world_readable && !room.guest_can_join) {
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
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;
}
}
if (!room_alias) {
room_alias = get_display_alias_for_room(room);
}
payload.oob_data = {
avatarUrl: room.avatar_url,
// XXX: This logic is duplicated from the JS SDK which
// would normally decide what the name is.
name: room.name || room.canonical_alias || (room.aliases ? room.aliases[0] : "Unnamed room"),
name: room.name || room_alias || "Unnamed room",
};
}
dis.dispatch({
action: 'view_room',
room_id: roomId,
oob_data: oob_data,
});
// It's not really possible to join Matrix rooms by ID because the HS has no way to know
// which servers to start querying. However, there's no other way to join rooms in
// this list without aliases at present, so if roomAlias isn't set here we have no
// choice but to supply the ID.
if (room_alias) {
payload.room_alias = room_alias;
} else {
payload.room_id = room.room_id;
}
dis.dispatch(payload);
},
getRows: function(filter) {
getRows: function() {
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 rooms = this.state.publicRooms.filter((a) => {
if (this.state.network) {
if (!this._isRoomInNetwork(a, this.state.roomServer, this.state.network)) return false;
}
return true;
});
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";
var name = rooms[i].name || get_display_alias_for_room(rooms[i]) || "Unnamed room";
guestRead = null;
guestJoin = null;
@@ -136,8 +406,12 @@ module.exports = React.createClass({
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)}>
rows.push(
<tr key={ rooms[i].room_id }
onClick={self.onRoomClicked.bind(self, rooms[i])}
// cancel onMouseDown otherwise shift-clicking highlights text
onMouseDown={(ev) => {ev.preventDefault();}}
>
<td className="mx_RoomDirectory_roomAvatar">
<BaseAvatar width={24} height={24} resizeMethod='crop'
name={ name } idName={ name }
@@ -151,7 +425,7 @@ module.exports = React.createClass({
<div className="mx_RoomDirectory_topic"
onClick={ function(e) { e.stopPropagation() } }
dangerouslySetInnerHTML={{ __html: topic }}/>
<div className="mx_RoomDirectory_alias">{ alias }</div>
<div className="mx_RoomDirectory_alias">{ get_display_alias_for_room(rooms[i]) }</div>
</td>
<td className="mx_RoomDirectory_roomMemberCount">
{ rooms[i].num_joined_members }
@@ -162,40 +436,196 @@ module.exports = React.createClass({
return rows;
},
onKeyUp: function(ev) {
this.forceUpdate();
this.setState({ roomAlias : this.refs.roomAlias.value })
if (ev.key == "Enter") {
this.showRoom(this.refs.roomAlias.value);
collectScrollPanel: function(element) {
this.scrollPanel = element;
},
/**
* Terrible temporary function that guess what network a public room
* entry is in, until synapse is able to tell us
*/
_isRoomInNetwork: function(room, server, network) {
// We carve rooms into two categories here. 'portal' rooms are
// rooms created by a user joining a bridge 'portal' alias to
// participate in that room or a foreign network. A room is a
// portal room if it has exactly one alias and that alias matches
// a pattern defined in the config. Its network is the key
// of the pattern that it matches.
// All other rooms are considered 'native matrix' rooms, and
// go into the special '_matrix' network.
let roomNetwork = '_matrix';
if (room.aliases && room.aliases.length == 1) {
if (this.props.config.serverConfig && this.props.config.serverConfig[server] && this.props.config.serverConfig[server].networks) {
for (const n of this.props.config.serverConfig[server].networks) {
const pat = this.portalRoomPatterns[n];
if (pat && pat.test(room.aliases[0])) {
roomNetwork = n;
}
}
}
}
return roomNetwork == network;
},
_stringLooksLikeId: function(s, network) {
let pat = /^#[^\s]+:[^\s]/;
if (
network && network != '_matrix' &&
this.nativePatterns[network]
) {
pat = this.nativePatterns[network];
}
return pat.test(s);
},
_protocolForThirdPartyNetwork: function(network) {
if (
this.props.config.networks &&
this.props.config.networks[network] &&
this.props.config.networks[network].protocol
) {
return this.props.config.networks[network].protocol;
}
},
render: function() {
if (this.state.loading) {
var Loader = sdk.getComponent("elements.Spinner");
return (
<div className="mx_RoomDirectory">
<Loader />
</div>
);
_getFieldsForThirdPartyLocation: function(user_input, network) {
if (!this.props.config.networks || !this.props.config.networks[network]) return null;
const network_info = this.props.config.networks[network];
if (!network_info.protocol) return null;
if (!this.protocols) return null;
let matched_instance;
// Try to find which instance in the 'protocols' response
// matches this network. We look for a matching protocol
// and the existence of a 'domain' field and if present,
// its value.
if (
this.protocols[network_info.protocol] &&
this.protocols[network_info.protocol].instances &&
this.protocols[network_info.protocol].instances.length == 1
) {
const the_instance = this.protocols[network_info.protocol].instances[0];
// If there's only one instance in this protocol, use it
// as long as it has no domain (which we assume to mean it's
// there is only one possible instance).
if (
(
the_instance.fields.domain === undefined &&
network_info.domain === undefined
) ||
(
the_instance.fields.domain !== undefined &&
the_instance.fields.domain == network_info.domain
)
) {
matched_instance = the_instance;
}
} else if (network_info.domain) {
// otherwise, we look for one with a matching domain.
for (const this_instance of this.protocols[network_info.protocol].instances) {
if (this_instance.fields.domain == network_info.domain) {
matched_instance = this_instance;
}
}
}
var RoomHeader = sdk.getComponent('rooms.RoomHeader');
if (matched_instance === undefined) return null;
// now make an object with the fields specified by that protocol. We
// require that the values of all but the last field come from the
// instance. The last is the user input.
const required_fields = this.protocols[network_info.protocol].location_fields;
const fields = {};
for (let i = 0; i < required_fields.length - 1; ++i) {
const this_field = required_fields[i];
if (matched_instance.fields[this_field] === undefined) return null;
fields[this_field] = matched_instance.fields[this_field];
}
fields[required_fields[required_fields.length - 1]] = user_input;
return fields;
},
render: function() {
let content;
if (this.state.loading) {
const Loader = sdk.getComponent("elements.Spinner");
content = <div className="mx_RoomDirectory">
<Loader />
</div>;
} else {
const rows = this.getRows();
// we still show the scrollpanel, at least for now, because
// otherwise we don't fetch more because we don't get a fill
// request from the scrollpanel because there isn't one
let scrollpanel_content;
if (rows.length == 0) {
scrollpanel_content = <i>No rooms to show</i>;
} else {
scrollpanel_content = <table ref="directory_table" className="mx_RoomDirectory_table">
<tbody>
{ this.getRows() }
</tbody>
</table>;
}
const ScrollPanel = sdk.getComponent("structures.ScrollPanel");
content = <ScrollPanel ref={this.collectScrollPanel}
className="mx_RoomDirectory_tableWrapper"
onFillRequest={ this.onFillRequest }
stickyBottom={false}
startAtBottom={false}
onResize={function(){}}
>
{ scrollpanel_content }
</ScrollPanel>;
}
let placeholder = 'Search for a room';
if (this.state.network === null || this.state.network === '_matrix') {
placeholder = '#example:' + this.state.roomServer;
} else if (
this.props.config.networks &&
this.props.config.networks[this.state.network] &&
this.props.config.networks[this.state.network].example &&
this._getFieldsForThirdPartyLocation(this.state.filterString, this.state.network)
) {
placeholder = this.props.config.networks[this.state.network].example;
}
let showJoinButton = this._stringLooksLikeId(this.state.filterString, this.state.network);
if (this.state.network && this.state.network != '_matrix') {
if (this._getFieldsForThirdPartyLocation(this.state.filterString, this.state.network) === null) {
showJoinButton = false;
}
}
const SimpleRoomHeader = sdk.getComponent('rooms.SimpleRoomHeader');
const NetworkDropdown = sdk.getComponent('directory.NetworkDropdown');
const DirectorySearchBox = sdk.getComponent('elements.DirectorySearchBox');
return (
<div className="mx_RoomDirectory">
<RoomHeader simpleHeader="Directory" />
<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">
<table ref="directory_table" className="mx_RoomDirectory_table">
<tbody>
{ this.getRows(this.state.roomAlias) }
</tbody>
</table>
</GeminiScrollbar>
<div className="mx_RoomDirectory_listheader">
<DirectorySearchBox
className="mx_RoomDirectory_searchbox"
onChange={this.onFilterChange} onClear={this.onFilterClear} onJoinClick={this.onJoinClick}
placeholder={placeholder} showJoinButton={showJoinButton}
/>
<NetworkDropdown config={this.props.config} onOptionChange={this.onOptionChange} />
</div>
{content}
</div>
</div>
);
}
});
// Similar to matrix-react-sdk's MatrixTools.getDisplayAliasForRoom
// but works with the objects we get from the public room list
function get_display_alias_for_room(room) {
return room.canonical_alias || (room.aliases ? room.aliases[0] : "");
}
+234 -35
View File
@@ -17,15 +17,21 @@ limitations under the License.
'use strict';
var React = require('react');
var ReactDOM = require('react-dom');
var classNames = require('classnames');
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');
var RoomNotifs = require('matrix-react-sdk/lib/RoomNotifs');
var FormattingUtils = require('matrix-react-sdk/lib/utils/FormattingUtils');
// turn this on for drop & drag console debugging galore
var debug = false;
const TRUNCATE_AT = 10;
var roomListTarget = {
canDrop: function() {
return true;
@@ -61,26 +67,26 @@ var RoomSubList = React.createClass({
label: React.PropTypes.string.isRequired,
tagName: React.PropTypes.string,
editable: React.PropTypes.bool,
order: React.PropTypes.string.isRequired,
selectedRoom: React.PropTypes.string.isRequired,
// undefined if no room is selected (eg we are showing settings)
selectedRoom: React.PropTypes.string,
startAsHidden: React.PropTypes.bool,
showSpinner: React.PropTypes.bool, // true to show a spinner if 0 elements when expanded
// TODO: Fix the name of this. This is too easily confused with the
// "hidden" state which is the expanded (or not) view of the list of rooms.
// What this prop *really* does is control whether the room name is displayed
// so it should be named as such.
collapsed: React.PropTypes.bool.isRequired,
collapsed: React.PropTypes.bool.isRequired, // is LeftPanel collapsed?
onHeaderClick: React.PropTypes.func,
alwaysShowHeader: React.PropTypes.bool,
incomingCall: React.PropTypes.object,
onShowMoreRooms: React.PropTypes.func
onShowMoreRooms: React.PropTypes.func,
searchFilter: React.PropTypes.string,
},
getInitialState: function() {
return {
hidden: this.props.startAsHidden || false,
truncateAt: 20,
truncateAt: TRUNCATE_AT,
sortedList: [],
};
},
@@ -93,26 +99,50 @@ var RoomSubList = React.createClass({
},
componentWillMount: function() {
this.sortList(this.props.list, this.props.order);
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(newProps.list, newProps.order);
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
});
},
// The header is collapsable if it is hidden or not stuck
// The dataset elements are added in the RoomList _initAndPositionStickyHeaders method
isCollapsableOnClick: function() {
var stuck = this.refs.header.dataset.stuck;
if (this.state.hidden || stuck === undefined || stuck === "none") {
return true;
} else {
return false;
}
},
onClick: function(ev) {
var isHidden = !this.state.hidden;
this.setState({ hidden : isHidden });
if (this.isCollapsableOnClick()) {
// The header isCollapsable, so the click is to be interpreted as collapse and truncation logic
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 : TRUNCATE_AT });
}
if (isHidden) {
// as good a way as any to reset the truncate state
this.setState({ truncateAt : 20 });
this.props.onShowMoreRooms();
this.props.onHeaderClick(isHidden);
} else {
// The header is stuck, so the click is to be interpreted as a scroll to the header
this.props.onHeaderClick(this.state.hidden, this.refs.header.dataset.originalPosition);
}
this.props.onHeaderClick(isHidden);
},
tsOfNewestEvent: function(room) {
@@ -142,11 +172,26 @@ var RoomSubList = React.createClass({
return this.tsOfNewestEvent(roomB) - this.tsOfNewestEvent(roomA);
},
lexicographicalComparator: function(roomA, roomB) {
return roomA.name > roomB.name ? 1 : -1;
},
// Generates the manual comparator using the given list
manualComparator: function(roomA, roomB) {
if (!roomA.tags[this.props.tagName] || !roomB.tags[this.props.tagName]) return 0;
// Make sure the room tag has an order element, if not set it to be the bottom
var a = roomA.tags[this.props.tagName].order;
var b = roomB.tags[this.props.tagName].order;
return a == b ? this.recentsComparator(roomA, roomB) : ( a > b ? 1 : -1);
// Order undefined room tag orders to the bottom
if (a === undefined && b !== undefined) {
return 1;
} else if (a !== undefined && b === undefined) {
return -1;
}
return a == b ? this.lexicographicalComparator(roomA, roomB) : ( a > b ? 1 : -1);
},
sortList: function(list, order) {
@@ -157,10 +202,59 @@ var RoomSubList = React.createClass({
if (order === "manual") comparator = this.manualComparator;
if (order === "recent") comparator = this.recentsComparator;
// Fix undefined orders here, and make sure the backend gets updated as well
this._fixUndefinedOrder(list);
//if (debug) console.log("sorting list for sublist " + this.props.label + " with length " + list.length + ", this.props.list = " + this.props.list);
this.setState({ sortedList: list.sort(comparator) });
},
_shouldShowNotifBadge: function(roomNotifState) {
const showBadgeInStates = [RoomNotifs.ALL_MESSAGES, RoomNotifs.ALL_MESSAGES_LOUD];
return showBadgeInStates.indexOf(roomNotifState) > -1;
},
_shouldShowMentionBadge: function(roomNotifState) {
return roomNotifState != RoomNotifs.MUTE;
},
/**
* Total up all the notification counts from the rooms
*
* @param {Number} If supplied will only total notifications for rooms outside the truncation number
* @returns {Array} The array takes the form [total, highlight] where highlight is a bool
*/
roomNotificationCount: function(truncateAt) {
var self = this;
return this.props.list.reduce(function(result, room, index) {
if (truncateAt === undefined || index >= truncateAt) {
var roomNotifState = RoomNotifs.getRoomNotifsState(room.roomId);
var highlight = room.getUnreadNotificationCount('highlight') > 0 || self.props.label === 'Invites';
var notificationCount = room.getUnreadNotificationCount();
const notifBadges = notificationCount > 0 && self._shouldShowNotifBadge(roomNotifState);
const mentionBadges = highlight && self._shouldShowMentionBadge(roomNotifState);
const badges = notifBadges || mentionBadges;
if (badges) {
result[0] += notificationCount;
if (highlight) {
result[1] = true;
}
}
}
return result;
}, [0, false]);
},
_updateSubListCount: function() {
// Force an update by setting the state to the current state
// Doing it this way rather than using forceUpdate(), so that the shouldComponentUpdate()
// method is honoured
this.setState(this.state);
},
moveRoomTile: function(room, atIndex) {
if (debug) console.log("moveRoomTile: id " + room.roomId + ", atIndex " + atIndex);
//console.log("moveRoomTile before: " + JSON.stringify(this.state.rooms));
@@ -254,12 +348,12 @@ var RoomSubList = React.createClass({
makeRoomTiles: function() {
var self = this;
var RoomTile = sdk.getComponent("rooms.RoomTile");
var DNDRoomTile = sdk.getComponent("rooms.DNDRoomTile");
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
<DNDRoomTile
room={ room }
roomSubList={ self }
key={ room.roomId }
@@ -268,32 +362,95 @@ var RoomSubList = React.createClass({
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 } />
refreshSubList={ self._updateSubListCount }
incomingCall={ null } />
);
});
},
_getHeaderJsx: function() {
var TintableSvg = sdk.getComponent("elements.TintableSvg");
var subListNotifications = this.roomNotificationCount();
var subListNotifCount = subListNotifications[0];
var subListNotifHighlight = subListNotifications[1];
var roomCount = this.props.list.length > 0 ? this.props.list.length : '';
var chevronClasses = classNames({
'mx_RoomSubList_chevron': true,
'mx_RoomSubList_chevronRight': this.state.hidden,
'mx_RoomSubList_chevronDown': !this.state.hidden,
});
var badgeClasses = classNames({
'mx_RoomSubList_badge': true,
'mx_RoomSubList_badgeHighlight': subListNotifHighlight,
});
var badge;
if (subListNotifCount > 0) {
badge = <div className={badgeClasses}>{ FormattingUtils.formatCount(subListNotifCount) }</div>;
}
// When collapsed, allow a long hover on the header to show user
// the full tag name and room count
var title;
if (this.props.collapsed) {
title = this.props.label;
if (roomCount !== '') {
title += " [" + roomCount + "]";
}
}
var incomingCall;
if (this.props.incomingCall) {
var self = this;
// Check if the incoming call is for this section
var incomingCallRoom = this.state.sortedList.filter(function(room) {
return self.props.incomingCall.roomId === room.roomId;
});
if (incomingCallRoom.length === 1) {
var IncomingCallBox = sdk.getComponent("voip.IncomingCallBox");
incomingCall = <IncomingCallBox className="mx_RoomSubList_incomingCall" incomingCall={ this.props.incomingCall }/>;
}
}
return (
<h2 onClick={ this.onClick } className="mx_RoomSubList_label">
{ this.props.collapsed ? '' : this.props.label }
<TintableSvg className="mx_RoomSubList_chevron"
src={ this.state.hidden ? "img/list-close.svg" : "img/list-open.svg" }
width="10" height="10" />
</h2>
<div className="mx_RoomSubList_labelContainer" title={ title } ref="header">
<div onClick={ this.onClick } className="mx_RoomSubList_label">
{ this.props.collapsed ? '' : this.props.label }
<div className="mx_RoomSubList_roomCount">{ roomCount }</div>
<div className={chevronClasses}></div>
{ badge }
{ incomingCall }
</div>
</div>
);
},
_createOverflowTile: function(overflowCount, totalCount) {
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
// XXX: this is duplicated from RoomTile - factor it out
var content = <div className="mx_RoomSubList_chevronDown"></div>;
var overflowNotifications = this.roomNotificationCount(TRUNCATE_AT);
var overflowNotifCount = overflowNotifications[0];
var overflowNotifHighlight = overflowNotifications[1];
if (overflowNotifCount && !this.props.collapsed) {
content = FormattingUtils.formatCount(overflowNotifCount);
}
var badgeClasses = classNames({
'mx_RoomSubList_moreBadge': true,
'mx_RoomSubList_moreBadgeNotify': overflowNotifCount && !this.props.collapsed,
'mx_RoomSubList_moreBadgeHighlight': overflowNotifHighlight && !this.props.collapsed,
});
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 className="mx_RoomSubList_ellipsis" onClick={this._showFullMemberList}>
<div className="mx_RoomSubList_line"></div>
<div className="mx_RoomSubList_more">more</div>
<div className={ badgeClasses }>{ content }</div>
</div>
);
},
@@ -302,7 +459,49 @@ var RoomSubList = React.createClass({
this.setState({
truncateAt: -1
});
this.props.onShowMoreRooms();
this.props.onHeaderClick(false);
},
// Fix any undefined order elements of a room in a manual ordered list
// room.tag[tagname].order
_fixUndefinedOrder: function(list) {
if (this.props.order === "manual") {
var order = 0.0;
var self = this;
// Find the highest (lowest position) order of a room in a manual ordered list
list.forEach(function(room) {
if (room.tags.hasOwnProperty(self.props.tagName)) {
if (order < room.tags[self.props.tagName].order) {
order = room.tags[self.props.tagName].order;
}
}
});
// Fix any undefined order elements of a room in a manual ordered list
// Do this one at a time, as each time a rooms tag data is updated the RoomList
// gets triggered and another list is passed in. Doing it one at a time means that
// we always correctly calculate the highest order for the list - stops multiple
// rooms getting the same order. This is only really relevant for the first time this
// is run with historical room tag data, after that there should only be undefined
// in the list at a time anyway.
for (let i = 0; i < list.length; i++) {
if (list[i].tags[self.props.tagName] && list[i].tags[self.props.tagName].order === undefined) {
MatrixClientPeg.get().setRoomTag(list[i].roomId, self.props.tagName, {order: (order + 1.0) / 2.0}).finally(function() {
// Do any final stuff here
}).fail(function(err) {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to add tag " + self.props.tagName + " to room",
description: err.toString()
});
});
break;
};
};
}
},
render: function() {
+119
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/icons-search-copy.svg" width="13" height="13"
/>,
<input
key="searchfield"
type="text"
ref="search"
className="mx_SearchBox_search"
value={ this.state.searchTerm }
onChange={ this.onChange }
placeholder="Filter room names"
/>
];
}
var self = this;
return (
<div className="mx_SearchBox">
{ searchControls }
{ toggleCollapse }
</div>
);
}
});
@@ -20,13 +20,25 @@ var React = require('react');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var dis = require('matrix-react-sdk/lib/dispatcher');
var sdk = require('matrix-react-sdk')
var sdk = require('matrix-react-sdk');
var Modal = require('matrix-react-sdk/lib/Modal');
var Resend = require("matrix-react-sdk/lib/Resend");
import * as UserSettingsStore from 'matrix-react-sdk/lib/UserSettingsStore';
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() {
Resend.resend(this.props.mxEvent);
if (this.props.onFinished) this.props.onFinished();
@@ -36,7 +48,7 @@ module.exports = React.createClass({
var ViewSource = sdk.getComponent('structures.ViewSource');
Modal.createDialog(ViewSource, {
mxEvent: this.props.mxEvent
});
}, 'mx_Dialog_viewsource');
if (this.props.onFinished) this.props.onFinished();
},
@@ -66,6 +78,21 @@ module.exports = React.createClass({
if (this.props.onFinished) this.props.onFinished();
},
onUnhidePreviewClick: function() {
if (this.props.eventTileOps) {
this.props.eventTileOps.unhideWidget();
}
if (this.props.onFinished) this.props.onFinished();
},
onQuoteClick: function () {
console.log(this.props.mxEvent);
dis.dispatch({
action: 'quote',
event: this.props.mxEvent,
});
},
render: function() {
var eventStatus = this.props.mxEvent.status;
var resendButton;
@@ -73,10 +100,11 @@ module.exports = React.createClass({
var redactButton;
var cancelButton;
var permalinkButton;
var unhidePreviewButton;
if (eventStatus === 'not_sent') {
resendButton = (
<div className="mx_ContextualMenu_field" onClick={this.onResendClick}>
<div className="mx_MessageContextMenu_field" onClick={this.onResendClick}>
Resend
</div>
);
@@ -84,7 +112,7 @@ module.exports = React.createClass({
if (!eventStatus) { // sent
redactButton = (
<div className="mx_ContextualMenu_field" onClick={this.onRedactClick}>
<div className="mx_MessageContextMenu_field" onClick={this.onRedactClick}>
Redact
</div>
);
@@ -92,24 +120,39 @@ module.exports = React.createClass({
if (eventStatus === "queued" || eventStatus === "not_sent") {
cancelButton = (
<div className="mx_ContextualMenu_field" onClick={this.onCancelSendClick}>
<div className="mx_MessageContextMenu_field" onClick={this.onCancelSendClick}>
Cancel Sending
</div>
);
}
viewSourceButton = (
<div className="mx_ContextualMenu_field" onClick={this.onViewSourceClick}>
<div className="mx_MessageContextMenu_field" onClick={this.onViewSourceClick}>
View Source
</div>
);
// XXX: this should be https://matrix.to.
if (this.props.eventTileOps) {
if (this.props.eventTileOps.isWidgetHidden()) {
unhidePreviewButton = (
<div className="mx_MessageContextMenu_field" onClick={this.onUnhidePreviewClick}>
Unhide Preview
</div>
)
}
}
// 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 className="mx_MessageContextMenu_field">
<a href={ "https://matrix.to/#/" + this.props.mxEvent.getRoomId() +"/"+ this.props.mxEvent.getId() }
target="_blank" onClick={ this.onPermalinkClick }>Permalink</a>
</div>
);
const quoteButton = (
<div className="mx_MessageContextMenu_field" onClick={this.onQuoteClick}>
Quote
</div>
);
@@ -119,7 +162,9 @@ module.exports = React.createClass({
{redactButton}
{cancelButton}
{viewSourceButton}
{unhidePreviewButton}
{permalinkButton}
{UserSettingsStore.isFeatureEnabled('rich_text_editor') ? quoteButton : null}
</div>
);
}
@@ -0,0 +1,144 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var q = require("q");
var React = require('react');
var classNames = require('classnames');
var RoomNotifs = require('matrix-react-sdk/lib/RoomNotifs');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
module.exports = React.createClass({
displayName: 'NotificationStateContextMenu',
propTypes: {
room: React.PropTypes.object.isRequired,
/* callback called when the menu is dismissed */
onFinished: React.PropTypes.func,
},
getInitialState() {
return {
roomNotifState: RoomNotifs.getRoomNotifsState(this.props.room.roomId),
}
},
componentWillMount: function() {
this._unmounted = false;
},
componentWillUnmount: function() {
this._unmounted = true;
},
_save: function(newState) {
const oldState = this.state.roomNotifState;
const roomId = this.props.room.roomId;
var cli = MatrixClientPeg.get();
if (cli.isGuest()) return;
this.setState({
roomNotifState: newState,
});
RoomNotifs.setRoomNotifsState(this.props.room.roomId, newState).done(() => {
// delay slightly so that the user can see their state change
// before closing the menu
return q.delay(500).then(() => {
if (this._unmounted) return;
// Close the context menu
if (this.props.onFinished) {
this.props.onFinished();
};
});
}, (error) => {
// TODO: some form of error notification to the user
// to inform them that their state change failed.
// For now we at least set the state back
if (this._unmounted) return;
this.setState({
roomNotifState: oldState,
});
});
},
_onClickAlertMe: function() {
this._save(RoomNotifs.ALL_MESSAGES_LOUD);
},
_onClickAllNotifs: function() {
this._save(RoomNotifs.ALL_MESSAGES);
},
_onClickMentions: function() {
this._save(RoomNotifs.MENTIONS_ONLY);
},
_onClickMute: function() {
this._save(RoomNotifs.MUTE);
},
render: function() {
var alertMeClasses = classNames({
'mx_NotificationStateContextMenu_field': true,
'mx_NotificationStateContextMenu_fieldSet': this.state.roomNotifState == RoomNotifs.ALL_MESSAGES_LOUD,
});
var allNotifsClasses = classNames({
'mx_NotificationStateContextMenu_field': true,
'mx_NotificationStateContextMenu_fieldSet': this.state.roomNotifState == RoomNotifs.ALL_MESSAGES,
});
var mentionsClasses = classNames({
'mx_NotificationStateContextMenu_field': true,
'mx_NotificationStateContextMenu_fieldSet': this.state.roomNotifState == RoomNotifs.MENTIONS_ONLY,
});
var muteNotifsClasses = classNames({
'mx_NotificationStateContextMenu_field': true,
'mx_NotificationStateContextMenu_fieldSet': this.state.roomNotifState == RoomNotifs.MUTE,
});
return (
<div>
<div className="mx_NotificationStateContextMenu_picker" >
<img src="img/notif-slider.svg" width="20" height="107" />
</div>
<div className={ alertMeClasses } onClick={this._onClickAlertMe} >
<img className="mx_NotificationStateContextMenu_activeIcon" src="img/notif-active.svg" width="12" height="12" />
<img className="mx_NotificationStateContextMenu_icon" src="img/icon-context-mute-off-copy.svg" width="16" height="12" />
All messages (loud)
</div>
<div className={ allNotifsClasses } onClick={this._onClickAllNotifs} >
<img className="mx_NotificationStateContextMenu_activeIcon" src="img/notif-active.svg" width="12" height="12" />
<img className="mx_NotificationStateContextMenu_icon" src="img/icon-context-mute-off.svg" width="16" height="12" />
All messages
</div>
<div className={ mentionsClasses } onClick={this._onClickMentions} >
<img className="mx_NotificationStateContextMenu_activeIcon" src="img/notif-active.svg" width="12" height="12" />
<img className="mx_NotificationStateContextMenu_icon" src="img/icon-context-mute-mentions.svg" width="16" height="12" />
Mentions only
</div>
<div className={ muteNotifsClasses } onClick={this._onClickMute} >
<img className="mx_NotificationStateContextMenu_activeIcon" src="img/notif-active.svg" width="12" height="12" />
<img className="mx_NotificationStateContextMenu_icon" src="img/icon-context-mute.svg" width="16" height="12" />
Mute
</div>
</div>
);
}
});
@@ -0,0 +1,253 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var q = require("q");
var React = require('react');
var classNames = require('classnames');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var dis = require('matrix-react-sdk/lib/dispatcher');
var DMRoomMap = require('matrix-react-sdk/lib/utils/DMRoomMap');
var Rooms = require('matrix-react-sdk/lib/Rooms');
module.exports = React.createClass({
displayName: 'RoomTagContextMenu',
propTypes: {
room: React.PropTypes.object.isRequired,
/* callback called when the menu is dismissed */
onFinished: React.PropTypes.func,
},
getInitialState: function() {
const dmRoomMap = new DMRoomMap(MatrixClientPeg.get());
return {
isFavourite: this.props.room.tags.hasOwnProperty("m.favourite"),
isLowPriority: this.props.room.tags.hasOwnProperty("m.lowpriority"),
isDirectMessage: Boolean(dmRoomMap.getUserIdForRoomId(this.props.room.roomId)),
};
},
_toggleTag: function(tagNameOn, tagNameOff) {
var self = this;
const roomId = this.props.room.roomId;
var cli = MatrixClientPeg.get();
if (!cli.isGuest()) {
q.delay(500).then(function() {
if (tagNameOff !== null && tagNameOff !== undefined) {
cli.deleteRoomTag(roomId, tagNameOff).finally(function() {
// Close the context menu
if (self.props.onFinished) {
self.props.onFinished();
};
}).fail(function(err) {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to remove tag " + tagNameOff + " from room",
description: err.toString()
});
});
}
if (tagNameOn !== null && tagNameOn !== undefined) {
// If the tag ordering meta data is required, it is added by
// the RoomSubList when it sorts its rooms
cli.setRoomTag(roomId, tagNameOn, {}).finally(function() {
// Close the context menu
if (self.props.onFinished) {
self.props.onFinished();
};
}).fail(function(err) {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to add tag " + tagNameOn + " to room",
description: err.toString()
});
});
}
});
}
},
_onClickFavourite: function() {
// Tag room as 'Favourite'
if (!this.state.isFavourite && this.state.isLowPriority) {
this.setState({
isFavourite: true,
isLowPriority: false,
});
this._toggleTag("m.favourite", "m.lowpriority");
} else if (this.state.isFavourite) {
this.setState({isFavourite: false});
this._toggleTag(null, "m.favourite");
} else if (!this.state.isFavourite) {
this.setState({isFavourite: true});
this._toggleTag("m.favourite");
}
},
_onClickLowPriority: function() {
// Tag room as 'Low Priority'
if (!this.state.isLowPriority && this.state.isFavourite) {
this.setState({
isFavourite: false,
isLowPriority: true,
});
this._toggleTag("m.lowpriority", "m.favourite");
} else if (this.state.isLowPriority) {
this.setState({isLowPriority: false});
this._toggleTag(null, "m.lowpriority");
} else if (!this.state.isLowPriority) {
this.setState({isLowPriority: true});
this._toggleTag("m.lowpriority");
}
},
_onClickDM: function() {
const newIsDirectMessage = !this.state.isDirectMessage;
this.setState({
isDirectMessage: newIsDirectMessage,
});
if (MatrixClientPeg.get().isGuest()) return;
let newTarget;
if (newIsDirectMessage) {
const guessedTarget = Rooms.guessDMRoomTarget(
this.props.room,
this.props.room.getMember(MatrixClientPeg.get().credentials.userId),
);
newTarget = guessedTarget.userId;
} else {
newTarget = null;
}
// give some time for the user to see the icon change first, since
// this will hide the context menu once it completes
q.delay(500).done(() => {
return Rooms.setDMRoom(this.props.room.roomId, newTarget).finally(() => {
// Close the context menu
if (this.props.onFinished) {
this.props.onFinished();
};
}, (err) => {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Failed to set Direct Message status of room",
description: err.toString()
});
});
});
},
_onClickLeave: function() {
// Leave room
dis.dispatch({
action: 'leave_room',
room_id: this.props.room.roomId,
});
// Close the context menu
if (this.props.onFinished) {
this.props.onFinished();
};
},
_onClickForget: function() {
// FIXME: duplicated with RoomSettings (and dead code in RoomView)
MatrixClientPeg.get().forget(this.props.room.roomId).done(function() {
dis.dispatch({ action: 'view_next_room' });
}, function(err) {
var errCode = err.errcode || "unknown error code";
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Error",
description: `Failed to forget room (${errCode})`
});
});
// Close the context menu
if (this.props.onFinished) {
this.props.onFinished();
};
},
render: function() {
const myUserId = MatrixClientPeg.get().credentials.userId;
const myMember = this.props.room.getMember(myUserId);
const favouriteClasses = classNames({
'mx_RoomTagContextMenu_field': true,
'mx_RoomTagContextMenu_fieldSet': this.state.isFavourite,
'mx_RoomTagContextMenu_fieldDisabled': false,
});
const lowPriorityClasses = classNames({
'mx_RoomTagContextMenu_field': true,
'mx_RoomTagContextMenu_fieldSet': this.state.isLowPriority,
'mx_RoomTagContextMenu_fieldDisabled': false,
});
const leaveClasses = classNames({
'mx_RoomTagContextMenu_field': true,
'mx_RoomTagContextMenu_fieldSet': false,
'mx_RoomTagContextMenu_fieldDisabled': false,
});
const dmClasses = classNames({
'mx_RoomTagContextMenu_field': true,
'mx_RoomTagContextMenu_fieldSet': this.state.isDirectMessage,
'mx_RoomTagContextMenu_fieldDisabled': false,
});
if (myMember && myMember.membership === "leave") {
return (
<div>
<div className={ leaveClasses } onClick={ this._onClickForget } >
<img className="mx_RoomTagContextMenu_icon" src="img/icon_context_delete.svg" width="15" height="15" />
Forget
</div>
</div>
);
}
return (
<div>
<div className={ favouriteClasses } onClick={this._onClickFavourite} >
<img className="mx_RoomTagContextMenu_icon" src="img/icon_context_fave.svg" width="15" height="15" />
<img className="mx_RoomTagContextMenu_icon_set" src="img/icon_context_fave_on.svg" width="15" height="15" />
Favourite
</div>
<div className={ lowPriorityClasses } onClick={this._onClickLowPriority} >
<img className="mx_RoomTagContextMenu_icon" src="img/icon_context_low.svg" width="15" height="15" />
<img className="mx_RoomTagContextMenu_icon_set" src="img/icon_context_low_on.svg" width="15" height="15" />
Low Priority
</div>
<div className={ dmClasses } onClick={this._onClickDM} >
<img className="mx_RoomTagContextMenu_icon" src="img/icon_context_person.svg" width="15" height="15" />
<img className="mx_RoomTagContextMenu_icon_set" src="img/icon_context_person_on.svg" width="15" height="15" />
Direct Chat
</div>
<hr className="mx_RoomTagContextMenu_separator" />
<div className={ leaveClasses } onClick={(myMember && myMember.membership === "join") ? this._onClickLeave : null} >
<img className="mx_RoomTagContextMenu_icon" src="img/icon_context_delete.svg" width="15" height="15" />
Leave
</div>
</div>
);
}
});
@@ -0,0 +1,92 @@
/*
Copyright 2016 Aviral Dasgupta
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import sdk from 'matrix-react-sdk';
import request from 'browser-request';
const REPOS = ['vector-im/vector-web', 'matrix-org/matrix-react-sdk', 'matrix-org/matrix-js-sdk'];
export default class ChangelogDialog extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
const version = this.props.newVersion.split('-');
const version2 = this.props.version.split('-');
if(version == null || version2 == null) return;
for(let i=0; i<REPOS.length; i++) {
const oldVersion = version2[2*i+1];
const newVersion = version[2*i+1];
request(`https://api.github.com/repos/${REPOS[i]}/compare/${oldVersion}...${newVersion}`, (a, b, body) => {
if(body == null) return;
this.setState({[REPOS[i]]: JSON.parse(body).commits});
});
}
}
_elementsForCommit(commit) {
return (
<li key={commit.sha} className="mx_ChangelogDialog_li">
<a href={commit.html_url} target="_blank" ref="noopener">
{commit.commit.message}
</a>
</li>
);
}
render() {
const Spinner = sdk.getComponent('views.elements.Spinner');
const QuestionDialog = sdk.getComponent('dialogs.QuestionDialog');
const logs = REPOS.map(repo => {
if (this.state[repo] == null) return <Spinner key={repo} />;
return (
<div key={repo}>
<h2>{repo}</h2>
<ul>
{this.state[repo].map(this._elementsForCommit)}
</ul>
</div>
)
});
const content = (
<div className="mx_ChangelogDialog_content">
{this.props.version == null || this.props.newVersion == null ? <h2>Unavailable</h2> : logs}
</div>
);
return (
<QuestionDialog
title="Changelog"
description={content}
button="Update"
onFinished={this.props.onFinished}
/>
)
}
}
ChangelogDialog.propTypes = {
version: React.PropTypes.string.isRequired,
newVersion: React.PropTypes.string.isRequired,
onFinished: React.PropTypes.func.isRequired,
};
@@ -0,0 +1,244 @@
/*
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.
*/
import React from 'react';
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
export default class NetworkDropdown extends React.Component {
constructor(props) {
super(props);
this.dropdownRootElement = null;
this.ignoreEvent = null;
this.onInputClick = this.onInputClick.bind(this);
this.onRootClick = this.onRootClick.bind(this);
this.onDocumentClick = this.onDocumentClick.bind(this);
this.onMenuOptionClick = this.onMenuOptionClick.bind(this);
this.onInputKeyUp = this.onInputKeyUp.bind(this);
this.collectRoot = this.collectRoot.bind(this);
this.collectInputTextBox = this.collectInputTextBox.bind(this);
this.inputTextBox = null;
const server = MatrixClientPeg.getHomeServerName();
let defaultNetwork = null;
if (
this.props.config.serverConfig &&
this.props.config.serverConfig[server] &&
this.props.config.serverConfig[server].networks &&
this.props.config.serverConfig[server].networks.indexOf('_matrix') > -1
) {
defaultNetwork = '_matrix';
}
this.state = {
expanded: false,
selectedServer: server,
selectedNetwork: defaultNetwork,
};
}
componentWillMount() {
// Listen for all clicks on the document so we can close the
// menu when the user clicks somewhere else
document.addEventListener('click', this.onDocumentClick, false);
// fire this now so the defaults can be set up
this.props.onOptionChange(this.state.selectedServer, this.state.selectedNetwork);
}
componentWillUnmount() {
document.removeEventListener('click', this.onDocumentClick, false);
}
componentDidUpdate() {
if (this.state.expanded && this.inputTextBox) {
this.inputTextBox.focus();
}
}
onDocumentClick(ev) {
// Close the dropdown if the user clicks anywhere that isn't
// within our root element
if (ev !== this.ignoreEvent) {
this.setState({
expanded: false,
});
}
}
onRootClick(ev) {
// This captures any clicks that happen within our elements,
// such that we can then ignore them when they're seen by the
// click listener on the document handler, ie. not close the
// dropdown immediately after opening it.
// NB. We can't just stopPropagation() because then the event
// doesn't reach the React onClick().
this.ignoreEvent = ev;
}
onInputClick(ev) {
this.setState({
expanded: !this.state.expanded,
});
ev.preventDefault();
}
onMenuOptionClick(server, network, ev) {
this.setState({
expanded: false,
selectedServer: server,
selectedNetwork: network,
});
this.props.onOptionChange(server, network);
}
onInputKeyUp(e) {
if (e.key == 'Enter') {
this.setState({
expanded: false,
selectedServer: e.target.value,
selectedNetwork: null,
});
this.props.onOptionChange(e.target.value, null);
}
}
collectRoot(e) {
if (this.dropdownRootElement) {
this.dropdownRootElement.removeEventListener('click', this.onRootClick, false);
}
if (e) {
e.addEventListener('click', this.onRootClick, false);
}
this.dropdownRootElement = e;
}
collectInputTextBox(e) {
this.inputTextBox = e;
}
_getMenuOptions() {
const options = [];
let servers = [];
if (this.props.config.servers) {
servers = servers.concat(this.props.config.servers);
}
if (servers.indexOf(MatrixClientPeg.getHomeServerName()) == -1) {
servers.unshift(MatrixClientPeg.getHomeServerName());
}
for (const server of servers) {
options.push(this._makeMenuOption(server, null));
if (this.props.config.serverConfig && this.props.config.serverConfig[server] && this.props.config.serverConfig[server].networks) {
for (const network of this.props.config.serverConfig[server].networks) {
options.push(this._makeMenuOption(server, network));
}
}
}
return options;
}
_makeMenuOption(server, network, wire_onclick) {
if (wire_onclick === undefined) wire_onclick = true;
let icon;
let name;
let span_class;
if (network === null) {
name = server;
span_class = 'mx_NetworkDropdown_menu_all';
} else if (network == '_matrix') {
name = 'Matrix';
icon = <img src="img/network-matrix.svg" width="16" height="16" />;
span_class = 'mx_NetworkDropdown_menu_network';
} else {
if (this.props.config.networks[network] === undefined) {
throw new Error(network + ' network missing from config');
}
if (this.props.config.networks[network].name) {
name = this.props.config.networks[network].name;
} else {
name = network;
}
if (this.props.config.networks[network].icon) {
// omit height here so if people define a non-square logo in the config, it
// will keep the aspect when it scales
icon = <img src={this.props.config.networks[network].icon} width="16" />;
} else {
icon = <img src={iconPath} width="16" height="16" />;
}
span_class = 'mx_NetworkDropdown_menu_network';
}
const click_handler = wire_onclick ? this.onMenuOptionClick.bind(this, server, network) : null;
let key = server;
if (network !== null) {
key += '_' + network;
}
return <div key={key} className="mx_NetworkDropdown_networkoption" onClick={click_handler}>
{icon}
<span className={span_class}>{name}</span>
</div>;
}
render() {
let current_value;
let menu;
if (this.state.expanded) {
const menu_options = this._getMenuOptions();
menu = <div className="mx_NetworkDropdown_menu">
{menu_options}
</div>;
current_value = <input type="text" className="mx_NetworkDropdown_networkoption"
ref={this.collectInputTextBox} onKeyUp={this.onInputKeyUp}
placeholder="matrix.org" // 'matrix.org' as an example of an HS name
/>
} else {
current_value = this._makeMenuOption(
this.state.selectedServer, this.state.selectedNetwork, false
);
}
return <div className="mx_NetworkDropdown" ref={this.collectRoot}>
<div className="mx_NetworkDropdown_input" onClick={this.onInputClick}>
{current_value}
<span className="mx_NetworkDropdown_arrow"></span>
{menu}
</div>
</div>;
}
}
NetworkDropdown.propTypes = {
onOptionChange: React.PropTypes.func.isRequired,
config: React.PropTypes.object,
};
NetworkDropdown.defaultProps = {
config: {
networks: [],
}
};
+53 -18
View File
@@ -27,7 +27,19 @@ module.exports = React.createClass({
displayName: 'ImageView',
propTypes: {
onFinished: React.PropTypes.func.isRequired
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
@@ -65,6 +77,14 @@ module.exports = React.createClass({
});
},
getName: function () {
var name = this.props.name;
if (name && this.props.link) {
name = <a href={ this.props.link } target="_blank" rel="noopener">{ name }</a>;
}
return name;
},
render: function() {
/*
@@ -102,12 +122,36 @@ module.exports = React.createClass({
width: this.props.width,
height: this.props.height,
};
res = ", " + style.width + "x" + style.height + "px";
res = style.width + "x" + style.height + "px";
}
var size;
if (this.props.mxEvent.getContent().info && this.props.mxEvent.getContent().info.size) {
size = filesize(this.props.mxEvent.getContent().info.size);
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 (
@@ -122,25 +166,16 @@ module.exports = React.createClass({
<div className="mx_ImageView_shim">
</div>
<div className="mx_ImageView_name">
{ this.props.mxEvent.getContent().body }
{ this.getName() }
</div>
<div className="mx_ImageView_metadata">
Uploaded on { DateUtils.formatDate(new Date(this.props.mxEvent.getTs())) } by { this.props.mxEvent.getSender() }
</div>
<a className="mx_ImageView_link" href={ this.props.src } target="_blank">
{ eventMeta }
<a className="mx_ImageView_link" href={ this.props.src } target="_blank" rel="noopener">
<div className="mx_ImageView_download">
Download this file<br/>
<span className="mx_ImageView_size">{ size } { res }</span>
<span className="mx_ImageView_size">{ size_res }</span>
</div>
</a>
<div className="mx_ImageView_button">
<a className="mx_ImageView_link" href={ this.props.src } target="_blank">
View full screen
</a>
</div>
<div className="mx_ImageView_button" onClick={this.onRedactClick}>
Redact
</div>
{ eventRedact }
<div className="mx_ImageView_shim">
</div>
</div>
@@ -34,7 +34,7 @@ module.exports = React.createClass({
<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.
You are Rioting as a guest. <a onClick={this.onRegisterClicked}>Register</a> or <a onClick={this.onLoginClicked}>sign in</a> to access more rooms and features.
</div>
</div>
);
@@ -35,7 +35,7 @@ module.exports = React.createClass({
return (
<div className="mx_MatrixToolbar">
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="/!\"/>
<div>
<div className="mx_MatrixToolbar_content">
You are not receiving desktop notifications. <a className="mx_MatrixToolbar_link" onClick={ this.onClick }>Enable them now</a>
</div>
<div className="mx_MatrixToolbar_close"><img src="img/cancel.svg" width="18" height="18" onClick={ this.hideToolbar } /></div>
@@ -43,4 +43,3 @@ module.exports = React.createClass({
);
}
});
+42 -13
View File
@@ -17,20 +17,49 @@ limitations under the License.
'use strict';
var React = require('react');
var sdk = require('matrix-react-sdk')
var sdk = require('matrix-react-sdk');
import Modal from 'matrix-react-sdk/lib/Modal';
module.exports = React.createClass({
displayName: 'NewVersionBar',
/**
* Check a version string is compatible with the Changelog
* dialog
*/
function checkVersion(ver) {
const parts = ver.split('-');
return parts[0] == 'vector' && parts[2] == 'react' && parts[4] == 'js';
}
render: function() {
return (
<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>
);
export default function NewVersionBar(props) {
const onChangelogClicked = () => {
const ChangelogDialog = sdk.getComponent('dialogs.ChangelogDialog');
Modal.createDialog(ChangelogDialog, {
version: props.version,
newVersion: props.newVersion,
onFinished: (update) => {
if(update) {
window.location.reload();
}
}
});
};
let changelog_button;
if (checkVersion(props.version) && checkVersion(props.newVersion)) {
changelog_button = <button className="mx_MatrixToolbar_action" onClick={onChangelogClicked}>Changelog</button>;
}
});
return (
<div className="mx_MatrixToolbar">
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="/!\"/>
<div className="mx_MatrixToolbar_content">
A new version of Riot is available. Refresh your browser.
</div>
{changelog_button}
</div>
);
}
NewVersionBar.propTypes = {
version: React.PropTypes.string.isRequired,
newVersion: React.PropTypes.string.isRequired,
};
@@ -30,10 +30,10 @@ module.exports = React.createClass({
</div>
<div className="mx_Dialog_content">
<span>
You can use the custom server options to log into other Matrix
You can use the custom server options to sign into other Matrix
servers by specifying a different Home server URL.
<br/>
This allows you to use Vector with an existing Matrix account on
This allows you to use Riot with an existing Matrix account on
a different home server.
<br/>
<br/>
@@ -27,8 +27,8 @@ module.exports = React.createClass({
render: function() {
return (
<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://medium.com/@RiotChat">blog</a>&nbsp;&nbsp;&middot;&nbsp;&nbsp;
<a href="https://twitter.com/@RiotChat">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>
@@ -27,7 +27,7 @@ module.exports = React.createClass({
render: function() {
return (
<div className="mx_Login_logo">
<img src="img/logo.png" width="249" height="78" alt="vector"/>
<img src="img/logo.png" width="195" height="195" alt="Riot"/>
</div>
);
}
@@ -26,7 +26,7 @@ module.exports = React.createClass({
var date = new Date(this.props.ts);
return (
<span className="mx_MessageTimestamp">
{ DateUtils.formatDate(date) }
{ DateUtils.formatTime(date) }
</span>
);
},
@@ -1,45 +0,0 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require('react');
module.exports = React.createClass({
displayName: 'SenderProfile',
propTypes: {
mxEvent: React.PropTypes.object.isRequired, // event whose sender we're showing
aux: React.PropTypes.string, // stuff to go after the sender name, if anything
onClick: React.PropTypes.func,
},
render: function() {
var mxEvent = this.props.mxEvent;
var name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
var msgtype = mxEvent.getContent().msgtype;
if (msgtype && msgtype == 'm.emote') {
name = ''; // emote message must include the name so don't duplicate it
}
return (
<span className="mx_SenderProfile" onClick={this.props.onClick}>
{name} { this.props.aux }
</span>
);
},
});
@@ -1,57 +0,0 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require('react');
var sdk = require('matrix-react-sdk')
module.exports = React.createClass({
displayName: 'BottomLeftMenuTile',
getInitialState: function() {
return( { hover : false });
},
onMouseEnter: function() {
this.setState( { hover : true });
},
onMouseLeave: function() {
this.setState( { hover : false });
},
render: function() {
var label;
if (!this.props.collapsed) {
label = <div className="mx_RoomTile_name">{ this.props.label }</div>;
}
else if (this.state.hover) {
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="26" height="26"/>
</div>
{ label }
</div>
);
}
});
@@ -25,6 +25,13 @@ 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');
/**
* Defines a new Component, DNDRoomTile that wraps RoomTile, making it draggable.
* Requires extra props:
* roomSubList: React.PropTypes.object.isRequired,
* refreshSubList: React.PropTypes.func.isRequired,
*/
/**
* Specifies the drag source contract.
* Only `beginDrag` function is required.
@@ -202,4 +209,3 @@ DragSource('RoomTile', roomTileSource, function(connect, monitor) {
};
})(RoomTile));
module.exports.replaces = 'RoomTile';
+61 -24
View File
@@ -18,42 +18,79 @@ limitations under the License.
var React = require('react');
var ReactDOM = require('react-dom');
var dis = require('matrix-react-sdk/lib/dispatcher');
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: tooltip,
});
}
else {
tooltip.style.top = tooltip.parentElement.getBoundingClientRect().top + "px";
tooltip.style.display = "block";
}
propTypes: {
// Alllow the tooltip to be styled by the parent element
className: React.PropTypes.string.isRequired,
// The tooltip is derived from either the room name or a label
room: React.PropTypes.object,
label: React.PropTypes.string,
},
// Create a wrapper for the tooltip outside the parent and attach it to the body element
componentDidMount: function() {
this.tooltipContainer = document.createElement("div");
this.tooltipContainer.className = "mx_RoomTileTooltip_wrapper";
document.body.appendChild(this.tooltipContainer);
this._renderTooltip();
},
componentDidUpdate: function() {
this._renderTooltip();
},
// Remove the wrapper element, as the tooltip has finished using it
componentWillUnmount: function() {
if (!this.props.bottom) {
dis.dispatch({
action: 'view_tooltip',
tooltip: null,
});
}
dis.dispatch({
action: 'view_tooltip',
tooltip: null,
parent: null,
});
ReactDOM.unmountComponentAtNode(this.tooltipContainer);
document.body.removeChild(this.tooltipContainer);
},
_renderTooltip: function() {
var label = this.props.room ? this.props.room.name : this.props.label;
// Add the parent's position to the tooltips, so it's correctly
// positioned, also taking into account any window zoom
// NOTE: The additional 6 pixels for the left position, is to take account of the
// tooltips chevron
var parent = ReactDOM.findDOMNode(this);
var style = {};
style.top = parent.getBoundingClientRect().top + window.pageYOffset;
style.left = 6 + parent.getBoundingClientRect().right + window.pageXOffset;
style.display = "block";
var tooltip = (
<div className="mx_RoomTooltip" style={style} >
<div className="mx_RoomTooltip_chevron"></div>
{ label }
</div>
);
// Render the tooltip manually, as we wish it not to be rendered within the parent
this.tooltip = ReactDOM.render(tooltip, this.tooltipContainer);
// Tell the roomlist about us so it can manipulate us if it wishes
dis.dispatch({
action: 'view_tooltip',
tooltip: this.tooltip,
parent: parent,
});
},
render: function() {
var label = this.props.room ? this.props.room.name : this.props.label;
// Render a placeholder
return (
<div className="mx_RoomTooltip">
<img className="mx_RoomTooltip_chevron" src="img/chevron-left.png" width="9" height="16"/>
{ label }
<div className={ this.props.className } >
</div>
);
}
@@ -0,0 +1,63 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require('react');
var sdk = require('matrix-react-sdk');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var dis = require('matrix-react-sdk/lib/dispatcher');
module.exports = React.createClass({
displayName: 'IntegrationsManager',
propTypes: {
src: React.PropTypes.string.isRequired, // the source of the integration manager being embedded
onFinished: React.PropTypes.func.isRequired, // callback when the lightbox is dismissed
},
// XXX: keyboard shortcuts for managing dialogs should be done by the modal
// dialog base class somehow, surely...
componentDidMount: function() {
this.dispatcherRef = dis.register(this.onAction);
document.addEventListener("keydown", this.onKeyDown);
},
componentWillUnmount: function() {
dis.unregister(this.dispatcherRef);
document.removeEventListener("keydown", this.onKeyDown);
},
onKeyDown: function(ev) {
if (ev.keyCode == 27) { // escape
ev.stopPropagation();
ev.preventDefault();
this.props.onFinished();
}
},
onAction: function(payload) {
if (payload.action === 'close_scalar') {
this.props.onFinished();
}
},
render: function() {
return (
<iframe src={ this.props.src }></iframe>
);
}
});
+171 -325
View File
@@ -22,174 +22,18 @@ var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var UserSettingsStore = require('matrix-react-sdk/lib/UserSettingsStore');
var Modal = require('matrix-react-sdk/lib/Modal');
/**
* Enum for state of a push rule as defined by the Vector UI.
* @readonly
* @enum {string}
*/
var PushRuleVectorState = {
/** 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",
};
var notifications = require('../../../notifications');
// Encodes a dictionary of {
// "notify": true/false,
// "sound": string or undefined,
// "highlight: true/false,
// }
// to a list of push actions.
function encodeActions(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"];
}
}
// TODO: this "view" component still has far too much application logic in it,
// which should be factored out to other files.
// 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.
function decodeActions(actions) {
var notify = false;
var sound = null;
var highlight = false;
// TODO: this component also does a lot of direct poking into this.state, which
// is VERY NAUGHTY.
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;
}
var ACTION_NOTIFY = encodeActions({notify: true});
var ACTION_NOTIFY_DEFAULT_SOUND = encodeActions({notify: true, sound: "default"});
var ACTION_NOTIFY_RING_SOUND = encodeActions({notify: true, sound: "ring"});
var ACTION_HIGHLIGHT_DEFAULT_SOUND = encodeActions({notify: true, sound: "default", highlight: true});
var ACTION_DONT_NOTIFY = encodeActions({notify: false});
var ACTION_DISABLED = null;
/**
* The descriptions of rules managed by the Vector UI.
*/
var VectorPushRulesDefinitions = {
// Messages containing user's display name
// (skip contains_user_name which is too geeky)
".m.rule.contains_display_name": {
kind: "underride",
description: "Messages containing my name",
vectorStateToActions: { // The actions for each vector state, or null to disable the rule.
on: ACTION_NOTIFY,
loud: ACTION_HIGHLIGHT_DEFAULT_SOUND,
off: ACTION_DISABLED
}
},
// Messages just sent to the user in a 1:1 room
".m.rule.room_one_to_one": {
kind: "underride",
description: "Messages in one-to-one chats",
vectorStateToActions: {
on: ACTION_NOTIFY,
loud: ACTION_NOTIFY_DEFAULT_SOUND,
off: 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": {
kind: "underride",
description: "Messages in group chats",
vectorStateToActions: {
on: ACTION_NOTIFY,
loud: ACTION_NOTIFY_DEFAULT_SOUND,
off: ACTION_DONT_NOTIFY
}
},
// Invitation for the user
".m.rule.invite_for_me": {
kind: "underride",
description: "When I'm invited to a room",
vectorStateToActions: {
on: ACTION_NOTIFY,
loud: ACTION_NOTIFY_DEFAULT_SOUND,
off: ACTION_DISABLED
}
},
// Incoming call
".m.rule.call": {
kind: "underride",
description: "Call invitation",
vectorStateToActions: {
on: ACTION_NOTIFY,
loud: ACTION_NOTIFY_RING_SOUND,
off: ACTION_DISABLED
}
},
// Notifications from bots
".m.rule.suppress_notices": {
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: ACTION_DISABLED,
loud: ACTION_NOTIFY_DEFAULT_SOUND,
off: ACTION_DONT_NOTIFY,
}
}
};
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.
@@ -206,9 +50,9 @@ var LEGACY_RULES = {
};
function portLegacyActions(actions) {
var decoded = decodeActions(actions);
var decoded = NotificationUtils.decodeActions(actions);
if (decoded !== null) {
return encodeActions(decoded);
return NotificationUtils.encodeActions(decoded);
} else {
// We don't recognise one of the actions here, so we don't try to
// canonicalise them.
@@ -216,7 +60,6 @@ function portLegacyActions(actions) {
}
}
module.exports = React.createClass({
displayName: 'Notififications',
@@ -226,6 +69,19 @@ module.exports = React.createClass({
ERROR: "ERROR" // There was an error
},
propTypes: {
// The array of threepids from the JS SDK (required for email notifications)
threepids: React.PropTypes.array.isRequired,
// The brand string set when creating an email pusher
brand: React.PropTypes.string,
},
getDefaultProps: function() {
return {
threepids: []
};
},
getInitialState: function() {
return {
phase: this.phases.LOADING,
@@ -259,7 +115,30 @@ module.exports = React.createClass({
UserSettingsStore.setEnableNotifications(event.target.checked);
},
onEnableEmailNotificationsChange: function(address, event) {
var emailPusherPromise;
if (event.target.checked) {
var data = {}
data['brand'] = this.props.brand || 'Riot';
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: "An error occurred whilst saving 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];
@@ -330,40 +209,6 @@ module.exports = React.createClass({
}
},
_actionsFor: function(pushRuleVectorState) {
if (pushRuleVectorState === PushRuleVectorState.ON) {
return ACTION_NOTIFY;
}
else if (pushRuleVectorState === PushRuleVectorState.LOUD) {
return ACTION_HIGHLIGHT_DEFAULT_SOUND;
}
},
// Determine whether a content rule is in the PushRuleVectorState.ON category or in PushRuleVectorState.LOUD
// regardless of its enabled state. Returns undefined if it does not match these categories.
_contentRuleVectorStateKind: function(rule) {
var stateKind;
// Count tweaks to determine if it is a ON or LOUD rule
var tweaks = 0;
for (var j in rule.actions) {
var action = rule.actions[j];
if (action.set_tweak === 'sound' ||
(action.set_tweak === 'highlight' && action.value)) {
tweaks++;
}
}
switch (tweaks) {
case 0:
stateKind = PushRuleVectorState.ON;
break;
case 2:
stateKind = PushRuleVectorState.LOUD;
break;
}
return stateKind;
},
_setPushRuleVectorState: function(rule, newPushRuleVectorState) {
if (rule && rule.vectorState !== newPushRuleVectorState) {
@@ -379,7 +224,7 @@ module.exports = React.createClass({
if (rule.rule) {
var actions = ruleDefinition.vectorStateToActions[newPushRuleVectorState];
if (actions === ACTION_DISABLED) {
if (!actions) {
// The new state corresponds to disabling the rule.
deferreds.push(cli.setPushRuleEnabled('global', rule.rule.kind, rule.rule.rule_id, false));
}
@@ -425,7 +270,7 @@ module.exports = React.createClass({
switch (newPushRuleVectorState) {
case PushRuleVectorState.ON:
if (rule.actions.length !== 1) {
actions = this._actionsFor(PushRuleVectorState.ON);
actions = PushRuleVectorState.actionsFor(PushRuleVectorState.ON);
}
if (this.state.vectorContentRules.vectorState === PushRuleVectorState.OFF) {
@@ -435,7 +280,7 @@ module.exports = React.createClass({
case PushRuleVectorState.LOUD:
if (rule.actions.length !== 3) {
actions = this._actionsFor(PushRuleVectorState.LOUD);
actions = PushRuleVectorState.actionsFor(PushRuleVectorState.LOUD);
}
if (this.state.vectorContentRules.vectorState === PushRuleVectorState.OFF) {
@@ -521,7 +366,7 @@ module.exports = React.createClass({
// when creating the new rule.
// Thus, this new rule will join the 'vectorContentRules' set.
if (self.state.vectorContentRules.rules.length) {
pushRuleVectorStateKind = self._contentRuleVectorStateKind(self.state.vectorContentRules.rules[0]);
pushRuleVectorStateKind = PushRuleVectorState.contentRuleVectorStateKind(self.state.vectorContentRules.rules[0]);
}
else {
// ON is default
@@ -536,13 +381,13 @@ module.exports = React.createClass({
if (self.state.vectorContentRules.vectorState !== PushRuleVectorState.OFF) {
deferreds.push(cli.addPushRule
('global', 'content', keyword, {
actions: self._actionsFor(pushRuleVectorStateKind),
actions: PushRuleVectorState.actionsFor(pushRuleVectorStateKind),
pattern: keyword
}));
}
else {
deferreds.push(self._addDisabledPushRule('global', 'content', keyword, {
actions: self._actionsFor(pushRuleVectorStateKind),
actions: PushRuleVectorState.actionsFor(pushRuleVectorStateKind),
pattern: keyword
}));
}
@@ -601,7 +446,10 @@ module.exports = React.createClass({
_refreshFromServer: function() {
var self = this;
MatrixClientPeg.get().getPushRules().then(self._portRulesToNewAPI).done(function(rulesets) {
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
@@ -624,8 +472,6 @@ module.exports = React.createClass({
// HS default rules
var defaultRules = {master: [], vector: {}, others: []};
// Content/keyword rules
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) {
@@ -644,84 +490,25 @@ module.exports = React.createClass({
defaultRules['others'].push(r);
}
}
else if (kind === 'content') {
switch (self._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;
}
}
}
}
// 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 self.state.externalContentRules.
// 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) {
self.state.vectorContentRules = {
vectorState: PushRuleVectorState.LOUD,
rules: contentRules.loud
}
self.state.externalContentRules = [].concat(contentRules.loud_but_disabled, contentRules.on, contentRules.on_but_disabled, contentRules.other);
}
else if (contentRules.loud_but_disabled.length) {
self.state.vectorContentRules = {
vectorState: PushRuleVectorState.OFF,
rules: contentRules.loud_but_disabled
}
self.state.externalContentRules = [].concat(contentRules.on, contentRules.on_but_disabled, contentRules.other);
}
else if (contentRules.on.length) {
self.state.vectorContentRules = {
vectorState: PushRuleVectorState.ON,
rules: contentRules.on
}
self.state.externalContentRules = [].concat(contentRules.on_but_disabled, contentRules.other);
}
else if (contentRules.on_but_disabled.length) {
self.state.vectorContentRules = {
vectorState: PushRuleVectorState.OFF,
rules: contentRules.on_but_disabled
}
self.state.externalContentRules = contentRules.other;
}
else {
self.state.externalContentRules = contentRules.other;
}
// 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',
@@ -735,7 +522,6 @@ module.exports = React.createClass({
];
for (var i in vectorRuleIds) {
var vectorRuleId = vectorRuleIds[i];
var ruleDefinition = VectorPushRulesDefinitions[vectorRuleId];
if (vectorRuleId === '_keywords') {
// keywords needs a special handling
@@ -748,42 +534,12 @@ module.exports = React.createClass({
});
}
else {
var ruleDefinition = VectorPushRulesDefinitions[vectorRuleId];
var rule = defaultRules.vector[vectorRuleId];
// Translate the rule actions and its enabled value into vector state
var vectorState;
if (rule) {
for (var stateKey in PushRuleVectorState) {
var state = PushRuleVectorState[stateKey];
var vectorStateToActions = ruleDefinition.vectorStateToActions[state];
var vectorState = ruleDefinition.ruleToVectorState(rule);
if (vectorStateToActions === ACTION_DISABLED) {
// No defined actions means that this vector state expects a disabled default hs rule
if (rule.enabled === false) {
vectorState = state;
break;
}
}
else {
// The actions must match to the ones expected by vector state
if (JSON.stringify(rule.actions) === JSON.stringify(vectorStateToActions)) {
// And the rule must be enabled.
if (rule.enabled === true) {
vectorState = state;
break;
}
}
}
}
if (!vectorState) {
console.error("Cannot translate rule actions into Vector rule state. Rule: " + rule);
vectorState = PushRuleVectorState.OFF;
}
}
else {
vectorState = PushRuleVectorState.OFF;
}
//console.log("Refreshing vectorPushRules for " + vectorRuleId +", "+ ruleDefinition.description +", " + rule +", " + vectorState);
self.state.vectorPushRules.push({
"vectorRuleId": vectorRuleId,
@@ -791,6 +547,12 @@ module.exports = React.createClass({
"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);
}
}
}
@@ -800,7 +562,6 @@ module.exports = React.createClass({
'.m.rule.fallback': "Notify me for anything else"
};
self.state.externalPushRules = [];
for (var i in defaultRules.others) {
var rule = defaultRules.others[i];
var ruleDescription = otherRulesDescriptions[rule.rule_id];
@@ -811,11 +572,31 @@ module.exports = React.createClass({
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) {
@@ -835,7 +616,7 @@ module.exports = React.createClass({
renderNotifRulesTableRow: function(title, className, pushRuleVectorState) {
return (
<tr key = {className}>
<tr key={ className }>
<th>
{title}
</th>
@@ -868,21 +649,37 @@ module.exports = React.createClass({
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");
return (
<div className="mx_UserSettings_notifTable">
<Loader />
</div>
);
spinner = <Loader />;
}
if (this.state.masterPushRule) {
@@ -912,12 +709,29 @@ module.exports = React.createClass({
{masterPushRuleDiv}
<div className="mx_UserSettings_notifTable">
All notifications are currently disabled for all devices.
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) {
@@ -936,13 +750,41 @@ module.exports = React.createClass({
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.
You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply.
<ul>
{ externalRules }
</ul>
@@ -957,6 +799,8 @@ module.exports = React.createClass({
<div className="mx_UserSettings_notifTable">
{ spinner }
<div className="mx_UserNotifSettings_tableRow">
<div className="mx_UserNotifSettings_inputCell">
<input id="enableDesktopNotifications"
@@ -990,7 +834,7 @@ module.exports = React.createClass({
</div>
</div>
<h3>General use</h3>
{ emailNotificationsRow }
<div className="mx_UserNotifSettings_pushRulesTableWrapper">
<table className="mx_UserNotifSettings_pushRulesTable">
@@ -999,7 +843,7 @@ module.exports = React.createClass({
<th width="55%"></th>
<th width="15%">Off</th>
<th width="15%">On</th>
<th width="15%">Loud</th>
<th width="15%">Noisy</th>
</tr>
</thead>
<tbody>
@@ -1012,6 +856,8 @@ module.exports = React.createClass({
{ advancedSettings }
{ devicesSection }
</div>
</div>
+125
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;
},
};
+89
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;
},
};
+94
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];
};
+30
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,
};
@@ -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: "override",
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,
}
}),
};
+24
View File
@@ -0,0 +1,24 @@
/*
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 = {
NotificationUtils: require('./NotificationUtils'),
PushRuleVectorState: require('./PushRuleVectorState'),
VectorPushRulesDefinitions: require('./VectorPushRulesDefinitions'),
ContentRules: require('./ContentRules'),
};
+134 -60
View File
@@ -32,6 +32,8 @@ body {
color: #454545;
border: 0px;
margin: 0px;
/* This should render the fonts the same accross browsers */
-webkit-font-smoothing: subpixel-antialiased;
}
div.error {
@@ -52,12 +54,35 @@ a:visited {
color: #76cfa6;
}
input[type=text].error, input[type=password].error {
border: 1px solid red;
}
input[type=text]:focus, textarea:focus {
border: 1px solid #76CFA6;
outline: none;
box-shadow: none;
}
/* Required by Firefox */
textarea {
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
}
/* Prevent ugly dotted highlight around selected elements in Firefox */
::-moz-focus-inner {
border: 0;
}
/* applied to side-panels and messagepanel when in RoomSettings */
.mx_fadable {
opacity: 1;
-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.
@@ -66,53 +91,27 @@ input[type=text]:focus, textarea:focus {
position: absolute;
}
/* hack to avoid accidental click-throughs if you miss the narrow scrollbar */
/* Expand thumbs on hoverover */
.gm-scrollbar {
border-radius: 5px ! important;
}
.gm-scrollbar.-vertical {
border-left: 6px solid transparent;
width: 6px;
transition: width 120ms ease-out ! important;
}
.mx_ContextualMenu_background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 1.0;
z-index: 2000;
.gm-scrollbar.-vertical:hover,
.gm-scrollbar.-vertical:active {
width: 8px;
transition: width 120ms ease-out ! important;
}
.mx_ContextualMenu {
border: 1px solid #a4a4a4;
border-radius: 8px;
background-color: #fff;
color: #747474;
position: fixed;
z-index: 2001;
padding: 6px;
.gm-scrollbar.-horizontal {
height: 6px;
transition: height 120ms ease-out ! important;
}
.mx_ContextualMenu_chevron_right {
padding: 12px;
position: absolute;
right: -21px;
top: 0px;
}
.mx_ContextualMenu_chevron_left {
padding: 12px;
position: absolute;
left: -21px;
top: 0px;
}
.mx_ContextualMenu_field {
padding: 3px 6px 3px 6px;
cursor: pointer;
}
.mx_ContextualMenu_spinner {
display: block;
margin: 0 auto;
.gm-scrollbar.-horizontal:hover,
.gm-scrollbar.-horizontal:active {
height: 8px;
transition: height 120ms ease-out ! important;
}
.mx_Dialog_wrapper {
@@ -134,16 +133,33 @@ input[type=text]:focus, textarea:focus {
justify-content: center;
}
/* Spinner Dialog overide */
.mx_Dialog_wrapper.mx_Dialog_spinner .mx_Dialog {
width: auto;
border-radius: 8px;
padding-left: 0px;
box-shadow: none;
}
/* View Source Dialog overide */
.mx_Dialog_wrapper.mx_Dialog_viewsource .mx_Dialog {
padding-left: 10px;
padding-right: 10px;
}
.mx_Dialog {
background-color: #fff;
color: #747474;
text-align: center;
z-index: 4010;
font-weight: 300;
font-size: 15px;
position: relative;
border-radius: 8px;
max-width: 80%;
padding-left: 58px;
width: 60%;
max-width: 704px;
box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.2);
max-height: 80%;
overflow-y: auto;
}
.mx_Dialog_background {
@@ -152,12 +168,13 @@ input[type=text]:focus, textarea:focus {
left: 0;
width: 100%;
height: 100%;
background-color: #000;
opacity: 0.2;
background-color: #e9e9e9;
opacity: 0.8;
}
.mx_Dialog_lightbox .mx_Dialog_background {
opacity: 0.85;
background-color: #000;
}
.mx_Dialog_lightbox .mx_Dialog {
@@ -171,34 +188,64 @@ input[type=text]:focus, textarea:focus {
}
.mx_Dialog_content {
margin: 24px;
margin: 24px 58px 68px 0;
font-size: 14px;
color: #4a4a4a;
word-wrap: break-word;
}
.mx_Dialog_buttons {
padding-bottom: 24px;
padding-bottom: 36px;
}
.mx_Dialog button, .mx_Dialog input[type="submit"] {
border: 0px;
height: 36px;
border-radius: 36px;
font-weight: 400;
font-size: 15px;
border-radius: 40px;
border: solid 1px #76cfa6;
font-weight: 600;
font-size: 14px;
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
margin-left: 0px;
margin-right: 8px;
padding-left: 1.5em;
padding-right: 1.5em;
outline: none;
cursor: pointer;
color: #76cfa6;
background-color: #fff;
/* align images in buttons (eg spinners) */
vertical-align: middle;
}
.mx_Dialog button.mx_Dialog_primary, .mx_Dialog input[type="submit"].mx_Dialog_primary {
color: #fff;
background-color: #76cfa6;
margin-left: 8px;
margin-right: 8px;
padding-left: 1em;
padding-right: 1em;
}
.mx_Dialog button.danger, .mx_Dialog input[type="submit"].danger {
background-color: #ff0064;
border: solid 1px #ff0064;
}
.mx_Dialog button:disabled, .mx_Dialog input[type="submit"]:disabled {
background-color: #777777;
border: solid 1px #777777;
opacity: 0.7;
}
.mx_Dialog_title {
min-height: 16px;
padding: 12px;
border-bottom: 1px solid #a4a4a4;
padding-top: 40px;
font-weight: bold;
font-size: 18px;
font-size: 22px;
line-height: 1.4;
color: #454545;
}
.mx_Dialog_title.danger {
color: #ff0064;
}
.mx_TextInputDialog_label {
@@ -214,3 +261,30 @@ input[type=text]:focus, textarea:focus {
color: #454545;
background-color: #fff;
}
.mx_emojione {
height: 1em;
vertical-align: middle;
}
::-moz-selection {
background-color: #76CFA6;
color: white;
}
::selection {
background-color: #76CFA6;
color: white;
}
/** green button with rounded corners */
.mx_textButton {
color: #fff;
background-color: #76cfa6;
border-radius: 17px;
text-align: center;
padding-left: 1em;
padding-right: 1em;
cursor: pointer;
display: inline;
}
-6
View File
@@ -1,6 +0,0 @@
.mx_RoomSettings_encrypt,
.mx_CreateRoom_encrypt,
.mx_RightPanel_filebutton
{
display: none !important;
}
@@ -0,0 +1,106 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_ContextualMenu_wrapper {
position: fixed;
z-index: 2000;
}
.mx_ContextualMenu_background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 1.0;
z-index: 2000;
}
.mx_ContextualMenu {
border: solid 1px rgba(187, 187, 187, 0.5);
border-radius: 4px;
background-color: #f6f6f6;
color: #4a4a4a;
position: absolute;
padding: 6px;
font-size: 14px;
z-index: 2001;
}
.mx_ContextualMenu.mx_ContextualMenu_right {
right: 8px;
}
.mx_ContextualMenu_chevron_right {
position: absolute;
right: -8px;
top: 0px;
width: 0;
height: 0;
border-top: 8px solid transparent;
border-left: 8px solid rgba(187, 187, 187, 0.5);
border-bottom: 8px solid transparent;
}
.mx_ContextualMenu_chevron_right:after {
content:'';
width: 0;
height: 0;
border-top: 7px solid transparent;
border-left: 7px solid #f6f6f6;
border-bottom: 7px solid transparent;
position:absolute;
top: -7px;
right: 1px;
}
.mx_ContextualMenu.mx_ContextualMenu_left {
left: 8px;
}
.mx_ContextualMenu_chevron_left {
position: absolute;
left: -8px;
top: 0px;
width: 0;
height: 0;
border-top: 8px solid transparent;
border-right: 8px solid rgba(187, 187, 187, 0.5);
border-bottom: 8px solid transparent;
}
.mx_ContextualMenu_chevron_left:after{
content:'';
width: 0;
height: 0;
border-top: 7px solid transparent;
border-right: 7px solid #f6f6f6;
border-bottom: 7px solid transparent;
position:absolute;
top: -7px;
left: 1px;
}
.mx_ContextualMenu_field {
padding: 3px 6px 3px 6px;
cursor: pointer;
white-space: nowrap;
}
.mx_ContextualMenu_spinner {
display: block;
margin: 0 auto;
}
@@ -0,0 +1,120 @@
/*
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_FilePanel {
-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;
width: 100%;
overflow-y: auto;
}
.mx_FilePanel .mx_RoomView_messageListWrapper {
margin-right: 20px;
}
.mx_FilePanel .mx_RoomView_MessageList h2 {
display: none;
}
/* FIXME: rather than having EventTile's default CSS be for MessagePanel,
we should make EventTile a base CSS class and customise it specifically
for usage in {Message,File,Notification}Panel. */
.mx_FilePanel .mx_EventTile_avatar {
display: none;
}
/* Overrides for the attachment body tiles */
.mx_FilePanel .mx_EventTile {
word-break: break-word;
}
.mx_FilePanel .mx_EventTile .mx_MImageBody {
margin-right: 0px;
}
.mx_FilePanel .mx_EventTile .mx_MImageBody_download {
display: flex;
font-size: 14px;
color: #acacac;
}
.mx_FilePanel .mx_EventTile .mx_MImageBody_downloadLink {
flex: 1 1 auto;
color: #747474;
}
.mx_FilePanel .mx_EventTile .mx_MImageBody_size {
flex: 1 0 0;
font-size: 11px;
text-align: right;
white-space: nowrap;
}
/* Overides for the sender details line */
.mx_FilePanel .mx_EventTile_senderDetails {
display: flex;
margin-top: -2px;
}
.mx_FilePanel .mx_EventTile_senderDetailsLink {
text-decoration: none;
}
.mx_FilePanel .mx_EventTile .mx_SenderProfile {
flex: 1 1 auto;
line-height: initial;
padding: 0px;
font-size: 11px;
opacity: 1.0;
color: #acacac;
}
.mx_FilePanel .mx_EventTile .mx_MessageTimestamp {
flex: 1 0 0;
text-align: right;
visibility: visible;
position: initial;
font-size: 11px;
opacity: 1.0;
color: #acacac;
}
/* Overrides for the wrappers around the body tile */
.mx_FilePanel .mx_EventTile_line {
margin-right: 0px;
padding-left: 0px;
}
.mx_FilePanel .mx_EventTile:hover .mx_EventTile_line {
background-color: #fff;
}
.mx_FilePanel .mx_EventTile_selected .mx_EventTile_line {
padding-left: 0px;
}
@@ -93,8 +93,8 @@ limitations under the License.
background-color: #eaf5f0;
-webkit-flex: 0 0 210px;
flex: 0 0 210px;
-webkit-flex: 0 0 235px;
flex: 0 0 235px;
}
.mx_MatrixChat .mx_LeftPanel.collapsed {
@@ -109,7 +109,7 @@ limitations under the License.
-webkit-order: 2;
order: 2;
padding-left: 25px;
padding-left: 20px;
padding-right: 22px;
background-color: #fff;
@@ -151,6 +151,6 @@ limitations under the License.
}
.mx_MatrixChat .mx_RightPanel.collapsed {
-webkit-flex: 0 0 72px;
flex: 0 0 72px;
-webkit-flex: 0 0 122px;
flex: 0 0 122px;
}
@@ -0,0 +1,106 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_NotificationPanel {
-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;
width: 100%;
overflow-y: auto;
}
.mx_NotificationPanel .mx_RoomView_messageListWrapper {
margin-right: 20px;
}
.mx_NotificationPanel .mx_RoomView_MessageList h2 {
margin-left: 0px;
}
/* FIXME: rather than having EventTile's default CSS be for MessagePanel,
we should make EventTile a base CSS class and customise it specifically
for usage in {Message,File,Notification}Panel. */
.mx_NotificationPanel .mx_EventTile {
word-break: break-word;
}
.mx_NotificationPanel .mx_EventTile_roomName {
font-weight: bold;
font-size: 14px;
}
.mx_NotificationPanel .mx_EventTile_roomName a {
color: #4a4a4a;
}
.mx_NotificationPanel .mx_EventTile_avatar {
top: 8px;
left: 0px;
}
.mx_NotificationPanel .mx_EventTile .mx_SenderProfile,
.mx_NotificationPanel .mx_EventTile .mx_MessageTimestamp {
color: #000;
opacity: 0.3;
font-size: 12px;
display: inline;
padding-left: 0px;
}
.mx_NotificationPanel .mx_EventTile_senderDetails {
padding-left: 32px;
padding-top: 8px;
position: relative;
}
.mx_NotificationPanel .mx_EventTile_roomName a,
.mx_NotificationPanel .mx_EventTile_senderDetails a {
text-decoration: none ! important;
}
.mx_NotificationPanel .mx_EventTile .mx_MessageTimestamp {
visibility: visible;
position: initial;
display: inline;
}
.mx_NotificationPanel .mx_EventTile_line {
margin-right: 0px;
padding-left: 32px;
padding-top: 0px;
padding-bottom: 0px;
padding-right: 0px;
}
.mx_NotificationPanel .mx_EventTile:hover .mx_EventTile_line {
background-color: #fff;
}
.mx_NotificationPanel .mx_EventTile_selected .mx_EventTile_line {
padding-left: 0px;
}
.mx_NotificationPanel .mx_EventTile_content {
margin-right: 0px;
}
@@ -1,7 +1,22 @@
/*
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: 5px;
margin-left: 65px;
min-height: 24px;
min-height: 34px;
}
/* position the indicator in the same place horizontally as .mx_EventTile_avatar. */
@@ -9,14 +24,50 @@
padding-left: 18px;
padding-right: 12px;
margin-left: -73px;
margin-top: 13px;
float: left;
width: 24px;
text-align: center;
}
.mx_RoomStatusBar_placeholderIndicator {
.mx_RoomStatusBar_callBar {
height: 50px;
line-height: 50px;
}
.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 {
@@ -24,6 +75,7 @@
}
.mx_RoomStatusBar_unreadMessagesBar {
padding-top: 10px;
color: #ff0064;
cursor: pointer;
}
@@ -57,10 +109,12 @@
}
.mx_RoomStatusBar_tabCompleteBar {
padding-top: 10px;
color: #4a4a4a;
}
.mx_RoomStatusBar_typingBar {
padding-top: 10px;
color: #4a4a4a;
opacity: 0.5;
overflow-y: hidden;
@@ -70,7 +124,7 @@
.mx_RoomStatusBar_tabCompleteWrapper {
display: flex;
display: -webkit-flex;
height: 24px;
height: 26px;
}
.mx_RoomStatusBar_tabCompleteWrapper .mx_TabCompleteBar {
@@ -36,8 +36,8 @@ limitations under the License.
-webkit-order: 1;
order: 1;
-webkit-flex: 0 0 83px;
flex: 0 0 83px;
-webkit-flex: 0 0 70px;
flex: 0 0 70px;
}
.mx_RoomView_fileDropTarget {
@@ -64,7 +64,7 @@ limitations under the License.
border: 2px #e1dddd solid;
border-bottom: none;
position: absolute;
top: 83px;
top: 70px;
bottom: 0px;
z-index: 3000;
}
@@ -89,7 +89,7 @@ limitations under the License.
margin: auto;
overflow: auto;
border-bottom: 1px solid #eee;
border-bottom: 1px solid #e5e5e5;
-webkit-flex: 0 0 auto;
flex: 0 0 auto;
@@ -158,7 +158,7 @@ limitations under the License.
margin-bottom: 8px;
margin-left: 63px;
padding-bottom: 6px;
border-bottom: 1px solid #eee;
border-bottom: 1px solid #e5e5e5;
}
.mx_RoomView_invitePrompt {
@@ -207,14 +207,24 @@ hr.mx_RoomView_myReadMarker {
.mx_RoomView_statusAreaBox {
max-width: 960px;
margin: auto;
min-height: 36px;
min-height: 50px;
}
.mx_RoomView_statusAreaBox_line {
border-top: 1px solid #eee;
margin-left: 65px;
border-top: 1px solid #e5e5e5;
height: 1px;
}
.mx_RoomView_callStatusBar .mx_UploadBar_uploadProgressInner {
background-color: #fff;
}
.mx_RoomView_callStatusBar .mx_UploadBar_uploadFilename {
color: #fff;
opacity: 1.0;
}
.mx_RoomView_inCall .mx_RoomView_statusAreaBox_line {
border-top: 1px hidden;
}
@@ -238,6 +248,7 @@ hr.mx_RoomView_myReadMarker {
.mx_RoomView_voipButton {
float: right;
margin-right: 13px;
margin-top: 10px;
cursor: pointer;
}
@@ -267,3 +278,7 @@ hr.mx_RoomView_myReadMarker {
padding: 6px 0;
cursor: pointer;
}
.mx_RoomView_ongoingConfCallNotification a {
color: #fff ! important;
}
@@ -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.
*/
.mx_SearchBox {
height: 24px;
margin-left: 16px;
margin-right: 16px;
padding-top: 24px;
padding-bottom: 22px;
display: flex;
display: -webkit-flex;
}
.mx_SearchBox_searchButton {
margin-right: 10px;
margin-top: 5px;
pointer-events: none;
}
.mx_SearchBox_closeButton {
cursor: pointer;
margin-top: -5px;
}
.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;
}
@@ -1,16 +1,33 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_UploadBar {
position: relative;
}
.mx_UploadBar_uploadProgressOuter {
height: 4px;
height: 5px;
margin-left: 63px;
margin-top: -1px;
padding-bottom: 5px;
}
.mx_UploadBar_uploadProgressInner {
background-color: #76cfa6;
height: 4px;
height: 5px;
}
.mx_UploadBar_uploadFilename {
@@ -22,7 +39,7 @@
.mx_UploadBar_uploadIcon {
float: left;
margin-top: 1px;
margin-top: 5px;
margin-left: 14px;
}
@@ -36,8 +36,8 @@ limitations under the License.
-webkit-order: 1;
order: 1;
-webkit-flex: 0 0 83px;
flex: 0 0 83px;
-webkit-flex: 0 0 70px;
flex: 0 0 70px;
}
.mx_UserSettings_body {
@@ -50,9 +50,25 @@ limitations under the License.
-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;
@@ -78,20 +94,8 @@ limitations under the License.
cursor: pointer;
}
.mx_UserSettings h2 {
clear: both;
margin-top: 32px;
margin-bottom: 8px;
margin-left: 63px;
padding-bottom: 6px;
border-bottom: 1px solid #eee;
}
.mx_UserSettings h3 {
font-weight: bold;
font-size: 15px;
margin-top: 4px;
margin-bottom: 4px;
.mx_UserSettings_button.danger {
background-color: #ff0064;
}
.mx_UserSettings_section {
@@ -100,12 +104,38 @@ limitations under the License.
margin-bottom: 28px;
}
.mx_UserSettings_cryptoSection ul {
display: table;
}
.mx_UserSettings_cryptoSection li {
display: table-row;
}
.mx_UserSettings_cryptoSection label,
.mx_UserSettings_cryptoSection span {
display: table-cell;
padding-right: 1em;
}
.mx_UserSettings_toggle input {
width: 16px;
margin-right: 8px;
margin-bottom: 8px;
}
.mx_UserSettings_toggle label {
padding-bottom: 21px;
}
.mx_UserSettings_accountTable
.mx_UserSettings_notifTable
{
display: table;
}
.mx_UserSettings_notifTable .mx_Spinner {
position: absolute;
}
.mx_UserSettings_profileTable
{
display: table;
@@ -131,9 +131,19 @@ limitations under the License.
}
.mx_Login_loader {
position: absolute;
left: 50%;
margin-top: 12px;
display: inline;
position: relative;
top: 2px;
left: 8px;
}
.mx_Login_loader .mx_Spinner {
display: inline;
}
.mx_Login_loader .mx_Spinner img {
width: 16px;
height: 16px;
}
.mx_Login_error {
@@ -0,0 +1,65 @@
/*
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.
*/
/* Using a textarea for this element, to circumvent autofill */
.mx_ChatInviteDialog_input,
.mx_ChatInviteDialog_input:focus
{
height: 26px;
font-size: 14px;
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
padding-left: 12px;
padding-right: 12px;
margin: 0 !important;
border: 0 !important;
outline: 0 !important;
width: 1000%; /* Pretend that this is an "input type=text" */
resize: none;
overflow: hidden;
vertical-align: middle;
box-sizing: border-box;
word-wrap: nowrap;
}
.mx_ChatInviteDialog_inputContainer {
border-radius: 3px;
border: solid 1px #f0f0f0;
line-height: 36px;
padding-left: 4px;
padding-right: 4px;
padding-top: 1px;
padding-bottom: 1px;
max-height: 150px;
overflow-x: hidden;
overflow-y: auto;
}
.mx_ChatInviteDialog_error {
position: absolute;
color: #ff0064;
line-height: 36px;
}
.mx_ChatInviteDialog_cancel {
position: absolute;
right: 11px;
top: 13px;
cursor: pointer;
}
.mx_ChatInviteDialog_cancel object {
pointer-events: none;
}
@@ -0,0 +1,39 @@
/*
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_EncryptedEventDialog .mx_MemberDeviceInfo {
float: right;
padding: 0px;
margin-right: 42px;
}
.mx_EncryptedEventDialog .mx_MemberDeviceInfo_textButton {
border: 0px;
height: 36px;
border-radius: 40px;
border: solid 1px #76cfa6;
font-weight: 600;
font-size: 14px;
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
margin-left: 0px;
margin-right: 8px;
padding-left: 1.5em;
padding-right: 1.5em;
outline: none;
cursor: pointer;
color: #76cfa6;
background-color: #fff;
}
@@ -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_AddressSelector {
position: absolute;
background-color: #fff;
width: 485px;
max-height: 116px;
overflow-y: auto;
border-radius: 3px;
background-color: #fff;
border: solid 1px #76cfa6;
cursor: pointer;
}
.mx_AddressSelector.mx_AddressSelector_empty {
display: none;
}
.mx_AddressSelector_addressListElement .mx_AddressTile {
background-color: #fff;
border: solid 1px #fff;
}
.mx_AddressSelector_addressListElement.mx_AddressSelector_selected {
background-color: #eaf5f0; /* selected colour */
}
.mx_AddressSelector_addressListElement.mx_AddressSelector_selected .mx_AddressTile {
background-color: #eaf5f0; /* selected colour */
border: solid 1px #eaf5f0; /* selected colour */
}
@@ -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_AddressTile {
display: inline-block;
border-radius: 3px;
background-color: rgba(74, 73, 74, 0.1);
border: solid 1px #f0f0f0;
line-height: 26px;
color: #454545;
font-size: 14px;
font-weight: normal;
margin-right: 4px;
}
.mx_AddressTile.mx_AddressTile_error {
background-color: rgba(255, 0, 100, 0.1);
color: #ff0064;
border-color: #ff0064;
}
.mx_AddressTile_network {
display: inline-block;
position: relative;
padding-left: 2px;
padding-right: 4px;
vertical-align: middle;
}
.mx_AddressTile_avatar {
display: inline-block;
position: relative;
padding-left: 2px;
padding-right: 7px;
vertical-align: middle;
}
.mx_AddressTile_mx {
display: inline-block;
margin: 0;
border: 0;
padding: 0;
}
.mx_AddressTile_name {
display: inline-block;
padding-right: 4px;
font-weight: 600;
overflow: hidden;
height: 26px;
vertical-align: middle;
}
.mx_AddressTile_name.mx_AddressTile_justified {
width: 180px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
vertical-align: middle;
}
.mx_AddressTile_id {
display: inline-block;
padding-right: 11px;
}
.mx_AddressTile_id.mx_AddressTile_justified {
width: 200px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
vertical-align: middle;
}
.mx_AddressTile_unknownMx {
display: inline-block;
font-weight: 600;
padding-right: 11px;
}
.mx_AddressTile_unknownMxl.mx_AddressTile_justified {
width: 380px; /* name + id width */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
vertical-align: middle;
}
.mx_AddressTile_email {
display: inline-block;
font-weight: 600;
padding-right: 11px;
}
.mx_AddressTile_email.mx_AddressTile_justified {
width: 380px; /* name + id width */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
vertical-align: middle;
}
.mx_AddressTile_unknown {
display: inline-block;
padding-right: 11px;
}
.mx_AddressTile_unknown.mx_AddressTile_justified {
width: 380px; /* name + id width */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
vertical-align: middle;
}
.mx_AddressTile_dismiss {
display: inline-block;
padding-right: 11px;
padding-left: 1px;
cursor: pointer;
}
.mx_AddressTile_dismiss object {
pointer-events: none;
}
@@ -0,0 +1,72 @@
/*
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_DirectorySearchBox {
position: relative;
border-radius: 3px;
border: 1px solid #c7c7c7;
}
.mx_DirectorySearchBox_container {
display: flex;
display: -webkit-flex;
padding-left: 9px;
padding-right: 9px;
}
.mx_DirectorySearchBox_input {
flex-grow: 1;
-webkit-flex-grow: 1;
border: 0;
padding: 0;
font-weight: 300;
font-size: 13px;
}
input[type=text].mx_DirectorySearchBox_input:focus {
border: 0;
}
.mx_DirectorySearchBox_joinButton {
display: table-cell;
padding: 3px;
padding-left: 10px;
padding-right: 10px;
background-color: #efefef;
border-radius: 3px;
background-image: url('img/icon-return.svg');
background-position: 8px 70%;
background-repeat: no-repeat;
text-indent: 18px;
font-weight: 600;
font-size: 12px;
user-select: none;
cursor: pointer;
}
.mx_DirectorySearchBox_clear_wrapper {
display: table-cell;
}
.mx_DirectorySearchBox_clear {
display: inline-block;
vertical-align: middle;
background: url('img/icon_context_delete.svg');
background-position: 0 50%;
background-repeat: no-repeat;
width: 15px;
height: 15px;
cursor: pointer;
}
@@ -0,0 +1,39 @@
.mx_UserPill {
color: white;
background-color: #76cfa6;
padding: 2px 8px;
border-radius: 16px;
}
.mx_RoomPill {
background-color: white;
color: #76cfa6;
border: 1px solid #76cfa6;
padding: 2px 8px;
border-radius: 16px;
}
.mx_Markdown_BOLD {
font-weight: bold;
}
.mx_Markdown_ITALIC {
font-style: italic;
}
.mx_Markdown_CODE {
padding: .2em 0;
margin: 0;
font-size: 85%;
background-color: rgba(0,0,0,.04);
border-radius: 3px;
}
.mx_Markdown_HR {
display: block;
background: #e7e7e7;
}
.mx_Markdown_STRIKETHROUGH {
text-decoration: line-through;
}
@@ -14,6 +14,11 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_MImageBody {
display: block;
margin-right: 34px;
}
.mx_MImageBody_thumbnail {
max-width: 100%;
/*
@@ -25,7 +30,6 @@ limitations under the License.
.mx_MImageBody_download {
color: #76cfa6;
cursor: pointer;
}
.mx_MImageBody_download a {
@@ -17,3 +17,8 @@ limitations under the License.
.mx_MTextBody {
white-space: pre-wrap;
}
.mx_MTextBody pre{
overflow-y: auto;
max-height: 30vh;
}
@@ -0,0 +1,16 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_UnknownBody {
white-space: pre-wrap;
}
@@ -0,0 +1,79 @@
.mx_Autocomplete {
position: absolute;
bottom: 0;
z-index: 1000;
width: 100%;
border: 1px solid #e5e5e5;
background: white;
border-bottom: none;
border-radius: 4px 4px 0 0;
max-height: 50vh;
overflow: auto
}
.mx_Autocomplete_ProviderSection {
border-bottom: 1px solid #e5e5e5;
}
.mx_Autocomplete_Completion_container_pill {
margin: 12px;
display: flex;
}
/* a "block" completion takes up a whole line */
.mx_Autocomplete_Completion_block {
height: 34px;
display: flex;
padding: 0 12px;
user-select: none;
cursor: pointer;
align-items: center;
color: #4a4a4a;
}
.mx_Autocomplete_Completion_block * {
margin: 0 3px;
}
.mx_Autocomplete_Completion_pill {
border-radius: 17px;
height: 34px;
display: flex;
user-select: none;
cursor: pointer;
align-items: center;
color: #4a4a4a;
}
.mx_Autocomplete_Completion_pill * {
margin: 0 3px;
}
/* container for pill-style completions */
.mx_Autocomplete_Completion_container_pill {
margin: 12px;
display: flex;
flex-flow: wrap;
}
.mx_Autocomplete_Completion.selected {
background: #f6f6f6;
outline: none;
}
.mx_Autocomplete_provider_name {
margin: 12px;
color: #454545;
font-weight: 400;
opacity: 0.4;
}
/* styling for common completion elements */
.mx_Autocomplete_Completion_subtitle {
font-style: italic;
flex: 1;
}
.mx_Autocomplete_Completion_description {
color: gray;
}
@@ -52,6 +52,7 @@ limitations under the License.
display: table-cell;
vertical-align: middle;
overflow: hidden;
font-size: 14px;
text-overflow: ellipsis;
}
@@ -86,14 +87,17 @@ limitations under the License.
.mx_EntityTile_unavailable .mx_EntityTile_avatar,
.mx_EntityTile_unavailable .mx_EntityTile_name,
.mx_EntityTile_unavailable .mx_EntityTile_name_hover
.mx_EntityTile_unavailable .mx_EntityTile_name_hover,
.mx_EntityTile_offline_beenactive .mx_EntityTile_avatar,
.mx_EntityTile_offline_beenactive .mx_EntityTile_name,
.mx_EntityTile_offline_beenactive .mx_EntityTile_name_hover
{
opacity: 0.66;
}
.mx_EntityTile_offline .mx_EntityTile_avatar,
.mx_EntityTile_offline .mx_EntityTile_name,
.mx_EntityTile_offline .mx_EntityTile_name_hover
.mx_EntityTile_offline_neveractive .mx_EntityTile_avatar,
.mx_EntityTile_offline_neveractive .mx_EntityTile_name,
.mx_EntityTile_offline_neveractive .mx_EntityTile_name_hover
{
opacity: 0.25;
}
@@ -17,104 +17,91 @@ limitations under the License.
.mx_EventTile {
max-width: 100%;
clear: both;
margin-top: 24px;
margin-left: 65px;
padding-top: 18px;
font-size: 14px;
position: relative;
}
.mx_EventTile.mx_EventTile_info {
padding-top: 0px;
}
.mx_EventTile_avatar {
padding-left: 18px;
padding-right: 12px;
margin-left: -73px;
margin-top: -2px;
float: left;
position: relative;
top: 0px;
position: absolute;
top: 14px;
left: 8px;
cursor: pointer;
z-index: 2;
}
.mx_EventTile.mx_EventTile_info .mx_EventTile_avatar {
top: 8px;
left: 65px;
}
.mx_EventTile_continuation {
margin-top: 8px ! important;
padding-top: 0px ! important;
}
.mx_EventTile .mx_SenderProfile {
color: #454545;
opacity: 0.5;
font-size: 13px;
margin-bottom: 4px;
display: block;
font-size: 14px;
display: block; /* anti-zalgo, with overflow hidden */
overflow-y: hidden;
cursor: pointer;
padding-left: 65px; /* left gutter */
padding-bottom: 0px;
padding-top: 0px;
margin: 0px;
line-height: 22px;
}
.mx_EventTile .mx_MessageTimestamp {
display: block;
visibility: hidden;
white-space: nowrap;
color: #acacac;
font-size: 11px;
left: 8px;
position: absolute;
}
.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;
margin-right: 110px;
padding-left: 65px; /* left gutter */
padding-top: 4px;
padding-bottom: 2px;
border-radius: 4px;
min-height: 24px;
line-height: 22px;
}
/* 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;
.mx_EventTile_info .mx_EventTile_line {
padding-left: 83px;
}
/* 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;
/* HACK to override line-height which is already marked important elsewhere */
.mx_EventTile_bigEmoji.mx_EventTile_bigEmoji {
font-size: 48px ! important;
line-height: 48px ! important;
}
/* 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 {
.mx_EventTile_selected .mx_EventTile_line {
border-left: #76cfa6 5px solid;
margin-left: 53px;
padding-left: 7px;
padding-left: 60px;
background-color: #f7f7f7;
}
.mx_EventTile:hover .mx_EventTile_line,
.mx_EventTile.menu .mx_EventTile_line
{
background-color: #f7f7f7;
}
.mx_EventTile_searchHighlight {
@@ -131,6 +118,10 @@ limitations under the License.
color: #fff;
}
.mx_EventTile_encrypting {
color: #abddbc ! important;
}
.mx_EventTile_sending {
color: #ddd;
}
@@ -159,31 +150,33 @@ limitations under the License.
margin-right: 10px;
}
.mx_EventTile .mx_MessageTimestamp {
display: block;
visibility: hidden;
text-align: right;
.mx_EventTile_msgOption a {
text-decoration: none;
}
.mx_EventTile_last .mx_MessageTimestamp {
.mx_EventTile_last .mx_MessageTimestamp,
.mx_EventTile:hover .mx_MessageTimestamp,
.mx_EventTile.menu .mx_MessageTimestamp
{
visibility: visible;
}
.mx_EventTile:hover .mx_MessageTimestamp {
visibility: visible;
.mx_EventTile_selected .mx_MessageTimestamp {
left: 3px;
}
.mx_EventTile_editButton {
position: absolute;
display: inline-block;
visibility: hidden;
cursor: pointer;
top: 6px;
right: 6px;
}
.mx_EventTile:hover .mx_EventTile_editButton {
visibility: visible;
}
.mx_EventTile.menu .mx_EventTile_editButton {
.mx_EventTile:hover .mx_EventTile_editButton,
.mx_EventTile.menu .mx_EventTile_editButton
{
visibility: visible;
}
@@ -196,6 +189,13 @@ limitations under the License.
display: inline-block;
width: 14px;
height: 14px;
top: 29px;
}
.mx_EventTile_continuation .mx_EventTile_readAvatars,
.mx_EventTile_info .mx_EventTile_readAvatars
{
top: 7px;
}
.mx_EventTile_readAvatars .mx_BaseAvatar {
@@ -208,3 +208,100 @@ limitations under the License.
font-size: 11px;
position: absolute;
}
/* 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;
margin-right: 34px;
}
/* De-zalgoing */
.mx_EventTile_body {
overflow-y: hidden;
}
/* End to end encryption stuff */
.mx_EventTile_e2eIcon {
display: block;
position: absolute;
top: 9px;
left: 46px;
z-index: 2;
cursor: pointer;
}
.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line,
.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line {
padding-left: 60px;
}
.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line {
border-left: #76cfa5 5px solid;
}
.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line {
border-left: #e8bf37 5px solid;
}
.mx_EventTile:hover.mx_EventTile_verified .mx_MessageTimestamp,
.mx_EventTile:hover.mx_EventTile_unverified .mx_MessageTimestamp {
left: 3px;
}
/*
.mx_EventTile_verified .mx_EventTile_e2eIcon {
display: none;
}
*/
.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_e2eIcon,
.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_e2eIcon {
display: block;
left: 41px;
}
/* Various markdown overrides */
.mx_EventTile_content .markdown-body {
font-family: inherit ! important;
white-space: normal ! important;
line-height: inherit ! important;
color: inherit;
font-size: 14px;
}
/* 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 */
@@ -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-wrap: 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;
}
@@ -0,0 +1,69 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_MemberDeviceInfo {
padding: 10px 0px;
}
.mx_MemberDeviceInfo_textButton {
color: #fff;
background-color: #76cfa6;
border-radius: 17px;
text-align: center;
padding-left: 1em;
padding-right: 1em;
width: 95px;
border: 0px;
font-size: 14px;
cursor: pointer;
display: inline;
}
.mx_MemberDeviceInfo_deviceId {
font-size: 13px;
}
.mx_MemberDeviceInfo_deviceInfo {
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid rgba(0,0,0,0.1);
}
.mx_MemberDeviceInfo_block,
.mx_MemberDeviceInfo_unblock {
float: right;
}
.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_verified,
.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_unverified,
.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_blocked {
float: right;
padding-left: 1em;
}
.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_verified {
color: #76cfa5;
}
.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_unverified {
color: #e8bf37;
}
.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_blocked {
color: #ba6363;
}
@@ -15,16 +15,31 @@ limitations under the License.
*/
.mx_MemberInfo {
margin-top: 20px;
padding-right: 20px;
height: 100%;
overflow-y: auto;
}
.mx_MemberInfo h2 {
margin-top: 6px;
}
.mx_MemberInfo .mx_RoomTile_nameContainer {
width: 154px;
}
.mx_MemberInfo .mx_RoomTile_badge {
display: none;
}
.mx_MemberInfo .mx_RoomTile_name {
width: 160px;
}
.mx_MemberInfo_cancel {
float: right;
margin-right: 18px;
margin-right: 10px;
cursor: pointer;
}
@@ -32,6 +47,14 @@ limitations under the License.
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;
}
@@ -63,3 +86,13 @@ limitations under the License.
margin-left: 8px;
line-height: 23px;
}
.mx_MemberInfo_createRoom {
cursor: pointer;
}
.mx_MemberInfo_createRoom_label {
width: initial ! important;
cursor: pointer;
}
@@ -17,6 +17,9 @@ limitations under the License.
.mx_MemberList {
height: 100%;
margin-top: 12px;
margin-right: 20px;
-webkit-flex: 1;
flex: 1;
@@ -49,15 +52,29 @@ limitations under the License.
flex: 1 1 0px;
}
.mx_MemberList .mx_SearchableEntityList {
order: 1;
flex: 0 0 auto;
-webkit-flex: 0 0 auto;
.mx_MemberList_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: 14px;
margin-bottom: 8px;
width: 189px;
}
.mx_MemberList .mx_SearchableEntityList_expanded {
flex: 1 0 0;
-webkit-flex: 1 0 0;
.mx_MemberList_query::-moz-placeholder {
color: #454545;
opacity: 0.5;
font-size: 14px;
}
.mx_MemberList_query::-webkit-input-placeholder {
color: #454545;
opacity: 0.5;
font-size: 14px;
}
.mx_MemberList_joined {
@@ -77,17 +94,6 @@ limitations under the License.
}
*/
.mx_MemberList_bottom {
order: 4;
flex: 0 0 72px;
-webkit-flex: 0 0 72px;
}
.mx_MemberList_bottomRule {
border-top: 2px solid #e1dddd;
margin-right: 15px;
}
.mx_MemberList_invited h2 {
text-transform: uppercase;
color: #3d3b39;
@@ -18,35 +18,86 @@ limitations under the License.
max-width: 960px;
vertical-align: middle;
margin: auto;
border-top: 2px solid #e1dddd;
border-top: 1px solid #e5e5e5;
position: relative;
}
.mx_MessageComposer_autocomplete_wrapper {
position: relative;
height: 0;
}
.mx_MessageComposer_row {
display: table-row;
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
}
.mx_MessageComposer .mx_MessageComposer_avatar {
display: table-cell;
padding-left: 10px;
padding-right: 28px;
vertical-align: middle;
}
.mx_MessageComposer .mx_MessageComposer_avatar .mx_BaseAvatar {
display: block;
}
.mx_MessageComposer_input {
display: table-cell;
.mx_MessageComposer_composecontrols {
width: 100%;
}
.mx_MessageComposer_e2eIcon {
position: absolute;
left: 44px;
}
.mx_MessageComposer_noperm_error {
width: 100%;
height: 60px;
text-align: center;
font-style: italic;
color: #888;
}
.mx_MessageComposer_input_wrapper {
flex: 1;
display: flex;
flex-direction: column;
}
.mx_MessageComposer_input {
flex: 1;
vertical-align: middle;
height: 70px;
display: flex;
flex-direction: column;
min-height: 60px;
justify-content: center;
align-items: flex-start;
font-size: 14px;
margin-right: 6px;
}
.mx_MessageComposer_input_empty .public-DraftEditorPlaceholder-root {
display: none;
}
.mx_MessageComposer_input .DraftEditor-root {
width: 100%;
flex: 1;
max-height: 120px;
overflow: auto;
}
.mx_MessageComposer_input blockquote {
color: rgb(119, 119, 119);
margin: 0 0 16px;
padding: 0 15px;
border-left: 4px solid rgb(221, 221, 221);
}
.mx_MessageComposer_input textarea {
display: block;
font-size: 15px;
width: 100%;
padding: 0px;
margin-top: 6px;
@@ -59,7 +110,9 @@ limitations under the License.
box-shadow: none;
color: #454545;
background-color: #fff;
font-size: 14px;
max-height: 120px;
overflow: auto;
/* needed for FF */
font-family: 'Open Sans', Arial, Helvetica, Sans-Serif;
}
@@ -78,11 +131,12 @@ limitations under the License.
.mx_MessageComposer_hangup,
.mx_MessageComposer_voicecall,
.mx_MessageComposer_videocall {
display: table-cell;
vertical-align: middle;
padding-left: 10px;
padding-right: 10px;
/*display: table-cell;*/
/*vertical-align: middle;*/
/*padding-left: 10px;*/
padding-right: 5px;
cursor: pointer;
padding-top: 4px;
}
.mx_MessageComposer_upload object,
@@ -92,16 +146,59 @@ limitations under the License.
pointer-events: none;
}
.mx_MessageComposer_videocall {
padding-right: 10px;
padding-top: 4px;
.mx_MessageComposer_formatting {
cursor: pointer;
margin: 0 11px;
}
.mx_MessageComposer_voicecall {
padding-right: 10px;
padding-top: 4px;
.mx_MessageComposer_formatbar_wrapper {
width: 100%;
background-color: #f7f7f7;
box-shadow: inset 0 1px 0 0 rgba(0, 0, 0, 0.08);
}
.mx_MessageComposer_upload object {
margin-top: 5px;
.mx_MessageComposer_formatbar {
margin: auto;
max-width: 960px;
display: flex;
height: 30px;
box-sizing: border-box;
padding-left: 62px;
flex-direction: row;
align-items: center;
font-size: 10px;
color: #888;
}
.mx_MessageComposer_formatbar * {
margin-right: 4px;
}
.mx_MessageComposer_format_button,
.mx_MessageComposer_formatbar_cancel,
.mx_MessageComposer_formatbar_markdown {
cursor: pointer;
}
.mx_MessageComposer_format_button_disabled {
cursor: not-allowed;
opacity: 0.5;
}
.mx_MessageComposer_formatbar_cancel {
margin-right: 22px;
}
.mx_MessageComposer_formatbar_markdown {
margin-right: 64px;
}
.mx_MessageComposer_input_markdownIndicator {
cursor: pointer;
height: 10px;
padding: 4px 4px 4px 0;
opacity: 0.8;
}
@@ -23,8 +23,7 @@ limitations under the License.
.mx_RoomHeader_wrapper {
max-width: 960px;
margin: auto;
height: 83px;
border-bottom: 1px solid #eeeeee;
height: 70px;
-webkit-align-items: center;
align-items: center;
@@ -36,10 +35,6 @@ limitations under the License.
display: flex;
}
.mx_RoomHeader_editing .mx_RoomHeader_wrapper {
border-bottom: 1px solid transparent;
}
.mx_RoomHeader_leftRow {
margin-left: -2px;
@@ -53,6 +48,19 @@ limitations under the License.
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;
@@ -95,7 +103,8 @@ limitations under the License.
.mx_RoomHeader_rightRow {
margin-top: 4px;
background-color: #fff;
display: flex;
align-items: center;
-webkit-box-ordinal-group: 3;
-moz-box-ordinal-group: 3;
-ms-flex-order: 3;
@@ -110,7 +119,7 @@ limitations under the License.
}
.mx_RoomHeader_simpleHeader {
line-height: 83px;
line-height: 70px;
color: #454545;
font-size: 22px;
font-weight: bold;
@@ -120,11 +129,8 @@ limitations under the License.
width: 100%;
}
.mx_RoomHeader_simpleHeaderCancel {
.mx_RoomHeader_simpleHeader .mx_RoomHeader_cancelButton {
float: right;
margin-top: 8px;
padding: 24px;
cursor: pointer;
}
.mx_RoomHeader_name {
@@ -156,13 +162,6 @@ limitations under the License.
opacity: 0.6;
}
.mx_RoomHeader_settingsButton {
display: inline-block;
position: relative;
bottom: 10px;
left: 4px;
}
.mx_RoomHeader_settingsButton object {
pointer-events: none;
}
@@ -178,10 +177,6 @@ limitations under the License.
color: #76cfa6;
}
.mx_RoomHeader_leaveButton {
margin-top: -1px;
}
.mx_RoomHeader_placeholder {
color: #a2a2a2 ! important;
}
@@ -202,8 +197,9 @@ limitations under the License.
vertical-align: bottom;
float: left;
max-height: 42px;
color: #454545;
color: #A2A2A2;
font-weight: 300;
font-size: 13px;
margin-left: 19px;
margin-right: 16px;
overflow: hidden;
@@ -237,10 +233,7 @@ limitations under the License.
}
.mx_RoomHeader_button {
display: table-cell;
vertical-align: top;
padding-left: 8px;
padding-right: 8px;
margin-left: 12px;
cursor: pointer;
}
@@ -15,7 +15,6 @@ limitations under the License.
*/
.mx_RoomList {
padding-top: 24px;
padding-bottom: 12px;
min-height: 400px;
}
@@ -33,3 +32,8 @@ limitations under the License.
overflow-x: hidden ! important;
overflow-y: scroll ! important;
}
/* Make sure the scrollbar is above the sticky headers from RoomList */
.mx_RoomList_scrollbar .gm-scrollbar.-vertical {
z-index: 6;
}
@@ -19,6 +19,30 @@ limitations under the License.
margin-bottom: 20px;
}
.mx_RoomSettings_leaveButton,
.mx_RoomSettings_integrationsButton {
height: 36px;
background-color: #76cfa6;
border-radius: 36px;
margin-right: 8px;
color: #fff;
line-height: 34px;
text-align: center;
float: right;
cursor: pointer;
padding-left: 12px;
padding-right: 12px;
}
.mx_RoomSettings_e2eIcon {
padding-left: 4px;
padding-right: 7px;
}
.mx_RoomSettings_leaveButton {
margin-right: 32px;
}
.mx_RoomSettings_powerLevels {
display: table;
}
@@ -73,12 +97,14 @@ limitations under the License.
height: 37px;
border: 1px solid #979797;
margin-right: 13px;
cursor: pointer;
}
.mx_RoomSettings .mx_RoomSettings_roomColor_selected {
position: absolute;
left: 10px;
top: 4px;
cursor: default ! important;
}
.mx_RoomSettings .mx_RoomSettings_roomColorPrimary {
@@ -15,121 +15,183 @@ limitations under the License.
*/
.mx_RoomTile {
position: relative;
cursor: pointer;
/* This fixes wrapping of long room names, but breaks drag & drop previews */
/* display: table-row; */
font-size: 13px;
display: block;
height: 34px;
}
.mx_RoomTile_tooltip {
display: inline-block;
position: relative;
top: -54px;
left: -12px;
}
.mx_RoomTile_nameContainer {
display: inline-block;
width: 180px;
height: 24px;
}
.mx_RoomTile_avatar_container {
position: relative;
}
.mx_RoomTile_avatar {
display: table-cell;
padding-right: 8px;
padding-top: 6px;
padding-bottom: 6px;
padding-left: 18px;
display: inline-block;
padding-top: 5px;
padding-bottom: 5px;
padding-left: 16px;
padding-right: 6px;
width: 24px;
height: 24px;
position: relative;
vertical-align: middle;
}
.mx_RoomTile_dm {
display: block;
position: absolute;
bottom: 0;
right: -5px;
z-index: 2;
}
.mx_RoomTile:hover .mx_RoomTile_avatar_container:before,
.mx_RoomTile_avatar_container.mx_RoomTile_avatar_roomTagMenu:before {
display: block;
position: absolute;
content: "";
border-radius: 40px;
background-image: url("img/icons_ellipsis.svg");
background-size: 25px;
width: 24px;
height: 24px;
z-index: 4;
}
.mx_RoomTile:hover .mx_RoomTile_avatar_container:after,
.mx_RoomTile_avatar_container.mx_RoomTile_avatar_roomTagMenu:after {
display: block;
position: absolute;
content: "";
border-radius: 40px;
background: #4A4A4A;
bottom: 0;
width: 24px;
height: 24px;
opacity: 0.6;
z-index: 1;
}
.collapsed .mx_RoomTile:hover .mx_RoomTile_avatar_container:before {
display: none;
}
.collapsed .mx_RoomTile:hover .mx_RoomTile_avatar_container:after {
display: none;
}
.mx_RoomTile_name {
display: table-cell;
width: 100%;
display: inline-block;
position: relative;
width: 165px;
vertical-align: middle;
padding-left: 6px;
padding-right: 6px;
padding-top: 2px;
padding-bottom: 3px;
color: rgba(69, 69, 69, 0.8);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding-right: 16px;
color: rgba(69, 69, 69, 0.8);
}
.mx_RoomTile_ellipsis .mx_RoomTile_name {
font-style: italic;
color: #454545;
}
.mx_RoomTile_invite {
/* color: rgba(69, 69, 69, 0.5);
*/
/* color: rgba(69, 69, 69, 0.5); */
}
.collapsed .mx_RoomTile_nameContainer {
width: 60px; /* colapsed panel width */
}
.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: #76cfa6;
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;
.collapsed .mx_RoomTile_badge {
top: 0px;
min-width: 12px;
border-radius: 16px;
width: 9px;
height: 9px;
position: absolute;
right: 9px;
bottom: 3px;
padding: 0px 4px 0px 4px;
z-index: 3;
}
/* Hide the bottom of speech bubble */
.collapsed .mx_RoomTile_highlight .mx_RoomTile_badge:after {
display: none;
}
/* This is the bottom of the speech bubble */
.mx_RoomTile_highlight .mx_RoomTile_badge:after {
content: "";
position: absolute;
display: block;
width: 0;
height: 0;
margin-left: 5px;
border-top: 5px solid #ff0064;
border-right: 7px solid transparent;
}
*/
.mx_RoomTile_badge {
background-color: #ff0064;
width: 4px;
display: inline-block;
min-width: 15px;
height: 15px;
position: absolute;
left: 0px;
top: 5px;
bottom: 5px;
right: 8px; /*gutter */
top: 9px;
border-radius: 8px;
color: #fff;
font-weight: 600;
font-size: 10px;
text-align: center;
padding-top: 1px;
padding-left: 4px;
padding-right: 4px;
}
.mx_RoomTile .mx_RoomTile_badge.mx_RoomTile_badgeButton,
.mx_RoomTile.mx_RoomTile_notificationStateMenu .mx_RoomTile_badge {
letter-spacing: 0.1em;
opacity: 1;
}
.mx_RoomTile.mx_RoomTile_noBadges .mx_RoomTile_badge.mx_RoomTile_badgeButton,
.mx_RoomTile.mx_RoomTile_notificationStateMenu.mx_RoomTile_noBadges .mx_RoomTile_badge {
background-color: rgb(214, 214, 214);
}
.mx_RoomTile_unreadNotify .mx_RoomTile_badge {
background-color: #454545;
background-color: #76cfa6;
}
.mx_RoomTile_highlight .mx_RoomTile_badge {
background-color: #ff0064;
}
.mx_RoomTile_unread,
.mx_RoomTile_highlight {
font-weight: bold;
.mx_RoomTile_unread, .mx_RoomTile_highlight {
font-weight: 800;
}
.mx_RoomTile_selected .mx_RoomTile_name {
color: #76cfa6 ! important;
.mx_RoomTile_selected {
background-color: rgba(255, 255, 255, 0.8);
}
.mx_RoomTile_highlight .mx_RoomTile_name {
color: #ff0064 ! important;
}
.mx_RoomTile.mx_RoomTile_selected .mx_RoomTile_name {
background: url('img/selected.png');
background-repeat: no-repeat;
background-position: right center;
.mx_RoomTile .mx_RoomTile_name.mx_RoomTile_badgeShown {
width: 140px;
}
.mx_RoomTile_arrow {
@@ -137,5 +199,3 @@ limitations under the License.
right: 0px;
}
.mx_RoomTile:hover {
}
@@ -32,7 +32,7 @@ limitations under the License.
margin-left: 3px;
font-size: 15px;
margin-bottom: 8px;
width: 180px;
width: 189px;
}
.mx_SearchableEntityList_query::-moz-placeholder {
@@ -21,6 +21,7 @@ limitations under the License.
.mx_TabCompleteBar_item {
display: inline-block;
margin-right: 15px;
margin-bottom: 2px;
cursor: pointer;
}
@@ -33,10 +34,13 @@ limitations under the License.
padding-bottom: 2px;
margin-bottom: 6px;
border-radius: 30px;
position: relative;
top: 1px;
}
.mx_TabCompleteBar_command .mx_TabCompleteBar_text {
opacity: 1.0;
vertical-align: initial;
color: #fff;
}
@@ -47,5 +51,6 @@ limitations under the License.
.mx_TabCompleteBar_text {
color: #4a4a4a;
vertical-align: middle;
opacity: 0.5;
}
@@ -19,7 +19,7 @@ limitations under the License.
max-width: 960px;
padding-top: 5px;
padding-bottom: 5px;
border-bottom: 1px solid #eee;
border-bottom: 1px solid #e5e5e5;
}
.mx_TopUnreadMessagesBar_scrollUp {
@@ -0,0 +1,51 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_DevicesPanel {
display: table;
table-layout: fixed;
width: 880px;
border-spacing: 2px;
}
.mx_DevicesPanel_header {
display: table-header-group;
font-weight: bold;
}
.mx_DevicesPanel_header > div {
display: table-cell;
}
.mx_DevicesPanel_header .mx_DevicesPanel_deviceLastSeen {
width: 30%;
}
.mx_DevicesPanel_header .mx_DevicesPanel_deviceButtons {
width: 20%;
}
.mx_DevicesPanel_device {
display: table-row;
}
.mx_DevicesPanel_device > div {
display: table-cell;
}
.mx_DevicesPanel_myDevice {
font-weight: bold;
}
@@ -0,0 +1,31 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_IntegrationsManager .mx_Dialog {
width: 60%;
height: 70%;
overflow: hidden;
padding: 0px;
max-width: initial;
max-height: initial;
}
.mx_IntegrationsManager iframe {
background-color: #fff;
border: 0px;
width: 100%;
height: 100%;
}
@@ -12,4 +12,14 @@ 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_CallView_voice {
background-color: #76cfa6;
color: #fff;
cursor: pointer;
text-align: center;
padding: 6px;
font-weight: bold;
font-size: 13px;
}
+65
View File
@@ -0,0 +1,65 @@
/*
* Open Sans
* Includes extended Latin, Greek, Cyrillic and Vietnamese character sets
*/
@font-face {
font-family: 'Open Sans';
src: url('fonts/Open_Sans/OpenSans-Regular.ttf') format('truetype');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Open Sans';
src: url('fonts/Open_Sans/OpenSans-Italic.ttf') format('truetype');
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: 'Open Sans';
src: url('fonts/Open_Sans/OpenSans-Semibold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Open Sans';
src: url('fonts/Open_Sans/OpenSans-SemiboldItalic.ttf') format('truetype');
font-weight: 600;
font-style: italic;
}
@font-face {
font-family: 'Open Sans';
src: url('fonts/Open_Sans/OpenSans-Bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'Open Sans';
src: url('fonts/Open_Sans/OpenSans-BoldItalic.ttf') format('truetype');
font-weight: 700;
font-style: italic;
}
/*
* Fira Mono
* Used for monospace copy, i.e. code
*/
@font-face {
font-family: 'Fira Mono';
src: url('fonts/Fira_Mono/FiraMono-Regular.ttf') format('truetype');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Fira Mono';
src: url('fonts/Fira_Mono/FiraMono-Bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
}
@@ -49,6 +49,11 @@ limitations under the License.
flex: 1 1 0;
overflow-y: auto;
z-index: 6;
}
.mx_LeftPanel.collapsed .mx_BottomLeftMenu {
flex: 0 0 160px;
}
.mx_LeftPanel .mx_BottomLeftMenu {
@@ -58,23 +63,56 @@ limitations under the License.
-webkit-order: 3;
order: 3;
-webkit-flex: 0 0 140px;
flex: 0 0 140px;
background-color: rgba(118,207,166,0.2);
border-top: 1px solid rgba(118, 207, 166, 0.2);
margin-left: 16px; /* gutter */
margin-right: 16px; /* gutter */
-webkit-flex: 0 0 60px;
flex: 0 0 60px;
z-index: 1;
}
.mx_LeftPanel .mx_BottomLeftMenu .mx_RoomTile {
color: #454545;
.mx_LeftPanel .mx_BottomLeftMenu_options {
margin-top: 18px;
}
.mx_LeftPanel .mx_BottomLeftMenu .mx_BottomLeftMenu_options {
margin-top: 15px;
width: 100%;
.mx_BottomLeftMenu_options object {
pointer-events: none;
}
.mx_LeftPanel .mx_BottomLeftMenu img {
border-radius: 0px;
background-color: transparent;
vertical-align: middle;
}
.mx_LeftPanel .mx_BottomLeftMenu_directory,
.mx_LeftPanel .mx_BottomLeftMenu_createRoom,
.mx_LeftPanel .mx_BottomLeftMenu_people,
.mx_LeftPanel .mx_BottomLeftMenu_settings {
display: inline-block;
cursor: pointer;
}
.collapsed .mx_BottomLeftMenu_directory,
.collapsed .mx_BottomLeftMenu_createRoom,
.collapsed .mx_BottomLeftMenu_people,
.collapsed .mx_BottomLeftMenu_settings {
margin-right: 0px ! important;
padding-top: 3px ! important;
padding-bottom: 3px ! important;
}
.mx_LeftPanel .mx_BottomLeftMenu_directory,
.mx_LeftPanel .mx_BottomLeftMenu_createRoom,
.mx_LeftPanel .mx_BottomLeftMenu_people {
margin-right: 10px;
}
.mx_LeftPanel .mx_BottomLeftMenu_settings {
float: right;
}
.mx_LeftPanel.collapsed .mx_BottomLeftMenu_settings {
float: none;
}
.mx_LeftPanel .mx_BottomLeftMenu_tooltip {
display: inline-block;
position: relative;
top: -25px;
left: 6px;
}
@@ -33,60 +33,100 @@ limitations under the License.
-webkit-order: 1;
order: 1;
-webkit-flex: 0 0 83px;
flex: 0 0 83px;
border-bottom: 1px solid #e5e5e5;
margin-right: 20px;
-webkit-flex: 0 0 70px;
flex: 0 0 70px;
}
/** Fixme - factor this out with the main header **/
.mx_RightPanel_headerButtonGroup {
margin-top: 32px;
margin-top: 6px;
float: left;
background-color: #fff;
margin-left: -4px;
margin-left: 0px;
}
.mx_RightPanel_headerButton {
cursor: pointer;
display: table-cell;
vertical-align: middle;
padding-left: 15px;
padding-right: 15px;
vertical-align: top;
padding-left: 4px;
padding-right: 5px;
text-align: center;
position: relative;
}
.mx_RightPanel_headerButton object {
pointer-events: none;
padding-bottom: 3px;
}
.mx_RightPanel_headerButton_highlight {
position: absolute;
bottom: -2px;
left: 10px;
width: 25px;
height: 4px;
background-color: #76cfa6;
height: 5px;
border-radius: 5px;
background-color: rgba(118, 207, 166, 0.2);
}
.mx_RightPanel_headerButton_badge {
position: absolute;
top: 4px;
left: 28px;
font-size: 12px;
background-color: #76cfa6;
color: #fff;
font-size: 11px;
color: #76cfa6;
font-weight: bold;
border-radius: 20px;
padding-left: 4px;
padding-right: 4px;
padding-top: 0px;
padding-bottom: 2px;
}
.mx_RightPanel .mx_MemberList,
.mx_RightPanel .mx_MemberInfo {
.mx_RightPanel .mx_MemberInfo,
.mx_RightPanel_blank {
-webkit-box-ordinal-group: 2;
-moz-box-ordinal-group: 2;
-ms-flex-order: 2;
-webkit-order: 2;
order: 2;
flex: 1 1 0;
-webkit-flex: 1 1 0;
}
.mx_RightPanel_footer {
-webkit-box-ordinal-group: 3;
-moz-box-ordinal-group: 3;
-ms-flex-order: 3;
-webkit-order: 3;
order: 3;
border-top: 1px solid #e5e5e5;
margin-right: 20px;
-webkit-flex: 0 0 60px;
flex: 0 0 60px;
}
.mx_RightPanel_footer .mx_RightPanel_invite {
line-height: 35px;
font-size: 14px;
color: #4A4A4A;
padding-top: 13px;
padding-left: 5px;
cursor: pointer;
}
.collapsed .mx_RightPanel_footer .mx_RightPanel_invite {
display: none;
}
.mx_RightPanel_invite .mx_RightPanel_icon {
display: inline-block;
}
.mx_RightPanel_invite .mx_RightPanel_icon object {
pointer-events: none;
}
.mx_RightPanel_invite .mx_RightPanel_message {
display: inline-block;
vertical-align: top;
padding-left: 10px
}
@@ -46,15 +46,27 @@ limitations under the License.
-webkit-flex-direction: column;
}
.mx_RoomDirectory_input {
margin: auto;
border-radius: 3px;
border: 1px solid #c7c7c7;
font-weight: 300;
font-size: 13px;
padding: 9px;
.mx_RoomDirectory_list .mx_RoomView_messageListWrapper {
justify-content: flex-start;
-webkit-justify-content: flex-start;
}
.mx_RoomDirectory_listheader {
display: table;
table-layout: fixed;
width: 100%;
margin-top: 12px;
margin-bottom: 12px;
border-spacing: 5px;
}
.mx_RoomDirectory_searchbox {
display: table-cell;
}
.mx_RoomDirectory_listheader .mx_NetworkDropdown {
display: table-cell;
width: 200px;
}
.mx_RoomDirectory_tableWrapper {
@@ -20,22 +20,222 @@ limitations under the License.
width: 100%;
}
.mx_RoomSubList_labelContainer {
height: 31px; /* mx_RoomSubList_label height including border */
width: 235px; /* LHS Panel width */
position: relative;
}
.mx_RoomSubList_label {
position: relative;
text-transform: uppercase;
color: #3d3b39;
font-weight: 600;
font-size: 13px;
padding-left: 12px;
padding-right: 12px;
margin-top: 8px;
margin-bottom: 4px;
font-size: 12px;
width: 203px; /* padding + width = LHS Panel width */
height: 17px; /* padding + height = 29px, same as mx_RoomSubList_stickyContainer */
padding-left: 16px; /* gutter */
padding-right: 16px; /* gutter */
padding-top: 6px;
padding-bottom: 6px;
cursor: pointer;
background-color: #d3efe1;
border-top: solid 2px #eaf5f0;
}
.mx_RoomSubList_label.mx_RoomSubList_fixed {
position: fixed;
top: 0;
z-index: 5;
/* pointer-events: none; */
}
.collapsed .mx_RoomSubList_label {
height: 17px;
width: 28px; /* collapsed LHS Panel width */
}
.collapsed .mx_RoomSubList_labelContainer {
width: 28px; /* collapsed LHS Panel width */
}
.mx_RoomSubList_roomCount {
display: inline-block;
font-size: 12px;
font-weight: normal;
color: #76cfa6;
padding-left: 5px;
text-transform: none;
}
.collapsed .mx_RoomSubList_roomCount {
display: none;
}
.mx_RoomSubList_badge {
display: inline-block;
min-width: 15px;
height: 15px;
position: absolute;
right: 8px; /*gutter */
top: 7px;
border-radius: 8px;
color: #fff;
font-weight: 600;
font-size: 10px;
text-align: center;
padding-top: 1px;
padding-left: 4px;
padding-right: 4px;
background-color: #76cfa6;
}
/*
.collapsed .mx_RoomSubList_badge {
display: none;
}
*/
.mx_RoomSubList_badgeHighlight {
background-color: #ff0064;
}
/* This is the bottom of the speech bubble */
.mx_RoomSubList_badgeHighlight:after {
content: "";
position: absolute;
display: block;
width: 0;
height: 0;
margin-left: 5px;
border-top: 5px solid #ff0064;
border-right: 7px solid transparent;
}
/* Hide the bottom of speech bubble */
.collapsed .mx_RoomSubList_badgeHighlight:after {
display: none;
}
.mx_RoomSubList_chevron {
padding-left: 5px;
pointer-events: none;
position: absolute;
right: 41px;
top: 11px;
}
.collapsed .mx_RoomSubList_chevron {
padding-left: 13px;
.mx_RoomSubList_chevronDown {
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 6px solid #76cfa6;
}
.mx_RoomSubList_chevronUp {
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 6px solid #76cfa6;
}
.mx_RoomSubList_chevronRight {
width: 0;
height: 0;
border-top: 5px solid transparent;
border-left: 6px solid #76cfa6;
border-bottom: 5px solid transparent;
}
/* The overflow section */
.mx_RoomSubList_ellipsis {
display: block;
line-height: 11px;
height: 18px;
position: relative;
cursor: pointer;
font-size: 13px;
}
.collapsed .mx_RoomSubList_ellipsis {
height: 20px;
}
.mx_RoomSubList_line {
display: inline-block;
width: 159px;
border-top: dotted 2px #76cfa6;
vertical-align: middle;
}
.collapsed .mx_RoomSubList_line {
display: none;
}
.mx_RoomSubList_more {
display: inline-block;
text-transform: uppercase;
font-size: 10px;
font-weight: 600;
text-align: left;
color: #76cfa6;
padding-left: 7px;
padding-right: 7px;
padding-left: 7px;
vertical-align: middle;
}
.collapsed .mx_RoomSubList_more {
display: none;
}
.mx_RoomSubList_moreBadge {
display: inline-block;
min-width: 15px;
height: 13px;
position: absolute;
right: 8px; /*gutter */
top: -2px;
border-radius: 8px;
border: solid 1px #76cfa6;
color: #fff;
font-weight: 600;
font-size: 10px;
text-align: center;
padding-top: 1px;
padding-left: 3px;
padding-right: 3px;
background-color: #fff;
vertical-align: middle;
}
.mx_RoomSubList_moreBadge.mx_RoomSubList_moreBadgeNotify {
background-color: #76cfa6;
border: 0;
padding-top: 3px;
padding-left: 4px;
padding-right: 4px;
}
.mx_RoomSubList_moreBadge.mx_RoomSubList_moreBadgeHighlight {
background-color: #ff0064;
border: 0;
padding-top: 3px;
padding-left: 4px;
padding-right: 4px;
}
.collapsed .mx_RoomSubList_moreBadge {
position: static;
margin-left: 16px;
margin-top: 2px;
}
.mx_RoomSubList_ellipsis .mx_RoomSubList_chevronDown {
position: relative;
top: 4px;
left: 2px;
}
@@ -19,4 +19,5 @@ limitations under the License.
font-size: 12px;
padding: 0.5em 1em 0.5em 1em;
word-wrap: break-word;
white-space: pre-wrap;
}
@@ -0,0 +1,25 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_MessageContextMenu_field {
padding: 3px 6px 3px 6px;
cursor: pointer;
white-space: nowrap;
}
.mx_MessageContextMenu_field.mx_MessageContextMenu_fieldSet {
font-weight: bold;
}
@@ -0,0 +1,56 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_NotificationStateContextMenu_picker {
position: absolute;
top: 16px;
left: 5px;
}
.mx_NotificationStateContextMenu_field {
padding-top: 4px;
padding-right: 6px;
padding-bottom: 10px;
padding-left: 8px; /* 20px */
cursor: pointer;
white-space: nowrap;
display: flex;
align-items: center;
}
.mx_NotificationStateContextMenu_field.mx_NotificationStateContextMenu_fieldSet {
font-weight: bold;
}
.mx_NotificationStateContextMenu_field.mx_NotificationStateContextMenu_fieldDisabled {
color: rgba(0, 0, 0, 0.2);
}
.mx_NotificationStateContextMenu_icon {
padding-right: 4px;
padding-left: 4px;
}
.mx_NotificationStateContextMenu_activeIcon {
display: inline-block;
opacity: 0;
position: relative;
left: -5px;
}
.mx_NotificationStateContextMenu_fieldSet .mx_NotificationStateContextMenu_activeIcon {
opacity: 1;
}
@@ -0,0 +1,79 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_RoomTagContextMenu_field {
padding-top: 8px;
padding-right: 20px;
padding-bottom: 8px;
cursor: pointer;
white-space: nowrap;
display: flex;
align-items: center;
line-height: 16px;
}
.mx_RoomTagContextMenu_field:first-child {
padding-top: 4px;
}
.mx_RoomTagContextMenu_field:last-child {
padding-bottom: 4px;
color: #ff0064;
}
.mx_RoomTagContextMenu_field.mx_RoomTagContextMenu_fieldSet {
font-weight: bold;
}
.mx_RoomTagContextMenu_field.mx_RoomTagContextMenu_fieldSet .mx_RoomTagContextMenu_icon {
display: none;
}
.mx_RoomTagContextMenu_field.mx_RoomTagContextMenu_fieldSet .mx_RoomTagContextMenu_icon_set {
display: inline-block;
}
.mx_RoomTagContextMenu_field.mx_RoomTagContextMenu_fieldDisabled {
color: rgba(0, 0, 0, 0.2);
}
.mx_RoomTagContextMenu_icon {
padding-right: 8px;
padding-left: 4px;
display: inline-block
}
.mx_RoomTagContextMenu_icon_set {
padding-right: 8px;
padding-left: 4px;
display: none;
}
.mx_RoomTagContextMenu_separator {
margin-top: 0;
margin-bottom: 0;
border-bottom-style: none;
border-left-style: none;
border-right-style: none;
border-top-style: solid;
border-top-width: 1px;
border-color: #bbbbbb;
opacity: 0.4;
}
.mx_RoomTagContextMenu_fieldSet .mx_RoomTagContextMenu_icon {
/* Something to indicate that the icon is the set tag */
}
@@ -0,0 +1,24 @@
/*
Copyright 2016 Aviral Dasgupta
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_ChangelogDialog_content {
max-height: 300px;
overflow: auto;
}
.mx_ChangelogDialog_li {
padding: 0.2em;
}
@@ -0,0 +1,81 @@
/*
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_NetworkDropdown {
position: relative;
}
.mx_NetworkDropdown_input {
position: relative;
border-radius: 3px;
border: 1px solid #c7c7c7;
font-weight: 300;
font-size: 13px;
user-select: none;
}
.mx_NetworkDropdown_arrow {
border-color: #4a4a4a transparent transparent;
border-style: solid;
border-width: 5px 5px 0;
display: block;
height: 0;
position: absolute;
right: 10px;
top: 14px;
width: 0
}
.mx_NetworkDropdown_networkoption {
height: 35px;
line-height: 35px;
padding-left: 8px;
padding-right: 8px;
}
.mx_NetworkDropdown_networkoption img {
margin: 5px;
width: 25px;
vertical-align: middle;
}
input.mx_NetworkDropdown_networkoption, input.mx_NetworkDropdown_networkoption:focus {
border: 0;
padding-top: 0;
padding-bottom: 0;
}
.mx_NetworkDropdown_menu {
position: absolute;
left: -1px;
right: -1px;
top: 100%;
z-index: 2;
margin: 0;
padding: 0px;
border-radius: 3px;
border: 1px solid #76cfa6;
background-color: white;
}
.mx_NetworkDropdown_menu .mx_NetworkDropdown_networkoption:hover {
background-color: #ddd;
}
.mx_NetworkDropdown_menu_network {
font-weight: bold;
}
@@ -69,6 +69,7 @@ limitations under the License.
.mx_ImageView_labelWrapper {
position: absolute;
top: 0px;
right: 0px;
height: 100%;
overflow: auto;
pointer-events: all;
@@ -82,9 +83,10 @@ limitations under the License.
-webkit-justify-content: center;
flex-direction: column;
-webkit-flex-direction: column;
padding-left: 60px;
padding-right: 60px;
padding-left: 30px;
padding-right: 30px;
min-height: 100%;
max-width: 240px;
color: #fff;
}
@@ -99,6 +101,7 @@ limitations under the License.
.mx_ImageView_name {
font-size: 18px;
margin-bottom: 6px;
word-wrap: break-word;
}
.mx_ImageView_metadata {
@@ -33,6 +33,11 @@ limitations under the License.
margin-top: -2px;
}
.mx_MatrixToolbar_content {
-webkit-flex: 1;
flex: 1;
}
.mx_MatrixToolbar_link
{
color: #fff ! important;
@@ -41,10 +46,7 @@ limitations under the License.
}
.mx_MatrixToolbar_close {
-webkit-flex: 1;
flex: 1;
cursor: pointer;
text-align: right;
}
.mx_MatrixToolbar_close img {
@@ -52,3 +54,7 @@ limitations under the License.
float: right;
margin-right: 10px;
}
.mx_MatrixToolbar_action {
margin-right: 16px;
}
@@ -16,8 +16,10 @@ limitations under the License.
.mx_RoomDropTarget {
font-size: 13px;
margin-left: 10px;
margin-right: 15px;
margin-left: 18px;
margin-right: 18px;
margin-top: 8px;
margin-bottom: 7px;
padding-top: 5px;
padding-bottom: 5px;
border: 1px dashed #76cfa6;
@@ -28,6 +30,7 @@ limitations under the License.
.collapsed .mx_RoomDropTarget {
margin-right: 10px;
margin-left: 10px;
}
.mx_RoomDropTarget_placeholder {
@@ -14,19 +14,40 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_RoomTooltip_chevron {
position: absolute;
left: -8px;
top: 4px;
width: 0;
height: 0;
border-top: 8px solid transparent;
border-right: 8px solid rgba(187, 187, 187, 0.5);
border-bottom: 8px solid transparent;
}
.mx_RoomTooltip_chevron:after{
content:'';
width: 0;
height: 0;
border-top: 7px solid transparent;
border-right: 7px solid #fff;
border-bottom: 7px solid transparent;
position:absolute;
top: -7px;
left: 1px;
}
.mx_RoomTooltip {
display: none;
position: fixed;
border: 1px solid #a4a4a4;
border-radius: 8px;
border: 1px solid rgba(187, 187, 187, 0.5);
border-radius: 5px;
background-color: #fff;
z-index: 1000;
left: 64px;
padding: 6px;
z-index: 2000;
padding: 5px;
pointer-events: none;
line-height: 14px;
font-size: 13px;
color: rgba(0, 0, 0, 0.7);
}
.mx_RoomTooltip_chevron {
position: absolute;
left: -9px;
top: 8px;
}
@@ -21,20 +21,20 @@ limitations under the License.
.mx_UserNotifSettings_inputCell {
display: table-cell;
padding-bottom: 21px;
padding-bottom: 8px;
padding-right: 8px;
width: 16px;
}
.mx_UserNotifSettings_labelCell
{
padding-bottom: 21px;
padding-bottom: 8px;
width: 400px;
display: table-cell;
}
.mx_UserNotifSettings_pushRulesTableWrapper {
padding-bottom: 21px;
padding-bottom: 8px;
}
.mx_UserNotifSettings_pushRulesTable {
@@ -60,3 +60,11 @@ limitations under the License.
cursor: pointer;
color: #76cfa6;
}
.mx_UserSettings_devicesTable td {
padding-left: 20px;
padding-right: 20px;
}
.mx_UserSettings_devicesTable_nodevices {
font-style: italic;
}

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