diff --git a/src/components/structures/BottomLeftMenu.js b/src/components/structures/BottomLeftMenu.js
index 3aa1ec33..924410f5 100644
--- a/src/components/structures/BottomLeftMenu.js
+++ b/src/components/structures/BottomLeftMenu.js
@@ -16,7 +16,14 @@ limitations under the License.
*/
import React from 'react';
+import ReactDOM from 'react-dom';
import sdk from 'matrix-react-sdk';
+import dis from 'matrix-react-sdk/lib/dispatcher';
+import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton';
+import Velocity from 'velocity-vector';
+import 'velocity-vector/velocity.ui';
+
+const CALLOUT_ANIM_DURATION = 1000;
module.exports = React.createClass({
displayName: 'BottomLeftMenu',
@@ -25,6 +32,136 @@ module.exports = React.createClass({
collapsed: React.PropTypes.bool.isRequired,
},
+ getInitialState: function() {
+ return({
+ directoryHover : false,
+ roomsHover : false,
+ homeHover: false,
+ peopleHover : false,
+ settingsHover : false,
+ });
+ },
+
+ componentWillMount: function() {
+ this._dispatcherRef = dis.register(this.onAction);
+ this._peopleButton = null;
+ this._directoryButton = null;
+ this._createRoomButton = null;
+ this._lastCallouts = {};
+ },
+
+ componentWillUnmount: function() {
+ dis.unregister(this._dispatcherRef);
+ },
+
+ // 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 });
+ },
+
+ // Home button events
+ onHomeClick: function() {
+ dis.dispatch({ action: 'view_home_page' });
+ },
+
+ onHomeMouseEnter: function() {
+ this.setState({ homeHover: true });
+ },
+
+ onHomeMouseLeave: function() {
+ this.setState({ homeHover: 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' });
+ },
+
+ onSettingsMouseEnter: function() {
+ this.setState({ settingsHover: true });
+ },
+
+ onSettingsMouseLeave: function() {
+ this.setState({ settingsHover: false });
+ },
+
+ onAction: function(payload) {
+ let calloutElement;
+ switch (payload.action) {
+ // Incoming instruction: dance!
+ case 'callout_start_chat':
+ calloutElement = this._peopleButton;
+ break;
+ case 'callout_room_directory':
+ calloutElement = this._directoryButton;
+ break;
+ case 'callout_create_room':
+ calloutElement = this._createRoomButton;
+ break;
+ }
+ if (calloutElement) {
+ const lastCallout = this._lastCallouts[payload.action];
+ const now = Date.now();
+ if (lastCallout == undefined || lastCallout < now - CALLOUT_ANIM_DURATION) {
+ this._lastCallouts[payload.action] = now;
+ Velocity(ReactDOM.findDOMNode(calloutElement), "callout.bounce", CALLOUT_ANIM_DURATION);
+ }
+ }
+ },
+
+ // Get the label/tooltip to show
+ getLabel: function(label, show) {
+ if (show) {
+ var RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
+ return