diff --git a/src/components/structures/BottomLeftMenu.js b/src/components/structures/BottomLeftMenu.js index f378cac628..8ae8aec7fa 100644 --- a/src/components/structures/BottomLeftMenu.js +++ b/src/components/structures/BottomLeftMenu.js @@ -14,13 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -'use strict'; +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'; -var React = require('react'); -var ReactDOM = require('react-dom'); -var sdk = require('matrix-react-sdk') -var dis = require('matrix-react-sdk/lib/dispatcher'); -var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton'); +const CALLOUT_ANIM_DURATION = 1000; module.exports = React.createClass({ displayName: 'BottomLeftMenu', @@ -40,6 +42,18 @@ module.exports = React.createClass({ }); }, + 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' }); @@ -104,6 +118,30 @@ module.exports = React.createClass({ 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) { @@ -112,6 +150,18 @@ module.exports = React.createClass({ } }, + _collectPeopleButton: function(e) { + this._peopleButton = e; + }, + + _collectDirectoryButton: function(e) { + this._directoryButton = e; + }, + + _collectCreateRoomButton: function(e) { + this._createRoomButton = e; + }, + render: function() { var TintableSvg = sdk.getComponent('elements.TintableSvg'); @@ -130,15 +180,15 @@ module.exports = React.createClass({
{ homeButton } - + { this.getLabel("Start chat", this.state.peopleHover) } - + { this.getLabel("Room directory", this.state.directoryHover) } - + { this.getLabel("Create new room", this.state.roomsHover) }