diff --git a/.gitignore b/.gitignore index 060ca6e9..2ad05012 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,6 @@ npm-debug.log electron/dist electron/pub -/.idea +**/.idea /config.json /src/component-index.js diff --git a/CHANGELOG.md b/CHANGELOG.md index fb753d55..0f3a738b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,151 @@ +Changes in [0.12.0-rc.1](https://github.com/vector-im/riot-web/releases/tag/v0.12.0-rc.1) (2017-08-16) +====================================================================================================== +[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.11.4...v0.12.0-rc.1) + + * Update from Weblate. + [\#4797](https://github.com/vector-im/riot-web/pull/4797) + * move focus-via-up/down cursors to LeftPanel + [\#4777](https://github.com/vector-im/riot-web/pull/4777) + * Remove userId property on RightPanel + [\#4775](https://github.com/vector-im/riot-web/pull/4775) + * Make member device info buttons fluid and stackable with flexbox + [\#4776](https://github.com/vector-im/riot-web/pull/4776) + * un-i18n Modal Analytics + [\#4688](https://github.com/vector-im/riot-web/pull/4688) + * Quote using innerText + [\#4773](https://github.com/vector-im/riot-web/pull/4773) + * Karma tweaks for riot-web + [\#4765](https://github.com/vector-im/riot-web/pull/4765) + * Fix typo with scripts/fetch-develop-deps.sh in Building From Source + [\#4764](https://github.com/vector-im/riot-web/pull/4764) + * Adjust CSS for optional avatars in pills + [\#4757](https://github.com/vector-im/riot-web/pull/4757) + * Fix crypto on develop + [\#4754](https://github.com/vector-im/riot-web/pull/4754) + * Fix signing key url in readme + [\#4464](https://github.com/vector-im/riot-web/pull/4464) + * update gitignore to allow .idea directory to exist in subdirs + [\#4749](https://github.com/vector-im/riot-web/pull/4749) + * tweak compact theme + [\#4665](https://github.com/vector-im/riot-web/pull/4665) + * Update draft-js from 0.10.1 to 0.11.0-alpha + [\#4740](https://github.com/vector-im/riot-web/pull/4740) + * electron support for mouse forward/back buttons in Windows + [\#4739](https://github.com/vector-im/riot-web/pull/4739) + * Update draft-js from 0.8.1 to 0.10.1 + [\#4730](https://github.com/vector-im/riot-web/pull/4730) + * Make pills, emoji translucent when sending + [\#4693](https://github.com/vector-im/riot-web/pull/4693) + * Widget permissions styling and icon + [\#4690](https://github.com/vector-im/riot-web/pull/4690) + * CSS required for composer autoscroll + [\#4682](https://github.com/vector-im/riot-web/pull/4682) + * CSS for group edit UI + [\#4608](https://github.com/vector-im/riot-web/pull/4608) + * Fix a couple of minor errors in the room list + [\#4671](https://github.com/vector-im/riot-web/pull/4671) + * Styling for beta testing icon. + [\#4584](https://github.com/vector-im/riot-web/pull/4584) + * Increase the timeout for clearing indexeddbs + [\#4650](https://github.com/vector-im/riot-web/pull/4650) + * Make some adjustments to mx_UserPill and mx_RoomPill + [\#4597](https://github.com/vector-im/riot-web/pull/4597) + * Apply CSS to
 tags to distinguish them from each other
+   [\#4639](https://github.com/vector-im/riot-web/pull/4639)
+ * Use `catch` instead of `fail` to handle room tag error
+   [\#4643](https://github.com/vector-im/riot-web/pull/4643)
+ * CSS for decorated matrix.to links in the composer
+   [\#4583](https://github.com/vector-im/riot-web/pull/4583)
+ * Deflake the joining test
+   [\#4579](https://github.com/vector-im/riot-web/pull/4579)
+ * Bump react to 15.6 to fix build problems
+   [\#4577](https://github.com/vector-im/riot-web/pull/4577)
+ * Improve AppTile menu bar button styling.
+   [\#4567](https://github.com/vector-im/riot-web/pull/4567)
+ * Transform `async` functions to bluebird promises
+   [\#4572](https://github.com/vector-im/riot-web/pull/4572)
+ * use flushAllExpected in joining test
+   [\#4570](https://github.com/vector-im/riot-web/pull/4570)
+ * Switch riot-web to bluebird
+   [\#4565](https://github.com/vector-im/riot-web/pull/4565)
+ * loading tests: wait for login component
+   [\#4564](https://github.com/vector-im/riot-web/pull/4564)
+ * Remove CSS for the MessageComposerInputOld
+   [\#4568](https://github.com/vector-im/riot-web/pull/4568)
+ * Implement the focus_room_filter action
+   [\#4560](https://github.com/vector-im/riot-web/pull/4560)
+ * CSS for Rooms in Group View
+   [\#4530](https://github.com/vector-im/riot-web/pull/4530)
+ * more HomePage tweaks
+   [\#4557](https://github.com/vector-im/riot-web/pull/4557)
+ * Give HomePage an unmounted guard
+   [\#4556](https://github.com/vector-im/riot-web/pull/4556)
+ * Take RTE out of labs
+   [\#4500](https://github.com/vector-im/riot-web/pull/4500)
+ * CSS for Groups page
+   [\#4468](https://github.com/vector-im/riot-web/pull/4468)
+ * CSS for GroupView
+   [\#4442](https://github.com/vector-im/riot-web/pull/4442)
+ * remove unused class
+   [\#4525](https://github.com/vector-im/riot-web/pull/4525)
+ * Fix long words causing MessageComposer to widen
+   [\#4466](https://github.com/vector-im/riot-web/pull/4466)
+ * Add visual bell animation for RTE
+   [\#4516](https://github.com/vector-im/riot-web/pull/4516)
+ * Truncate auto-complete pills properly
+   [\#4502](https://github.com/vector-im/riot-web/pull/4502)
+ * Use chrome headless instead of phantomjs
+   [\#4512](https://github.com/vector-im/riot-web/pull/4512)
+ * Use external mock-request
+   [\#4489](https://github.com/vector-im/riot-web/pull/4489)
+ * fix Quote not closing contextual menu
+   [\#4443](https://github.com/vector-im/riot-web/pull/4443)
+ * Apply white-space: pre-wrap to mx_MEmoteBody
+   [\#4470](https://github.com/vector-im/riot-web/pull/4470)
+ * Add some style improvements to autocompletions
+   [\#4456](https://github.com/vector-im/riot-web/pull/4456)
+ * Styling for apps / widgets
+   [\#4447](https://github.com/vector-im/riot-web/pull/4447)
+ * Attempt to flush the rageshake logs on close
+   [\#4400](https://github.com/vector-im/riot-web/pull/4400)
+ * Update from Weblate.
+   [\#4401](https://github.com/vector-im/riot-web/pull/4401)
+ * improve update polling electron and provide a manual check for updates
+   button
+   [\#4176](https://github.com/vector-im/riot-web/pull/4176)
+ * Fix load failure in firefox when indexedDB is disabled
+   [\#4395](https://github.com/vector-im/riot-web/pull/4395)
+ * Change missed 'Redact' to 'Remove' in ImageView.
+   [\#4362](https://github.com/vector-im/riot-web/pull/4362)
+ * explicit convert to nativeImage to stabilise trayIcon on Windows [Electron]
+   [\#4355](https://github.com/vector-im/riot-web/pull/4355)
+ * Use _tJsx for PasswordNagBar (because it has )
+   [\#4373](https://github.com/vector-im/riot-web/pull/4373)
+ * Clean up some log outputs from the integ tests
+   [\#4376](https://github.com/vector-im/riot-web/pull/4376)
+ * CSS for redeisng of password warning
+   [\#4367](https://github.com/vector-im/riot-web/pull/4367)
+ * Give _t to PasswordNagBar, add CSS for UserSettings password warning
+   [\#4366](https://github.com/vector-im/riot-web/pull/4366)
+ * Update from Weblate.
+   [\#4361](https://github.com/vector-im/riot-web/pull/4361)
+ * Update from Weblate.
+   [\#4360](https://github.com/vector-im/riot-web/pull/4360)
+ * Test 'return-to-app' functionality
+   [\#4352](https://github.com/vector-im/riot-web/pull/4352)
+ * Update from Weblate.
+   [\#4354](https://github.com/vector-im/riot-web/pull/4354)
+ * onLoadCompleted is now onTokenLoginCompleted
+   [\#4335](https://github.com/vector-im/riot-web/pull/4335)
+ * Tweak tests to match updates to matrixchat
+   [\#4325](https://github.com/vector-im/riot-web/pull/4325)
+ * Update from Weblate.
+   [\#4346](https://github.com/vector-im/riot-web/pull/4346)
+ * change dispatcher forward_event signature
+   [\#4337](https://github.com/vector-im/riot-web/pull/4337)
+ * Add border on hover for code blocks
+   [\#4259](https://github.com/vector-im/riot-web/pull/4259)
+
 Changes in [0.11.4](https://github.com/vector-im/riot-web/releases/tag/v0.11.4) (2017-06-22)
 ============================================================================================
 [Full Changelog](https://github.com/vector-im/riot-web/compare/v0.11.3...v0.11.4)
diff --git a/README.md b/README.md
index d4b778b9..27138203 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ released version of Riot:
 1. Enter the URL into your browser and log into Riot!
 
 Releases are signed by PGP, and can be checked against the public key
-at https://riot.im/packages/keys/riot-master.asc
+at https://riot.im/packages/keys/riot.asc
 
 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
@@ -62,7 +62,7 @@ to build.
 1. If you're using the `develop` branch, install the develop versions of the
    dependencies, as the released ones will be too old:
    ```
-   scripts/fetch-develop-deps.sh
+   scripts/fetch-develop.deps.sh
    ```
    Whenever you git pull on riot-web you will also probably need to force an update
    to these dependencies - the simplest way is to re-run the script, but you can also
diff --git a/electron_app/package.json b/electron_app/package.json
index 2c6e62f2..2eed90d5 100644
--- a/electron_app/package.json
+++ b/electron_app/package.json
@@ -2,7 +2,7 @@
   "name": "riot-web",
   "productName": "Riot",
   "main": "src/electron-main.js",
-  "version": "0.11.4",
+  "version": "0.12.0-rc.1",
   "description": "A feature-rich client for Matrix.org",
   "author": "Vector Creations Ltd.",
   "dependencies": {
diff --git a/electron_app/src/electron-main.js b/electron_app/src/electron-main.js
index 99e14b74..ce5ac384 100644
--- a/electron_app/src/electron-main.js
+++ b/electron_app/src/electron-main.js
@@ -228,6 +228,17 @@ electron.app.on('ready', () => {
         }
     });
 
+    if (process.platform === 'win32') {
+        // Handle forward/backward mouse buttons in Windows
+        mainWindow.on('app-command', (e, cmd) => {
+            if (cmd === 'browser-backward' && mainWindow.webContents.canGoBack()) {
+                mainWindow.webContents.goBack();
+            } else if (cmd === 'browser-forward' && mainWindow.webContents.canGoForward()) {
+                mainWindow.webContents.goForward();
+            }
+        });
+    }
+
     webContentsHandler(mainWindow.webContents);
     mainWindowState.manage(mainWindow);
 });
diff --git a/karma.conf.js b/karma.conf.js
index d834987e..3b415b1a 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -84,13 +84,23 @@ module.exports = function (config) {
         // available preprocessors:
         // https://npmjs.org/browse/keyword/karma-preprocessor
         preprocessors: {
-            '{src,test}/**/*.js': ['webpack'],
+            '{src,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'],
+        reporters: ['logcapture', 'spec', 'junit', 'summary'],
+
+        specReporter: {
+            suppressErrorSummary: false, // do print error summary
+            suppressFailed: false, // do print information about failed tests
+            suppressPassed: false, // do print information about passed tests
+            showSpecTiming: true, // print the time elapsed for each spec
+        },
+
+        client: {
+            captureLogs: true,
+        },
 
         // web server port
         port: 9876,
diff --git a/package.json b/package.json
index 2b1d6e82..5b752325 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "name": "riot-web",
   "productName": "Riot",
   "main": "electron_app/src/electron-main.js",
-  "version": "0.11.4",
+  "version": "0.12.0-rc.1",
   "description": "A feature-rich client for Matrix.org",
   "author": "Vector Creations Ltd.",
   "repository": {
@@ -31,8 +31,8 @@
     "build:res": "node scripts/copy-res.js",
     "build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js",
     "build:compile": "npm run reskindex && babel --source-maps -d lib src",
-    "build:bundle": "cross-env NODE_ENV=production webpack -p --progress",
-    "build:bundle:dev": "webpack --optimize-occurence-order --progress",
+    "build:bundle": "cross-env NODE_ENV=production webpack -p --progress --bail",
+    "build:bundle:dev": "webpack --optimize-occurence-order --progress --bail",
     "build:electron": "npm run clean && npm run build && npm run install:electron && build -wml --ia32 --x64",
     "build": "npm run reskindex && npm run build:res && npm run build:bundle",
     "build:dev": "npm run reskindex && npm run build:res && npm run build:bundle:dev",
@@ -57,7 +57,7 @@
     "bluebird": "^3.5.0",
     "browser-request": "^0.3.3",
     "classnames": "^2.1.2",
-    "draft-js": "^0.8.1",
+    "draft-js": "^0.11.0-alpha",
     "extract-text-webpack-plugin": "^0.9.1",
     "favico.js": "^0.3.10",
     "filesize": "3.5.6",
@@ -66,8 +66,8 @@
     "gfm.css": "^1.1.1",
     "highlight.js": "^9.0.0",
     "linkifyjs": "^2.1.3",
-    "matrix-js-sdk": "0.7.13",
-    "matrix-react-sdk": "0.9.7",
+    "matrix-js-sdk": "0.8.0",
+    "matrix-react-sdk": "0.10.0-rc.1",
     "modernizr": "^3.1.0",
     "pako": "^1.0.5",
     "react": "^15.6.0",
@@ -114,11 +114,15 @@
     "fs-extra": "^0.30.0",
     "html-webpack-plugin": "^2.24.0",
     "json-loader": "^0.5.3",
-    "karma": "^0.13.22",
+    "karma": "^1.7.0",
     "karma-chrome-launcher": "^0.2.3",
     "karma-cli": "^0.1.2",
     "karma-junit-reporter": "^0.4.1",
+    "karma-logcapture-reporter": "0.0.1",
     "karma-mocha": "^0.2.2",
+    "karma-sourcemap-loader": "^0.3.7",
+    "karma-spec-reporter": "0.0.31",
+    "karma-summary-reporter": "^1.3.3",
     "karma-webpack": "^1.7.0",
     "matrix-mock-request": "^1.2.0",
     "matrix-react-test-utils": "^0.2.0",
diff --git a/release.sh b/release.sh
index 8ae307f7..13675018 100755
--- a/release.sh
+++ b/release.sh
@@ -11,7 +11,7 @@ cd `dirname $0`
 
 for i in matrix-js-sdk matrix-react-sdk
 do
-    depver=`cat package.json | jq -r .dependencies.\"$i\"`
+    depver=`cat package.json | jq -r .dependencies[\"$i\"]`
     latestver=`npm show $i version`
     if [ "$depver" != "$latestver" ]
     then
diff --git a/scripts/copy-res.js b/scripts/copy-res.js
index e8f6684d..fa52492e 100755
--- a/scripts/copy-res.js
+++ b/scripts/copy-res.js
@@ -9,24 +9,27 @@
 // This could readily be automated, but it's nice to explicitly
 // control when we languages are available.
 const INCLUDE_LANGS = [
+    {'value': 'da', 'label': 'Dansk'},
+    {'value': 'de_DE', 'label': 'Deutsch'},
     {'value': 'en_EN', 'label': 'English'},
     {'value': 'en_US', 'label': 'English (US)'},
-    {'value': 'da', 'label': 'Dansk'},
     {'value': 'el', 'label': 'Ελληνικά'},
     {'value': 'eo', 'label': 'Esperanto'},
-    {'value': 'nl', 'label': 'Nederlands'},
-    {'value': 'de_DE', 'label': 'Deutsch'},
+    {'value': 'es', 'label': 'Español'},
+    {'value': 'eu', 'label': 'Euskal'},
     {'value': 'fr', 'label': 'Français'},
     {'value': 'hu', 'label': 'Magyar'},
     {'value': 'ko', 'label': '한국어'},
+    {'value': 'lv', 'label': 'Latviešu'},
     {'value': 'nb_NO', 'label': 'Norwegian Bokmål'},
+    {'value': 'nl', 'label': 'Nederlands'},
     {'value': 'pl', 'label': 'Polski'},
     {'value': 'pt', 'label': 'Português'},
     {'value': 'pt_BR', 'label': 'Português do Brasil'},
     {'value': 'ru', 'label': 'Русский'},
     {'value': 'sv', 'label': 'Svenska'},
-    {'value': 'es', 'label': 'Español'},
     {'value': 'th', 'label': 'ไทย'},
+    {'value': 'te', 'label': 'తెలుగు'},
     {'value': 'tr', 'label': 'Türk'},
     {'value': 'zh_Hans', 'label': '简体中文'}, // simplified chinese
     {'value': 'zh_Hant', 'label': '繁體中文'}, // traditional chinese
diff --git a/scripts/fetch-develop.deps.sh b/scripts/fetch-develop.deps.sh
index 4fa1a4a2..e2d40341 100755
--- a/scripts/fetch-develop.deps.sh
+++ b/scripts/fetch-develop.deps.sh
@@ -49,42 +49,47 @@ function dodep() {
         [ "$curbranch" != 'develop' ] && clone $org $repo develop
     } || return $?
 
-    (
-        cd $repo
-        echo "$repo set to branch "`git rev-parse --abbrev-ref HEAD`
-    )
+    echo "$repo set to branch "`git -C "$repo" rev-parse --abbrev-ref HEAD`
 
     mkdir -p node_modules
     rm -r "node_modules/$repo" 2>/dev/null || true
     ln -sv "../$repo" node_modules/
+
+    (
+        cd $repo
+        npm install
+    )
 }
 
+##############################
+
 echo -en 'travis_fold:start:matrix-js-sdk\r'
 echo 'Setting up matrix-js-sdk'
 
 dodep matrix-org matrix-js-sdk
-(
-    cd node_modules/matrix-js-sdk
-    npm install
-)
 
 echo -en 'travis_fold:end:matrix-js-sdk\r'
 
+##############################
+
 echo -en 'travis_fold:start:matrix-react-sdk\r'
 echo 'Setting up matrix-react-sdk'
 
 dodep matrix-org matrix-react-sdk
 
-mkdir -p node_modules/matrix-react-sdk/node_modules
+# replace the version of js-sdk that got pulled into react-sdk with a symlink
+# to our version. Make sure to do this *after* doing 'npm i' in react-sdk,
+# otherwise npm helpfully moves another-json from matrix-js-sdk/node_modules
+# into matrix-react-sdk/node_modules.
+#
+# (note this matches the instructions in the README.)
+rm -r node_modules/matrix-react-sdk/node_modules/matrix-js-sdk
 ln -s ../../matrix-js-sdk node_modules/matrix-react-sdk/node_modules/
 
-(
-    cd node_modules/matrix-react-sdk
-    npm install
-)
-
 echo -en 'travis_fold:end:matrix-react-sdk\r'
 
+##############################
+
 # Link the reskindex binary in place: if we used npm link,
 # npm would do this for us, but we don't because we'd have
 # to define the npm prefix somewhere so it could put the
diff --git a/scripts/jenkins.sh b/scripts/jenkins.sh
index 4f2e9405..7b5b4c8e 100755
--- a/scripts/jenkins.sh
+++ b/scripts/jenkins.sh
@@ -8,8 +8,11 @@ nvm use 6
 
 set -x
 
-# check out corresponding branches of dependencies
-`dirname $0`/fetch-develop.deps.sh
+# check out corresponding branches of dependencies.
+#
+# clone the deps with depth 1: we know we will only ever need that one
+# commit.
+`dirname $0`/fetch-develop.deps.sh --depth 1
 
 npm install
 
diff --git a/src/components/structures/LeftPanel.js b/src/components/structures/LeftPanel.js
index 77338404..4539df1f 100644
--- a/src/components/structures/LeftPanel.js
+++ b/src/components/structures/LeftPanel.js
@@ -16,17 +16,16 @@ limitations under the License.
 
 'use strict';
 
-var React = require('react');
-var DragDropContext = require('react-dnd').DragDropContext;
-var HTML5Backend = require('react-dnd-html5-backend');
-var sdk = require('matrix-react-sdk')
-var dis = require('matrix-react-sdk/lib/dispatcher');
+import React from 'react';
+import { DragDropContext } from 'react-dnd';
+import HTML5Backend from 'react-dnd-html5-backend';
+import KeyCode from 'matrix-react-sdk/lib/KeyCode';
+import sdk from 'matrix-react-sdk';
+import dis from 'matrix-react-sdk/lib/dispatcher';
 import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
-
-var VectorConferenceHandler = require('../../VectorConferenceHandler');
-var CallHandler = require("matrix-react-sdk/lib/CallHandler");
-
+import CallHandler from 'matrix-react-sdk/lib/CallHandler';
 import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton';
+import VectorConferenceHandler from '../../VectorConferenceHandler';
 
 var LeftPanel = React.createClass({
     displayName: 'LeftPanel',
@@ -42,6 +41,10 @@ var LeftPanel = React.createClass({
         };
     },
 
+    componentWillMount: function() {
+        this.focusedElement = null;
+    },
+
     componentDidMount: function() {
         this.dispatcherRef = dis.register(this.onAction);
     },
@@ -64,6 +67,91 @@ var LeftPanel = React.createClass({
         }
     },
 
+    _onFocus: function(ev) {
+        this.focusedElement = ev.target;
+    },
+
+    _onBlur: function(ev) {
+        this.focusedElement = null;
+    },
+
+    _onKeyDown: function(ev) {
+        if (!this.focusedElement) return;
+        let handled = false;
+
+        switch (ev.keyCode) {
+            case KeyCode.UP:
+                this._onMoveFocus(true);
+                handled = true;
+                break;
+            case KeyCode.DOWN:
+                this._onMoveFocus(false);
+                handled = true;
+                break;
+        }
+
+        if (handled) {
+            ev.stopPropagation();
+            ev.preventDefault();
+        }
+    },
+
+    _onMoveFocus: function(up) {
+        var element = this.focusedElement;
+
+        // unclear why this isn't needed
+        // var descending = (up == this.focusDirection) ? this.focusDescending : !this.focusDescending;
+        // this.focusDirection = up;
+
+        var descending = false; // are we currently descending or ascending through the DOM tree?
+        var classes;
+
+        do {
+            var child = up ? element.lastElementChild : element.firstElementChild;
+            var sibling = up ? element.previousElementSibling : element.nextElementSibling;
+
+            if (descending) {
+                if (child) {
+                    element = child;
+                }
+                else if (sibling) {
+                    element = sibling;
+                }
+                else {
+                    descending = false;
+                    element = element.parentElement;
+                }
+            }
+            else {
+                if (sibling) {
+                    element = sibling;
+                    descending = true;
+                }
+                else {
+                    element = element.parentElement;
+                }
+            }
+
+            if (element) {
+                classes = element.classList;
+                if (classes.contains("mx_LeftPanel")) { // we hit the top
+                    element = up ? element.lastElementChild : element.firstElementChild;
+                    descending = true;
+                }
+            }
+
+        } while(element && !(
+            classes.contains("mx_RoomTile") ||
+            classes.contains("mx_SearchBox_search") ||
+            classes.contains("mx_RoomSubList_ellipsis")));
+
+        if (element) {
+            element.focus();
+            this.focusedElement = element;
+            this.focusedDescending = descending;
+        }
+    },
+
     _recheckCallElement: function(selectedRoomId) {
         // if we aren't viewing a room with an ongoing call, but there is an
         // active call, show the call element - we need to do this to make
@@ -126,7 +214,8 @@ var LeftPanel = React.createClass({
         }
 
         return (
-