Compare commits

..

70 Commits

Author SHA1 Message Date
David Baker
22060ac5a4 v0.9.6 2017-01-16 13:26:22 +00:00
David Baker
3f3a31e475 Prepare changelog for v0.9.6 2017-01-16 13:26:21 +00:00
David Baker
231306ea7c Update js-sdk & react-sdk 2017-01-16 13:24:44 +00:00
David Baker
e1c1937855 v0.9.6-rc.1 2017-01-13 11:21:08 +00:00
David Baker
9471c30f89 Prepare changelog for v0.9.6-rc.1 2017-01-13 11:21:08 +00:00
David Baker
40545bd48e Released react-sdk & js-sdk 2017-01-13 11:15:55 +00:00
David Baker
6b02bf8e8c Merge pull request #2920 from vector-im/dbkr/ci_build_js_sdk
Build the js-sdk in the CI script
2017-01-12 17:37:18 +00:00
David Baker
0d05e607f0 install js-sdk in travis too 2017-01-12 17:24:28 +00:00
David Baker
717aa94ba9 Merge pull request #2917 from vector-im/dbkr/fix_windows_shortcuts
Hopefully fix Windows shortcuts
2017-01-12 10:43:26 +00:00
David Baker
9caba57c14 Merge pull request #2921 from vector-im/dbkr/update_readme_for_js_sdk_transpiled
Update README now the js-sdk has a transpile step
2017-01-12 10:05:55 +00:00
David Baker
70f48343ee It's now just build 2017-01-11 19:03:52 +00:00
David Baker
f17f103d12 s/build/compile/ for js sdk 2017-01-11 18:19:44 +00:00
David Baker
27e311f7e8 Address PR comments 2017-01-11 18:15:06 +00:00
David Baker
5258bf9c84 Update README now the js-sdk has a transpile step 2017-01-11 17:25:58 +00:00
David Baker
10f0631487 Build the js-sdk in the CI script
now it's transpiled
2017-01-11 17:20:27 +00:00
David Baker
97fc92b1bb Update to electron 1.4.14
This pulls in the chrome change that broke geotrust ssl when the
build hit 10 weeks old, so let's get this one out before we hit
more disasters.
2017-01-11 16:53:01 +00:00
David Baker
06718c580e Hopefully fix Windows shortcuts
* Revert 79d164309f
   as it seems to break shortcuts altogether
 * Update electron-builder (and add the squirrel windows package
   that the newer version now requires: it's been split out). This
   uses a newer version of squirrel which has some fixes for
   shortcuts.

I'm unsure exactly what was going wrong originally in
https://github.com/vector-im/riot-web/issues/2775 but #79d1643
seems to break shortcut creation as far as I can see.
2017-01-11 16:27:40 +00:00
David Baker
15528ef8d7 Merge pull request #2915 from vector-im/dbkr/use_dev_tools_role
Use the role for 'toggle dev tools'
2017-01-11 14:50:15 +00:00
David Baker
b71f96e4e5 Use the role for 'toggle dev tools'
Let electron handle it rather than doing it ourselves
2017-01-11 10:28:04 +00:00
David Baker
278de1398b Merge pull request #2909 from vector-im/dbkr/enable_screen_sharing
Enable screen sharing easter-egg in desktop app
2017-01-11 10:12:57 +00:00
David Baker
c5459a2f19 Enable screen sharing easter-egg in desktop app 2017-01-10 18:39:21 +00:00
Richard van der Hoff
6a1af891b7 Use a custom script to copy resources (#2893)
All of those cpx invocations were getting unwieldy, and I suspect the exotic
quoting needed to run them under parallelshell was breaking things on windows.

Replace the unwieldy cpx invocations with an unwieldy custom script.
2017-01-06 10:43:13 +00:00
Matthew Hodgson
b0319ec0f1 merge 2016-12-24 19:32:29 +00:00
Matthew Hodgson
b06d045188 Merge pull request #2808 from vector-im/matthew/electron-captcha2
make electron send email validation URLs with a nextlink of riot.im
2016-12-24 18:38:29 +00:00
Matthew Hodgson
79d164309f empirically fix win32 shortcut in start menu 2016-12-24 18:13:33 +00:00
Matthew Hodgson
f2afcc0bc8 add gnu-tar to debian electron build deps 2016-12-24 18:13:20 +00:00
Matthew Hodgson
43f82cd95d Merge pull request #2809 from k3vmcd/master
add Debian Stretch install steps to readme
2016-12-24 16:47:20 +00:00
Kevin McDonald
2b70cb436e add Debian Stretch install steps to readme 2016-12-23 22:32:16 -07:00
Matthew Hodgson
9a861f46d0 make electron send email validation URLs with a nextlink of riot.im rather than file:/// 2016-12-24 03:18:12 +00:00
Matthew Hodgson
bb28903c8e fix warning page 2016-12-24 01:36:00 +00:00
Matthew Hodgson
e8eadc5d20 Merge pull request #2793 from joelostblom/patch-1
Update desktop build instructions fixes #2792
2016-12-22 20:42:01 +00:00
joelostblom
e741a4f294 Update desktop build instructions fixes #2792
This is based on what I had to do to get the desktop app running, as per the advice in https://github.com/vector-im/riot-web/issues/2792. I am not familiar with `npm`, so please change this pull request if there is a more appropriate way of achieving the same result.
2016-12-22 14:53:03 -05:00
Richard van der Hoff
1678a25fd6 Merge branch 'master' into develop 2016-12-22 18:33:37 +00:00
Richard van der Hoff
ff70b0a2c8 v0.9.4 2016-12-22 18:24:04 +00:00
Richard van der Hoff
3803c64226 prep 0.9.4 changelog 2016-12-22 18:15:00 +00:00
Richard van der Hoff
35a541c824 Bump to olm 2.1.0 2016-12-22 17:23:27 +00:00
Richard van der Hoff
ab8420f5a9 Bump to olm 2.1.0 2016-12-22 16:30:14 +00:00
David Baker
fa46757830 Merge pull request #2784 from vector-im/dbkr/delete_threepid
CSS for the delete threepid button
2016-12-22 15:31:38 +00:00
David Baker
ed35a90cfb Back to develop js & react sdk 2016-12-22 14:36:05 +00:00
David Baker
d8bce0f202 v0.9.3 2016-12-22 14:18:23 +00:00
David Baker
e6f600bb47 Prepare changelog for v0.9.3 2016-12-22 14:18:22 +00:00
David Baker
519af6a5d0 Bump to matrix-react-sdk 0.8.3 2016-12-22 14:14:44 +00:00
Richard van der Hoff
c6c4aff8ae Redeploy script: put each build in a separate directory (#2790)
* Redeploy script: put each build in a separate directory

Hopefully this will fix the problem whereby we can overwrite the live
deployment.
2016-12-22 12:02:54 +00:00
Matthew Hodgson
6d4abac016 Merge pull request #2755 from Mikaela/readme-nativefier
README.md: fix GFMD for nativefier
2016-12-22 02:37:17 +00:00
David Baker
d34cb80b68 CSS for the delete threepid button 2016-12-21 18:50:35 +00:00
Matthew Hodgson
57641f7228 typo 2016-12-20 00:05:49 +00:00
Mikaela Suomalainen
9ae86f2585 README.md: fix GFMD for nativefier
GitHub Flavoured MarkDown parsed this as
`sudo npm install nativefier -g nativefier https://riot.im/app/` which
is incorrect.
2016-12-17 21:17:58 +02:00
David Baker
1e7e9d6101 v0.9.2 2016-12-16 17:44:22 +00:00
David Baker
8bbc16ed4b Prepare changelog for v0.9.2 2016-12-16 17:44:22 +00:00
David Baker
4745b3efeb released js-sdk & react-sdk 2016-12-16 17:40:37 +00:00
David Baker
09f79b94dd Merge pull request #2750 from vector-im/dbkr/roomdir_remove_client_filter
Remove the client side filtering from the room dir
2016-12-16 16:44:05 +00:00
David Baker
42357dee0b Typo 2016-12-16 16:36:24 +00:00
David Baker
2e73cd6c4d PR feedback 2016-12-16 16:24:24 +00:00
David Baker
161978ab05 Fix tests 2016-12-16 15:20:52 +00:00
David Baker
994bc9279f Remove the client side filtering from the room dir
This removes the ability for the client to filter remote room
directories by network, since the /thirdparty/protocols API does
not yet work for remote servers. They would only get the main list
now though anyway, so there is no point in us continuing to support
it.
2016-12-16 14:17:13 +00:00
David Baker
fb08910db3 Read the icon from the right place
Also don't define image widths in the HTML as it's done in the CSS.
2016-12-16 10:14:38 +00:00
Richard van der Hoff
e607f49ae6 Merge pull request #2745 from vector-im/rav/set_olm_heap_size
Configure olm memory size
2016-12-15 17:19:04 +00:00
David Baker
52cf1f6a4b Missed a wire_onclick 2016-12-15 16:36:14 +00:00
Richard van der Hoff
61f9966fe0 Merge pull request #2747 from vector-im/dbkr/third_party_filter
Support room dir 3rd party network filtering
2016-12-15 16:21:28 +00:00
David Baker
5f7cdb8d42 s/wire_onclick/handleClicks/
and actually pass handleClicks false as appropriate
2016-12-15 14:29:16 +00:00
David Baker
901c0e7e41 Remove unused event params 2016-12-15 14:24:55 +00:00
David Baker
98cad8779c Add instance_id to initial state 2016-12-15 10:42:11 +00:00
David Baker
fc597ba86e Underscore for private method 2016-12-15 10:41:22 +00:00
David Baker
f5bd8abfda Support room dir 3rd party network filtering
As per https://github.com/matrix-org/synapse/pull/1676

The existing local config system still exists and is used for
remote home server directories (since /thirdparty/protocols
doesn't support listing remote home servers, and also because
people are using it).
2016-12-14 15:41:15 +00:00
Richard van der Hoff
8be72e6c27 Configure olm memory size
16M is somewhat excessive: configure olm to use a bit less.

Requires changes to the olm library to do anything useful, but will be harmless
without them.

Partial fix to vector-im/riot-web#2726.
2016-12-14 11:59:37 +00:00
David Baker
2740013625 RELEASES is for update, not install 2016-12-13 10:24:32 +00:00
David Baker
119e03b64f Get the update base URL right
and update the text in the README.
2016-12-12 17:24:22 +00:00
David Baker
c6dbeee245 ico needs to be at least 256x256 2016-12-09 22:33:20 +00:00
David Baker
feb3a13a71 Get version after we've checked out... 2016-12-09 20:23:19 +00:00
David Baker
c80d1c15d2 dev js-sdk & react-sdk 2016-12-09 20:12:37 +00:00
27 changed files with 461 additions and 346 deletions

View File

@@ -3,4 +3,5 @@ node_js:
- 6 # node v6, to match jenkins
install:
- npm install
- (cd node_modules/matrix-js-sdk && npm install)
- (cd node_modules/matrix-react-sdk && npm run build)

View File

@@ -1,3 +1,67 @@
Changes in [0.9.6](https://github.com/vector-im/riot-web/releases/tag/v0.9.6) (2017-01-16)
==========================================================================================
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.6-rc.1...v0.9.6)
* Update to matrix-js-sdk 0.9.6 for video calling fix
Changes in [0.9.6-rc.1](https://github.com/vector-im/riot-web/releases/tag/v0.9.6-rc.1) (2017-01-13)
====================================================================================================
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.5...v0.9.6-rc.1)
* Build the js-sdk in the CI script
[\#2920](https://github.com/vector-im/riot-web/pull/2920)
* Hopefully fix Windows shortcuts
[\#2917](https://github.com/vector-im/riot-web/pull/2917)
* Update README now the js-sdk has a transpile step
[\#2921](https://github.com/vector-im/riot-web/pull/2921)
* Use the role for 'toggle dev tools'
[\#2915](https://github.com/vector-im/riot-web/pull/2915)
* Enable screen sharing easter-egg in desktop app
[\#2909](https://github.com/vector-im/riot-web/pull/2909)
* make electron send email validation URLs with a nextlink of riot.im
[\#2808](https://github.com/vector-im/riot-web/pull/2808)
* add Debian Stretch install steps to readme
[\#2809](https://github.com/vector-im/riot-web/pull/2809)
* Update desktop build instructions fixes #2792
[\#2793](https://github.com/vector-im/riot-web/pull/2793)
* CSS for the delete threepid button
[\#2784](https://github.com/vector-im/riot-web/pull/2784)
Changes in [0.9.5](https://github.com/vector-im/riot-web/releases/tag/v0.9.5) (2016-12-24)
==========================================================================================
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.4...v0.9.5)
* make electron send email validation URLs with a nextlink of riot.im rather than file:///
* add gnu-tar to debian electron build deps
* fix win32 shortcut in start menu
Changes in [0.9.4](https://github.com/vector-im/riot-web/releases/tag/v0.9.4) (2016-12-22)
==========================================================================================
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.3...v0.9.4)
* Update to libolm 2.1.0. This should help resolve a problem with browser
sessions being logged out ([\#2726](https://github.com/vector-im/riot-web/issues/2726)).
Changes in [0.9.3](https://github.com/vector-im/riot-web/releases/tag/v0.9.3) (2016-12-22)
==========================================================================================
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.2...v0.9.3)
* (from matrix-react-sdk) Fix regression where the date separator would be displayed
at the wrong time of day.
* README.md: fix GFMD for nativefier
[\#2755](https://github.com/vector-im/riot-web/pull/2755)
Changes in [0.9.2](https://github.com/vector-im/riot-web/releases/tag/v0.9.2) (2016-12-16)
==========================================================================================
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.1...v0.9.2)
* Remove the client side filtering from the room dir
[\#2750](https://github.com/vector-im/riot-web/pull/2750)
* Configure olm memory size
[\#2745](https://github.com/vector-im/riot-web/pull/2745)
* Support room dir 3rd party network filtering
[\#2747](https://github.com/vector-im/riot-web/pull/2747)
Changes in [0.9.1](https://github.com/vector-im/riot-web/releases/tag/v0.9.1) (2016-12-09)
==========================================================================================
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.1-rc.2...v0.9.1)
@@ -98,7 +162,7 @@ Changes in [0.9.0](https://github.com/vector-im/vector-web/releases/tag/v0.9.0)
* Implement Platforms
[\#2531](https://github.com/vector-im/vector-web/pull/2531)
hanges in [0.8.4](https://github.com/vector-im/vector-web/releases/tag/v0.8.4) (2016-11-04)
Changes in [0.8.4](https://github.com/vector-im/vector-web/releases/tag/v0.8.4) (2016-11-04)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.8.4-rc.2...v0.8.4)

View File

@@ -25,6 +25,14 @@ Note that Chrome does not allow microphone or webcam access for sites served
over http (except localhost), so for working VoIP you will need to serve Riot
over https.
### Installation Steps for Debian Stretch
1. Add the repository to your sources.list using either of the following two options:
- Directly to sources.list: `echo "deb https://riot.im/packages/debian/ stretch main" | sudo tee -a /etc/apt/sources.list`
- As a separate entry in sources.list.d: `echo "deb https://riot.im/packages/debian/ stretch main" | sudo tee /etc/apt/sources.list.d/riot.list`
2. Add the gpg signing key for the riot repository: `curl -s https://riot.im/packages/debian/repo-key.asc | sudo apt-key add -`
3. Update your package lists: `sudo apt-get update`
4. Install Riot: `sudo apt-get install riot-web`
Important Security Note
=======================
@@ -49,9 +57,13 @@ to build.
1. Switch to the vector-web directory: `cd vector-web`
1. Install the prerequisites: `npm install`
1. If you are using the `develop` branch of vector-web, 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)`
to rebuild some of the dependencies, due to
https://github.com/npm/npm/issues/3055:
```
(cd node_modules/matrix-js-sdk && npm install)
(cd node_modules/matrix-react-sdk && npm install)
```
1. Configure the app by copying `config.sample.json` to `config.json` and
modifying it (see below for details)
1. `npm run dist` to build a tarball to deploy. Untaring this file will give
@@ -81,35 +93,12 @@ You can configure the app by copying `config.sample.json` to
and https://vector.im. In future identity servers will be decentralised.
1. `integrations_ui_url`: URL to the web interface for the integrations server.
1. `integrations_rest_url`: URL to the REST interface for the integrations server.
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`: config for the public room directory. 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.
1. `update_base_url` (electron app only): HTTPS URL to a web server to download
updates from. This should be the path to the directory containing `install`
and `update`.
updates from. This should be the path to the directory containing `macos`
and `win32` (for update packages, not installer packages).
1. `cross_origin_renderer_url`: URL to a static HTML page hosting code to help display
encrypted file attachments. This MUST be hosted on a completely separate domain to
anything else since it is used to isolate the privileges of file attachments to this
@@ -127,6 +116,7 @@ To run as a desktop app:
```
npm install
npm install electron
npm run build
node_modules/.bin/electron .
```
@@ -144,6 +134,7 @@ The only platform that can build packages for all three platforms is macOS:
```
brew install wine --without-x11
brew install mono
brew install gnu-tar
npm install
npm run build:electron
```
@@ -163,10 +154,11 @@ Many thanks to @aviraldg for the initial work on the electron integration.
Other options for running as a desktop app:
* https://github.com/krisak/vector-electron-desktop
* @asdf:matrix.org points out that you can use nativefier and it just works(tm)
```
sudo npm install nativefier -g
nativefier https://riot.im/app/
```
```
sudo npm install nativefier -g
nativefier https://riot.im/app/
```
Development
===========
@@ -253,10 +245,10 @@ Finally, build and start Riot itself:
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 Riot.
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.
When you make changes to `matrix-react-sdk` or `matrix-js-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 Riot skin, you will need to rebuild
the skin's index by running, `npm run reskindex`.

View File

@@ -8,64 +8,6 @@
"roomDirectory": {
"servers": [
"matrix.org"
],
"serverConfig": {
"matrix.org": {
"networks": [
"_matrix",
"gitter",
"irc:freenode",
"irc:mozilla",
"irc:snoonet",
"irc:oftc"
]
}
},
"networks": {
"gitter": {
"protocol": "gitter",
"portalRoomPattern": "#gitter_.*:matrix.org",
"name": "Gitter",
"icon": "//gitter.im/favicon.ico",
"example": "org/community",
"nativePattern": "[^\\s]+/[^\\s]+$"
},
"irc:freenode": {
"protocol": "irc",
"domain": "chat.freenode.net",
"portalRoomPattern": "#freenode_.*:matrix.org",
"name": "Freenode",
"icon": "//matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX",
"example": "#channel",
"nativePattern": "^#[^\\s]+$"
},
"irc:mozilla": {
"protocol": "irc",
"domain": "irc.mozilla.org",
"portalRoomPattern": "#mozilla_.*:matrix.org",
"name": "Mozilla",
"icon": "//matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX",
"example": "#channel",
"nativePattern": "^#[^\\s]+$"
},
"irc:snoonet": {
"protocol": "irc",
"domain": "ipv6-irc.snoonet.org",
"portalRoomPattern": "#_snoonet_.*:matrix.org",
"name": "Snoonet",
"icon": "//matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX",
"example": "#channel",
"nativePattern": "^#[^\\s]+$"
},
"irc:oftc": {
"protocol": "irc",
"domain": "irc.oftc.net",
"portalRoomPattern": "#_oftc_.*:matrix.org",
"name": "OFTC",
"icon": "//matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX",
"example": "#channel",
"nativePattern": "^#[^\\s]+$"
}
}
]
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1,5 +1,5 @@
{
"update_base_url": "https://riot.im/download/desktop/",
"update_base_url": "https://riot.im/download/desktop/update/",
"default_hs_url": "https://matrix.org",
"default_is_url": "https://vector.im",
"brand": "Riot",

View File

@@ -148,6 +148,8 @@ process.on('uncaughtException', function (error) {
electron.ipcMain.on('install_update', installUpdate);
electron.app.commandLine.appendSwitch('--enable-usermedia-screen-capturing');
electron.app.on('ready', () => {
if (vectorConfig.update_base_url) {
console.log("Starting auto update with base URL: " + vectorConfig.update_base_url);

View File

@@ -3,7 +3,12 @@ const spawn = require('child_process').spawn;
const app = require('electron').app;
function run_update_exe(args, done) {
// Invokes Squirrel's Update.exe which will do things for us like create shortcuts
// Note that there's an Update.exe in the app-x.x.x directory and one in the parent
// directory: we need to run the one in the parent directory, because it discovers
// information about the app by inspecting the directory it's run from.
const updateExe = path.resolve(path.dirname(process.execPath), '..', 'Update.exe');
console.log('Spawning `%s` with args `%s`', updateExe, args);
spawn(updateExe, args, {
detached: true
}).on('close', done);

View File

@@ -72,11 +72,7 @@ const template = [
role: 'togglefullscreen'
},
{
label: 'Toggle Developer Tools',
accelerator: process.platform == 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I',
click: function(item, focusedWindow) {
if (focusedWindow) focusedWindow.toggleDevTools();
}
role: 'toggledevtools'
}
]
},

View File

@@ -2,7 +2,7 @@
"name": "riot-web",
"productName": "Riot",
"main": "electron/src/electron-main.js",
"version": "0.9.1",
"version": "0.9.6",
"description": "A feature-rich client for Matrix.org",
"author": "Vector Creations Ltd.",
"repository": {
@@ -27,26 +27,22 @@
"matrix-react-parent": "matrix-react-sdk",
"scripts": {
"reskindex": "reskindex -h src/header",
"build:res": "cpx \"{src/skins/vector/fonts,src/skins/vector/img}/**\" webapp/ && cpx \"{res/media,res/vector-icons}/**\" webapp/",
"build:config": "cpx config.json webapp/",
"build:emojione": "cpx \"node_modules/emojione/assets/svg/*\" webapp/emojione/svg/",
"build:res": "node scripts/copy-res.js",
"build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js",
"build:css": "mkdirp build && catw \"src/skins/vector/css/**/*.css\" -o build/components.css --no-watch",
"build:compile": "babel --source-maps -d lib src",
"build:bundle": "NODE_ENV=production webpack -p --progress",
"build:bundle:dev": "webpack --optimize-occurence-order --progress",
"build:electron": "npm run clean && npm run build && build -wml --ia32 --x64",
"build": "node scripts/babelcheck.js && npm run build:res && npm run build:config && npm run build:emojione && npm run build:css && npm run build:bundle",
"build:dev": "node scripts/babelcheck.js && npm run build:res && npm run build:config && npm run build:emojione && npm run build:css && npm run build:bundle:dev",
"build": "node scripts/babelcheck.js && npm run build:res && npm run build:css && npm run build:bundle",
"build:dev": "node scripts/babelcheck.js && npm run build:res && npm run build:css && npm run build:bundle:dev",
"dist": "scripts/package.sh",
"start:res": "parallelshell \"cpx -w \\\"{src/skins/vector/fonts,src/skins/vector/img}/**\\\" webapp/\" \"cpx -w \\\"{res/media,res/vector-icons}/**\\\" webapp/\"",
"start:config": "cpx -w config.json webapp/",
"start:emojione": "cpx \"node_modules/emojione/assets/svg/*\" webapp/emojione/svg/ -w",
"start:res": "node scripts/copy-res.js -w",
"start:js": "webpack-dev-server -w --progress",
"start:js:prod": "NODE_ENV=production webpack-dev-server -w --progress",
"start:skins:css": "mkdirp build && catw \"src/skins/vector/css/**/*.css\" -o build/components.css",
"start": "node scripts/babelcheck.js && parallelshell \"npm run start:emojione\" \"npm run start:res\" \"npm run start:config\" \"npm run start:js\" \"npm run start:skins:css\"",
"start:prod": "parallelshell \"npm run start:emojione\" \"npm run start:js:prod\" \"npm run start:skins:css\"",
"start:css": "mkdirp build && catw \"src/skins/vector/css/**/*.css\" -o build/components.css",
"start": "node scripts/babelcheck.js && parallelshell \"npm run start:res\" \"npm run start:js\" \"npm run start:css\"",
"start:prod": "parallelshell \"npm run start:res\" \"npm run start:js:prod\" \"npm run start:css\"",
"clean": "rimraf build lib webapp electron/dist",
"prepublish": "npm run build:compile",
"test": "karma start --single-run=true --autoWatch=false --browsers PhantomJS --colors=false",
@@ -66,8 +62,8 @@
"gfm.css": "^1.1.1",
"highlight.js": "^9.0.0",
"linkifyjs": "^2.1.3",
"matrix-js-sdk": "0.7.1",
"matrix-react-sdk": "0.8.1",
"matrix-js-sdk": "0.7.4",
"matrix-react-sdk": "0.8.5",
"modernizr": "^3.1.0",
"q": "^1.4.1",
"react": "^15.4.0",
@@ -95,9 +91,11 @@
"babel-preset-react": "^6.16.0",
"babel-preset-stage-2": "^6.17.0",
"catw": "^1.0.1",
"chokidar": "^1.6.1",
"cpx": "^1.3.2",
"css-raw-loader": "^0.1.1",
"electron-builder": "^10.4.1",
"electron-builder": "^11.2.4",
"electron-builder-squirrel-windows": "^11.2.1",
"emojione": "^2.2.3",
"expect": "^1.16.0",
"fs-extra": "^0.30.0",
@@ -111,6 +109,7 @@
"karma-phantomjs-launcher": "^1.0.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^1.7.0",
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"mocha": "^2.4.5",
"parallelshell": "^1.2.0",
@@ -123,12 +122,12 @@
"webpack-dev-server": "^1.16.2"
},
"optionalDependencies": {
"olm": "https://matrix.org/packages/npm/olm/olm-2.0.0.tgz"
"olm": "https://matrix.org/packages/npm/olm/olm-2.1.0.tgz"
},
"build": {
"appId": "im.riot.app",
"category": "Network",
"electronVersion": "1.4.11",
"electronVersion": "1.4.14",
"//asar=false": "https://github.com/electron-userland/electron-builder/issues/675",
"asar": false,
"dereference": true,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 102 KiB

81
scripts/copy-res.js Executable file
View File

@@ -0,0 +1,81 @@
#!/usr/bin/env node
// copies the resources into the webapp directory.
//
// cpx includes globbed parts of the filename in the destination, but excludes
// common parents. Hence, "res/{a,b}/**": the output will be "dest/a/..." and
// "dest/b/...".
const COPY_LIST = [
["res/{media,vector-icons}/**", "webapp"],
["src/skins/vector/{fonts,img}/**", "webapp"],
["node_modules/emojione/assets/svg/*", "webapp/emojione/svg/"],
["./config.json", "webapp", {directwatch: 1}],
];
const parseArgs = require('minimist');
const Cpx = require('cpx');
const chokidar = require('chokidar');
const argv = parseArgs(
process.argv.slice(2), {}
);
var watch = argv.w;
var verbose = argv.v;
function errCheck(err) {
if (err) {
console.error(err.message);
process.exit(1);
}
}
function next(i, err) {
errCheck(err);
if (i >= COPY_LIST.length) {
return;
}
const ent = COPY_LIST[i];
const source = ent[0];
const dest = ent[1];
const opts = ent[2] || {};
const cpx = new Cpx.Cpx(source, dest);
if (verbose) {
cpx.on("copy", (event) => {
console.log(`Copied: ${event.srcPath} --> ${event.dstPath}`);
});
cpx.on("remove", (event) => {
console.log(`Removed: ${event.path}`);
});
}
const cb = (err) => {next(i+1, err)};
if (watch) {
if (opts.directwatch) {
// cpx -w creates a watcher for the parent of any files specified,
// which in the case of config.json is '.', which inevitably takes
// ages to crawl. So we create our own watcher on the files
// instead.
const copy = () => {cpx.copy(errCheck)};
chokidar.watch(source)
.on('add', copy)
.on('change', copy)
.on('ready', cb)
.on('error', errCheck);
} else {
cpx.on('watch-ready', cb);
cpx.on("watch-error", cb);
cpx.watch();
}
} else {
cpx.copy(cb);
}
}
next(0);

View File

@@ -73,12 +73,12 @@ projdir=`pwd`
builddir=`mktemp -d 2>/dev/null || mktemp -d -t 'buildtmp'`
pushd "$builddir"
# Figure out what version we're building
vername=`jq -r .version package.json`
git clone "$projdir" .
git checkout "$version"
# Figure out what version we're building
vername=`jq -r .version package.json`
if [ -n "$conffile" ]; then
popd
cp "$conffile" "$builddir/"
@@ -113,7 +113,7 @@ echo "$vername" > "$pubdir/update/macos/latest"
mkdir -p "$pubdir/update/win32/ia32/"
cp $distdir/win-ia32/*.nupkg "$pubdir/update/win32/ia32/"
cp $distdir/win-ia32/RELEASES "$pubdir/install/win32/ia32/"
cp $distdir/win-ia32/RELEASES "$pubdir/update/win32/ia32/"
mkdir -p "$pubdir/update/win32/x64/"
cp $distdir/win/*.nupkg "$pubdir/update/win32/x64/"

View File

@@ -19,7 +19,8 @@ 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
# we may be using dev branches of js-sdk and react-sdk, in which case we need to build them
(cd node_modules/matrix-js-sdk && npm run build)
(cd node_modules/matrix-react-sdk && npm run build)
# run the mocha tests

View File

@@ -80,7 +80,7 @@ cp "$tmpdir/150.png" "res/vector-icons/mstile-150x150.png"
cp "$tmpdir/310.png" "res/vector-icons/mstile-310x310.png"
cp "$tmpdir/310x150.png" "res/vector-icons/mstile-310x150.png"
convert "$tmpdir/16.png" "$tmpdir/32.png" "$tmpdir/64.png" "$tmpdir/128.png" "res/vector-icons/favicon.ico"
convert "$tmpdir/16.png" "$tmpdir/32.png" "$tmpdir/64.png" "$tmpdir/128.png" "$tmpdir/256.png" "res/vector-icons/favicon.ico"
cp "res/vector-icons/favicon.ico" "electron/build/icon.ico"

View File

@@ -13,7 +13,7 @@ def download_file(url):
local_filename = url.split('/')[-1]
r = requests.get(url, stream=True)
with open(local_filename, 'wb') as f:
for chunk in r.iter_content(chunk_size=1024):
for chunk in r.iter_content(chunk_size=1024):
if chunk: # filter out keep-alive new chunks
f.write(chunk)
return local_filename
@@ -107,21 +107,40 @@ def on_receive_jenkins_poke():
)
print("Retrieving .tar.gz file: %s" % tar_gz_url)
# we rely on the fact that flask only serves one request at a time to
# ensure that we do not overwrite a tarball from a concurrent request.
filename = download_file(tar_gz_url)
print("Downloaded file: %s" % filename)
try:
# we extract into a directory based on the build number. This avoids the
# problem of multiple builds building the same git version and thus having
# the same tarball name. That would lead to two potential problems:
# (a) sometimes jenkins serves corrupted artifacts; we would replace
# a good deploy with a bad one
# (b) we'll be overwriting the live deployment, which means people might
# see half-written files.
build_dir = os.path.join(arg_extract_path, "%s-#%s" % (job_name, build_num))
if os.path.exists(build_dir):
abort(400, "Not deploying. We have previously deployed this build.")
return
os.mkdir(build_dir)
untar_to(filename, build_dir)
print("Extracted to: %s" % build_dir)
finally:
if arg_should_clean:
os.remove(filename)
name_str = filename.replace(".tar.gz", "")
untar_to(filename, arg_extract_path)
extracted_dir = os.path.join(arg_extract_path, name_str)
if arg_should_clean:
os.remove(filename)
create_symlink(source=extracted_dir, linkname=arg_symlink)
extracted_dir = os.path.join(build_dir, name_str)
if arg_config_location:
create_symlink(source=arg_config_location, linkname=os.path.join(extracted_dir, 'config.json'))
create_symlink(source=extracted_dir, linkname=arg_symlink)
return jsonify({})
if __name__ == "__main__":

View File

@@ -45,10 +45,8 @@ module.exports = React.createClass({
available or experimental in your current browser.
</p>
<p>
Please install <a href="https://www.google.com/chrome">Chrome</a> 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.
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>
<p>
With your current browser, the look and feel of the application may

View File

@@ -31,6 +31,8 @@ var linkifyMatrix = require('matrix-react-sdk/lib/linkify-matrix');
var sanitizeHtml = require('sanitize-html');
var q = require('q');
import {instanceForInstanceId, protocolNameForInstanceId} from '../../utils/DirectoryUtils';
linkifyMatrix(linkify);
module.exports = React.createClass({
@@ -42,9 +44,7 @@ module.exports = React.createClass({
getDefaultProps: function() {
return {
config: {
networks: [],
},
config: {},
}
},
@@ -52,36 +52,26 @@ module.exports = React.createClass({
return {
publicRooms: [],
loading: true,
network: null,
protocolsLoading: true,
instanceId: null,
includeAll: false,
roomServer: null,
filterString: null,
}
},
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);
}
}
}
this.nextBatch = null;
this.filterTimeout = null;
this.scrollPanel = null;
this.protocols = null;
this.setState({protocolsLoading: true});
MatrixClientPeg.get().getThirdpartyProtocols().done((response) => {
this.protocols = response;
this.setState({protocolsLoading: false});
}, (err) => {
this.setState({protocolsLoading: false});
if (MatrixClientPeg.get().isGuest()) {
// Guests currently aren't allowed to use this API, so
// ignore this as otherwise this error is literally the
@@ -131,6 +121,11 @@ module.exports = React.createClass({
if (my_server != MatrixClientPeg.getHomeServerName()) {
opts.server = my_server;
}
if (this.state.instanceId) {
opts.third_party_instance_id = this.state.instanceId;
} else if (this.state.includeAll) {
opts.include_all_networks = true;
}
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) => {
@@ -231,7 +226,7 @@ module.exports = React.createClass({
}
},
onOptionChange: function(server, network) {
onOptionChange: function(server, instanceId, includeAll) {
// clear next batch so we don't try to load more rooms
this.nextBatch = null;
this.setState({
@@ -240,7 +235,8 @@ module.exports = React.createClass({
// to clear the list anyway.
publicRooms: [],
roomServer: server,
network: network,
instanceId: instanceId,
includeAll: includeAll,
}, this.refreshRoomList);
// We also refresh the room list each time even though this
// filtering is client-side. It hopefully won't be client side
@@ -271,7 +267,7 @@ module.exports = React.createClass({
this.filterTimeout = setTimeout(() => {
this.filterTimeout = null;
this.refreshRoomList();
}, 300);
}, 700);
},
onFilterClear: function() {
@@ -286,14 +282,19 @@ module.exports = React.createClass({
},
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') {
// If we don't have a particular instance id selected, just show that rooms alias
if (!this.state.instanceId) {
// If the user specified an alias without a domain, add on whichever server is selected
// in the dropdown
if (alias.indexOf(':') == -1) {
alias = alias + ':' + this.state.roomServer;
}
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);
// This is a 3rd party protocol. Let's see if we can join it
const protocolName = protocolNameForInstanceId(this.protocols, this.state.instanceId);
const instance = instanceForInstanceId(this.protocols, this.state.instanceId);
const fields = protocolName ? this._getFieldsForThirdPartyLocation(alias, this.protocols[protocolName], instance) : null;
if (!fields) {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
@@ -302,8 +303,7 @@ module.exports = React.createClass({
});
return;
}
const protocol = this._protocolForThirdPartyNetwork(this.state.network);
MatrixClientPeg.get().getThirdpartyLocation(protocol, fields).done((resp) => {
MatrixClientPeg.get().getThirdpartyLocation(protocolName, fields).done((resp) => {
if (resp.length > 0 && resp[0].alias) {
this.showRoomAlias(resp[0].alias);
} else {
@@ -372,13 +372,7 @@ module.exports = React.createClass({
if (!this.state.publicRooms) return [];
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 rooms = this.state.publicRooms;
var rows = [];
var self = this;
var guestRead, guestJoin, perms;
@@ -440,119 +434,46 @@ module.exports = React.createClass({
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) {
_stringLooksLikeId: function(s, field_type) {
let pat = /^#[^\s]+:[^\s]/;
if (
network && network != '_matrix' &&
this.nativePatterns[network]
) {
pat = this.nativePatterns[network];
if (field_type && field_type.regexp) {
pat = new RegExp(field_type.regexp);
}
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;
}
},
_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;
}
}
}
if (matched_instance === undefined) return null;
// now make an object with the fields specified by that protocol. We
_getFieldsForThirdPartyLocation: function(userInput, protocol, instance) {
// 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 requiredFields = protocol.location_fields;
if (!requiredFields) return null;
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];
for (let i = 0; i < requiredFields.length - 1; ++i) {
const thisField = requiredFields[i];
if (instance.fields[thisField] === undefined) return null;
fields[thisField] = instance.fields[thisField];
}
fields[required_fields[required_fields.length - 1]] = user_input;
fields[requiredFields[requiredFields.length - 1]] = userInput;
return fields;
},
render: function() {
const SimpleRoomHeader = sdk.getComponent('rooms.SimpleRoomHeader');
const Loader = sdk.getComponent("elements.Spinner");
if (this.state.protocolsLoading) {
return (
<div className="mx_RoomDirectory">
<SimpleRoomHeader title="Directory" />
<Loader />
</div>
);
}
let content;
if (this.state.loading) {
const Loader = sdk.getComponent("elements.Spinner");
content = <div className="mx_RoomDirectory">
<Loader />
</div>;
@@ -583,26 +504,35 @@ module.exports = React.createClass({
</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)
const protocolName = protocolNameForInstanceId(this.protocols, this.state.instanceId);
let instance_expected_field_type;
if (
protocolName &&
this.protocols &&
this.protocols[protocolName] &&
this.protocols[protocolName].location_fields.length > 0 &&
this.protocols[protocolName].field_types
) {
placeholder = this.props.config.networks[this.state.network].example;
const last_field = this.protocols[protocolName].location_fields.slice(-1)[0];
instance_expected_field_type = this.protocols[protocolName].field_types[last_field];
}
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) {
let placeholder = 'Search for a room';
if (!this.state.instanceId) {
placeholder = '#example:' + this.state.roomServer;
} else if (instance_expected_field_type) {
placeholder = instance_expected_field_type.placeholder;
}
let showJoinButton = this._stringLooksLikeId(this.state.filterString, instance_expected_field_type);
if (protocolName) {
const instance = instanceForInstanceId(this.protocols, this.state.instanceId);
if (this._getFieldsForThirdPartyLocation(this.state.filterString, this.protocols[protocolName], instance) === null) {
showJoinButton = false;
}
}
const SimpleRoomHeader = sdk.getComponent('rooms.SimpleRoomHeader');
const NetworkDropdown = sdk.getComponent('directory.NetworkDropdown');
const DirectorySearchBox = sdk.getComponent('elements.DirectorySearchBox');
return (
@@ -615,7 +545,7 @@ module.exports = React.createClass({
onChange={this.onFilterChange} onClear={this.onFilterClear} onJoinClick={this.onJoinClick}
placeholder={placeholder} showJoinButton={showJoinButton}
/>
<NetworkDropdown config={this.props.config} onOptionChange={this.onOptionChange} />
<NetworkDropdown config={this.props.config} protocols={this.protocols} onOptionChange={this.onOptionChange} />
</div>
{content}
</div>

View File

@@ -16,6 +16,9 @@ limitations under the License.
import React from 'react';
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
import {instanceForInstanceId} from '../../../utils/DirectoryUtils';
const DEFAULT_ICON_URL = "img/network-matrix.svg";
export default class NetworkDropdown extends React.Component {
constructor(props) {
@@ -35,20 +38,11 @@ export default class NetworkDropdown extends React.Component {
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,
selectedInstance: null,
includeAllNetworks: false,
};
}
@@ -58,7 +52,7 @@ export default class NetworkDropdown extends React.Component {
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);
this.props.onOptionChange(this.state.selectedServer, this.state.selectedInstance, this.state.includeAllNetworks);
}
componentWillUnmount() {
@@ -98,13 +92,14 @@ export default class NetworkDropdown extends React.Component {
ev.preventDefault();
}
onMenuOptionClick(server, network, ev) {
onMenuOptionClick(server, instance, includeAll) {
this.setState({
expanded: false,
selectedServer: server,
selectedNetwork: network,
selectedInstanceId: instance ? instance.instance_id : null,
includeAll: includeAll,
});
this.props.onOptionChange(server, network);
this.props.onOptionChange(server, instance ? instance.instance_id : null, includeAll);
}
onInputKeyUp(e) {
@@ -144,11 +139,22 @@ export default class NetworkDropdown extends React.Component {
servers.unshift(MatrixClientPeg.getHomeServerName());
}
// For our own HS, we can use the instance_ids given in the third party protocols
// response to get the server to filter the room list by network for us.
// We can't get thirdparty protocols for remote server yet though, so for those
// we can only show the default room list.
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));
options.push(this._makeMenuOption(server, null, true));
if (server == MatrixClientPeg.getHomeServerName()) {
options.push(this._makeMenuOption(server, null, false));
if (this.props.protocols) {
for (const proto of Object.keys(this.props.protocols)) {
if (!this.props.protocols[proto].instances) continue;
for (const instance of this.props.protocols[proto].instances) {
if (!instance.instance_id) continue;
options.push(this._makeMenuOption(server, instance, false));
}
}
}
}
}
@@ -156,50 +162,36 @@ export default class NetworkDropdown extends React.Component {
return options;
}
_makeMenuOption(server, network, wire_onclick) {
if (wire_onclick === undefined) wire_onclick = true;
_makeMenuOption(server, instance, includeAll, handleClicks) {
if (handleClicks === undefined) handleClicks = true;
let icon;
let name;
let span_class;
let key;
if (network === null) {
if (!instance && includeAll) {
key = server;
name = server;
span_class = 'mx_NetworkDropdown_menu_all';
} else if (network == '_matrix') {
} else if (!instance) {
key = server + '_all';
name = 'Matrix';
icon = <img src="img/network-matrix.svg" width="16" height="16" />;
icon = <img src="img/network-matrix.svg" />;
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" />;
}
key = server + '_inst_' + instance.instance_id;
icon = <img src={instance.icon || DEFAULT_ICON_URL} />;
name = instance.desc;
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;
}
const click_handler = handleClicks ? this.onMenuOptionClick.bind(this, server, instance, includeAll) : null;
return <div key={key} className="mx_NetworkDropdown_networkoption" onClick={click_handler}>
{icon}
<span className={span_class}>{name}</span>
</div>;
<span className="mx_NetworkDropdown_menu_network">{name}</span>
</div>
}
render() {
@@ -216,8 +208,9 @@ export default class NetworkDropdown extends React.Component {
placeholder="matrix.org" // 'matrix.org' as an example of an HS name
/>
} else {
const instance = instanceForInstanceId(this.props.protocols, this.state.selectedInstanceId);
current_value = this._makeMenuOption(
this.state.selectedServer, this.state.selectedNetwork, false
this.state.selectedServer, instance, this.state.includeAll, false
);
}
@@ -233,12 +226,12 @@ export default class NetworkDropdown extends React.Component {
NetworkDropdown.propTypes = {
onOptionChange: React.PropTypes.func.isRequired,
protocols: React.PropTypes.object,
// The room directory config. May have a 'servers' key that is a list of server names to include in the dropdown
config: React.PropTypes.object,
};
NetworkDropdown.defaultProps = {
config: {
networks: [],
}
protocols: {},
config: {},
};

View File

@@ -174,7 +174,7 @@ limitations under the License.
font-size: 16px;
}
.mx_UserSettings_addThreepid {
.mx_UserSettings_threepidButton {
display: table-cell;
padding-left: 0.5em;
position: relative;

View File

@@ -0,0 +1,23 @@
// Find a protocol 'instance' with a given instance_id
// in the supplied protocols dict
export function instanceForInstanceId(protocols, instance_id) {
if (!instance_id) return null;
for (const proto of Object.keys(protocols)) {
if (!protocols[proto].instances && protocols[proto].instances instanceof Array) continue;
for (const instance of protocols[proto].instances) {
if (instance.instance_id == instance_id) return instance;
}
}
}
// given an instance_id, return the name of the protocol for
// that instance ID in the supplied protocols dict
export function protocolNameForInstanceId(protocols, instance_id) {
if (!instance_id) return null;
for (const proto of Object.keys(protocols)) {
if (!protocols[proto].instances && protocols[proto].instances instanceof Array) continue;
for (const instance of protocols[proto].instances) {
if (instance.instance_id == instance_id) return proto;
}
}
}

View File

@@ -136,11 +136,20 @@ var onNewScreen = function(screen) {
// click back to the client having registered.
// It's up to us to recognise if we're loaded with
// this URL and tell MatrixClient to resume registration.
//
// If we're in electron, we should never pass through a file:// URL otherwise
// the identity server will try to 302 the browser to it, which breaks horribly.
// so in that instance, hardcode to use riot.im/app for now instead.
var makeRegistrationUrl = function() {
return window.location.protocol + '//' +
window.location.host +
window.location.pathname +
'#/register';
if (window.location.protocol === "file:") {
return 'https://riot.im/app/#/register';
}
else {
return window.location.protocol + '//' +
window.location.host +
window.location.pathname +
'#/register';
}
}
window.addEventListener('hashchange', onHashChange);

41
src/vector/olm-loader.js Normal file
View File

@@ -0,0 +1,41 @@
/*
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.
*/
/* a very thin shim for loading olm.js: just sets the global OLM_OPTIONS and
* requires the actual olm.js library.
*
* olm.js reads global.OLM_OPTIONS and defines global.Olm. The latter is fine for us,
* but we need to prepare the former.
*
* We can't use webpack's definePlugin to do this, because we tell webpack not
* to parse olm.js. We also can't put this code in index.js, because olm and
* index.js are loaded in parallel, and we need to make sure OLM_OPTIONS is set
* before olm.js is loaded.
*/
/* total_memory must be a power of two, and at least twice the stack.
*
* We don't need a lot of stack, but we do need about 128K of heap to encrypt a
* 64K event (enough to store the ciphertext and the plaintext, bearing in mind
* that the plaintext can only be 48K because base64). We also have about 36K
* of statics. So let's have 256K of memory.
*/
global.OLM_OPTIONS = {
TOTAL_STACK: 64*1024,
TOTAL_MEMORY: 256*1024,
};
require('olm/olm.js');

View File

@@ -127,4 +127,8 @@ export default class ElectronPlatform extends VectorBasePlatform {
getDefaultDeviceDisplayName() {
return "Riot Desktop on " + platformFriendlyName();
}
screenCaptureErrorString() {
return null;
}
}

View File

@@ -196,4 +196,12 @@ export default class WebPlatform extends VectorBasePlatform {
return app_name + " via " + ua.getBrowser().name +
" on " + ua.getOS().name;
}
screenCaptureErrorString() {
// it won't work at all if you're not on HTTPS so whine whine whine
if (!global.window || global.window.location.protocol !== "https:") {
return "You need to be using HTTPS to place a screen-sharing call.";
}
return null;
}
}

View File

@@ -77,6 +77,7 @@ describe('joining a room', function () {
httpBackend.when('POST', '/filter').respond(200, { filter_id: 'fid' });
httpBackend.when('GET', '/sync').respond(200, {});
httpBackend.when('POST', '/publicRooms').respond(200, {chunk: []});
httpBackend.when('GET', '/thirdparty/protocols').respond(200, {});
httpBackend.when('GET', '/directory/room/'+encodeURIComponent(ROOM_ALIAS)).respond(200, { room_id: ROOM_ID });
// start with a logged-in client
@@ -132,6 +133,12 @@ describe('joining a room', function () {
httpBackend.when('POST', '/join/'+encodeURIComponent(ROOM_ALIAS))
.respond(200, {room_id: ROOM_ID});
return httpBackend.flush();
}).then(() => {
// wait for the join request to be made
return q.delay(1);
}).then(() => {
// flush it through
return httpBackend.flush();
}).then(() => {
httpBackend.verifyNoOutstandingExpectation();

View File

@@ -14,7 +14,7 @@ module.exports = {
// (we should probably make js-sdk load it asynchronously at some
// point, so that it doesn't block the pageload, but that is a separate
// problem)
"olm": "olm/olm.js",
"olm": "./src/vector/olm-loader.js",
},
module: {
preLoaders: [