diff --git a/src/components/structures/BottomLeftMenu.js b/src/components/structures/BottomLeftMenu.js index f378cac628c693fcec8f692db1533f7ca1a3ee66..8ae8aec7fad1900c8c9272f93bcbcd9c0126c14f 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({ <div className="mx_BottomLeftMenu_options"> { homeButton } <AccessibleButton className="mx_BottomLeftMenu_people" onClick={ this.onPeopleClick } onMouseEnter={ this.onPeopleMouseEnter } onMouseLeave={ this.onPeopleMouseLeave } > - <TintableSvg src="img/icons-people.svg" width="25" height="25" /> + <TintableSvg ref={this._collectPeopleButton} src="img/icons-people.svg" width="25" height="25" /> { this.getLabel("Start chat", this.state.peopleHover) } </AccessibleButton> <AccessibleButton className="mx_BottomLeftMenu_directory" onClick={ this.onDirectoryClick } onMouseEnter={ this.onDirectoryMouseEnter } onMouseLeave={ this.onDirectoryMouseLeave } > - <TintableSvg src="img/icons-directory.svg" width="25" height="25"/> + <TintableSvg ref={this._collectDirectoryButton} src="img/icons-directory.svg" width="25" height="25"/> { this.getLabel("Room directory", this.state.directoryHover) } </AccessibleButton> <AccessibleButton className="mx_BottomLeftMenu_createRoom" onClick={ this.onRoomsClick } onMouseEnter={ this.onRoomsMouseEnter } onMouseLeave={ this.onRoomsMouseLeave } > - <TintableSvg src="img/icons-create-room.svg" width="25" height="25" /> + <TintableSvg ref={this._collectCreateRoomButton} src="img/icons-create-room.svg" width="25" height="25" /> { this.getLabel("Create new room", this.state.roomsHover) } </AccessibleButton> <AccessibleButton className="mx_BottomLeftMenu_settings" onClick={ this.onSettingsClick } onMouseEnter={ this.onSettingsMouseEnter } onMouseLeave={ this.onSettingsMouseLeave } >