Merge remote-tracking branch 'origin/develop' into dbkr/group_userlist
This commit is contained in:
commit
06fe240be2
38 changed files with 1083 additions and 184 deletions
|
@ -30,13 +30,14 @@ import VectorConferenceHandler from '../../VectorConferenceHandler';
|
|||
var LeftPanel = React.createClass({
|
||||
displayName: 'LeftPanel',
|
||||
|
||||
// NB. If you add props, don't forget to update
|
||||
// shouldComponentUpdate!
|
||||
propTypes: {
|
||||
collapsed: React.PropTypes.bool.isRequired,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
showCallElement: null,
|
||||
searchFilter: '',
|
||||
};
|
||||
},
|
||||
|
@ -45,26 +46,25 @@ var LeftPanel = React.createClass({
|
|||
this.focusedElement = null;
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(newProps) {
|
||||
this._recheckCallElement(newProps.selectedRoom);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
dis.unregister(this.dispatcherRef);
|
||||
},
|
||||
|
||||
onAction: function(payload) {
|
||||
switch (payload.action) {
|
||||
// listen for call state changes to prod the render method, which
|
||||
// may hide the global CallView if the call it is tracking is dead
|
||||
case 'call_state':
|
||||
this._recheckCallElement(this.props.selectedRoom);
|
||||
break;
|
||||
shouldComponentUpdate: function(nextProps, nextState) {
|
||||
// MatrixChat will update whenever the user switches
|
||||
// rooms, but propagating this change all the way down
|
||||
// the react tree is quite slow, so we cut this off
|
||||
// here. The RoomTiles listen for the room change
|
||||
// events themselves to know when to update.
|
||||
// We just need to update if any of these things change.
|
||||
if (
|
||||
this.props.collapsed !== nextProps.collapsed ||
|
||||
this.props.opacity !== nextProps.opacity
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.state.searchFilter !== nextState.searchFilter) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_onFocus: function(ev) {
|
||||
|
@ -152,74 +152,41 @@ var LeftPanel = React.createClass({
|
|||
}
|
||||
},
|
||||
|
||||
_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
|
||||
// audio/video not crap out
|
||||
var activeCall = CallHandler.getAnyActiveCall();
|
||||
var callForRoom = CallHandler.getCallForRoom(selectedRoomId);
|
||||
var showCall = (activeCall && activeCall.call_state === 'connected' && !callForRoom);
|
||||
this.setState({
|
||||
showCallElement: showCall
|
||||
});
|
||||
},
|
||||
|
||||
onHideClick: function() {
|
||||
dis.dispatch({
|
||||
action: 'hide_left_panel',
|
||||
});
|
||||
},
|
||||
|
||||
onCallViewClick: function() {
|
||||
var call = CallHandler.getAnyActiveCall();
|
||||
if (call) {
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: call.groupRoomId || call.roomId,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
onSearch: function(term) {
|
||||
this.setState({ searchFilter: term });
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var RoomList = sdk.getComponent('rooms.RoomList');
|
||||
var BottomLeftMenu = sdk.getComponent('structures.BottomLeftMenu');
|
||||
const RoomList = sdk.getComponent('rooms.RoomList');
|
||||
const BottomLeftMenu = sdk.getComponent('structures.BottomLeftMenu');
|
||||
const CallPreview = sdk.getComponent('voip.CallPreview');
|
||||
|
||||
var topBox;
|
||||
let topBox;
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
var LoginBox = sdk.getComponent('structures.LoginBox');
|
||||
const LoginBox = sdk.getComponent('structures.LoginBox');
|
||||
topBox = <LoginBox collapsed={ this.props.collapsed }/>;
|
||||
}
|
||||
else {
|
||||
var SearchBox = sdk.getComponent('structures.SearchBox');
|
||||
} else {
|
||||
const SearchBox = sdk.getComponent('structures.SearchBox');
|
||||
topBox = <SearchBox collapsed={ this.props.collapsed } onSearch={ this.onSearch } />;
|
||||
}
|
||||
|
||||
var classes = "mx_LeftPanel mx_fadable";
|
||||
let classes = "mx_LeftPanel mx_fadable";
|
||||
if (this.props.collapsed) {
|
||||
classes += " collapsed";
|
||||
}
|
||||
|
||||
var callPreview;
|
||||
if (this.state.showCallElement && !this.props.collapsed) {
|
||||
var CallView = sdk.getComponent('voip.CallView');
|
||||
callPreview = (
|
||||
<CallView
|
||||
className="mx_LeftPanel_callView" showVoice={true} onClick={this.onCallViewClick}
|
||||
ConferenceHandler={VectorConferenceHandler} />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<aside className={classes} style={{ opacity: this.props.opacity }}
|
||||
onKeyDown={ this._onKeyDown } onFocus={ this._onFocus } onBlur={ this._onBlur }>
|
||||
{ topBox }
|
||||
{ callPreview }
|
||||
<CallPreview ConferenceHandler={VectorConferenceHandler} />
|
||||
<RoomList
|
||||
selectedRoom={this.props.selectedRoom}
|
||||
collapsed={this.props.collapsed}
|
||||
searchFilter={this.state.searchFilter}
|
||||
ConferenceHandler={VectorConferenceHandler} />
|
||||
|
|
|
@ -84,7 +84,7 @@ module.exports = React.createClass({
|
|||
|
||||
var self = this;
|
||||
return (
|
||||
<div className="mx_SearchBox">
|
||||
<div className="mx_SearchBox mx_LoginBox">
|
||||
{ loginButton }
|
||||
{ toggleCollapse }
|
||||
</div>
|
||||
|
|
|
@ -75,8 +75,8 @@ var RoomSubList = React.createClass({
|
|||
|
||||
order: React.PropTypes.string.isRequired,
|
||||
|
||||
// undefined if no room is selected (eg we are showing settings)
|
||||
selectedRoom: React.PropTypes.string,
|
||||
// passed through to RoomTile and used to highlight room with `!` regardless of notifications count
|
||||
isInvite: React.PropTypes.bool,
|
||||
|
||||
startAsHidden: React.PropTypes.bool,
|
||||
showSpinner: React.PropTypes.bool, // true to show a spinner if 0 elements when expanded
|
||||
|
@ -104,6 +104,7 @@ var RoomSubList = React.createClass({
|
|||
onHeaderClick: function() {}, // NOP
|
||||
onShowMoreRooms: function() {}, // NOP
|
||||
extraTiles: [],
|
||||
isInvite: false,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -248,7 +249,7 @@ var RoomSubList = React.createClass({
|
|||
return this.props.list.reduce(function(result, room, index) {
|
||||
if (truncateAt === undefined || index >= truncateAt) {
|
||||
var roomNotifState = RoomNotifs.getRoomNotifsState(room.roomId);
|
||||
var highlight = room.getUnreadNotificationCount('highlight') > 0 || self.props.label === 'Invites';
|
||||
var highlight = room.getUnreadNotificationCount('highlight') > 0 || self.props.isInvite;
|
||||
var notificationCount = room.getUnreadNotificationCount();
|
||||
|
||||
const notifBadges = notificationCount > 0 && self._shouldShowNotifBadge(roomNotifState);
|
||||
|
@ -368,7 +369,6 @@ var RoomSubList = React.createClass({
|
|||
var self = this;
|
||||
var DNDRoomTile = sdk.getComponent("rooms.DNDRoomTile");
|
||||
return this.state.sortedList.map(function(room) {
|
||||
var selected = room.roomId == self.props.selectedRoom;
|
||||
// XXX: is it evil to pass in self as a prop to RoomTile?
|
||||
return (
|
||||
<DNDRoomTile
|
||||
|
@ -376,10 +376,9 @@ var RoomSubList = React.createClass({
|
|||
roomSubList={ self }
|
||||
key={ room.roomId }
|
||||
collapsed={ self.props.collapsed || false}
|
||||
selected={ selected }
|
||||
unread={ Unread.doesRoomHaveUnreadMessages(room) }
|
||||
highlight={ room.getUnreadNotificationCount('highlight') > 0 || self.props.label === 'Invites' }
|
||||
isInvite={ self.props.label === 'Invites' }
|
||||
highlight={ room.getUnreadNotificationCount('highlight') > 0 || self.props.isInvite }
|
||||
isInvite={ self.props.isInvite }
|
||||
refreshSubList={ self._updateSubListCount }
|
||||
incomingCall={ null }
|
||||
onClick={ self.onRoomTileClick }
|
||||
|
@ -411,6 +410,9 @@ var RoomSubList = React.createClass({
|
|||
var badge;
|
||||
if (subListNotifCount > 0) {
|
||||
badge = <div className={badgeClasses}>{ FormattingUtils.formatCount(subListNotifCount) }</div>;
|
||||
} else if (this.props.isInvite) {
|
||||
// no notifications but highlight anyway because this is an invite badge
|
||||
badge = <div className={badgeClasses}>!</div>;
|
||||
}
|
||||
|
||||
// When collapsed, allow a long hover on the header to show user
|
||||
|
|
30
src/components/views/context_menus/GenericTextContextMenu.js
Normal file
30
src/components/views/context_menus/GenericTextContextMenu.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Copyright 2017 Michael Telatynski <7t3chguy@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export default class GenericTextContextMenu extends React.Component {
|
||||
static PropTypes = {
|
||||
message: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>{ this.props.message }</div>;
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import sdk from 'matrix-react-sdk';
|
||||
import SdkConfig from 'matrix-react-sdk/lib/SdkConfig';
|
||||
import Modal from 'matrix-react-sdk/lib/Modal';
|
||||
import { _t } from 'matrix-react-sdk/lib/languageHandler';
|
||||
|
||||
export default class BugReportDialog extends React.Component {
|
||||
|
@ -64,8 +65,13 @@ export default class BugReportDialog extends React.Component {
|
|||
progressCallback: this._sendProgressCallback,
|
||||
}).then(() => {
|
||||
if (!this._unmounted) {
|
||||
this.setState({ busy: false, progress: null });
|
||||
this.props.onFinished(false);
|
||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
Modal.createTrackedDialog('Bug report sent', '', QuestionDialog, {
|
||||
title: _t('Bug report sent'),
|
||||
description: _t('Thank you!'),
|
||||
hasCancelButton: false,
|
||||
});
|
||||
}
|
||||
}, (err) => {
|
||||
if (!this._unmounted) {
|
||||
|
|
|
@ -30,7 +30,7 @@ module.exports = React.createClass({
|
|||
<div className="mx_Login_links">
|
||||
<a href="https://medium.com/@RiotChat">blog</a> ·
|
||||
<a href="https://twitter.com/@RiotChat">twitter</a> ·
|
||||
<a href="https://github.com/vector-im/vector-web">github</a> ·
|
||||
<a href="https://github.com/vector-im/riot-web">github</a> ·
|
||||
<a href="https://matrix.org">{ _t('powered by Matrix') }</a>
|
||||
</div>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue