2015-06-23 15:41:25 +00:00
|
|
|
/*
|
2016-01-07 04:06:39 +00:00
|
|
|
Copyright 2015, 2016 OpenMarket Ltd
|
2015-06-23 15:41:25 +00:00
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
2015-11-30 18:11:04 +00:00
|
|
|
var React = require('react');
|
|
|
|
var Matrix = require("matrix-js-sdk");
|
|
|
|
var url = require('url');
|
2015-12-21 12:55:13 +00:00
|
|
|
var Favico = require('favico.js');
|
2015-06-23 15:41:25 +00:00
|
|
|
|
2015-07-02 12:18:03 +00:00
|
|
|
var MatrixClientPeg = require("../../MatrixClientPeg");
|
2015-11-30 15:04:24 +00:00
|
|
|
var Notifier = require("../../Notifier");
|
2015-11-30 18:11:04 +00:00
|
|
|
var ContextualMenu = require("../../ContextualMenu");
|
2015-07-08 17:18:03 +00:00
|
|
|
var RoomListSorter = require("../../RoomListSorter");
|
2015-10-26 13:54:54 +00:00
|
|
|
var UserActivity = require("../../UserActivity");
|
2015-09-18 17:39:16 +00:00
|
|
|
var Presence = require("../../Presence");
|
2015-06-19 11:53:48 +00:00
|
|
|
var dis = require("../../dispatcher");
|
2015-06-09 16:40:42 +00:00
|
|
|
|
2015-11-30 18:11:04 +00:00
|
|
|
var Login = require("./login/Login");
|
|
|
|
var Registration = require("./login/Registration");
|
|
|
|
var PostRegistration = require("./login/PostRegistration");
|
|
|
|
|
2015-12-13 13:49:28 +00:00
|
|
|
var Modal = require("../../Modal");
|
2015-09-15 12:34:36 +00:00
|
|
|
var sdk = require('../../index');
|
2015-09-18 17:39:16 +00:00
|
|
|
var MatrixTools = require('../../MatrixTools');
|
2015-10-27 09:58:55 +00:00
|
|
|
var linkifyMatrix = require("../../linkify-matrix");
|
2015-07-03 10:12:54 +00:00
|
|
|
|
2015-11-30 18:11:04 +00:00
|
|
|
module.exports = React.createClass({
|
|
|
|
displayName: 'MatrixChat',
|
|
|
|
|
|
|
|
propTypes: {
|
|
|
|
config: React.PropTypes.object.isRequired,
|
|
|
|
ConferenceHandler: React.PropTypes.any,
|
|
|
|
onNewScreen: React.PropTypes.func,
|
2015-12-17 14:56:55 +00:00
|
|
|
registrationUrl: React.PropTypes.string,
|
|
|
|
startingQueryParams: React.PropTypes.object
|
2015-11-30 18:11:04 +00:00
|
|
|
},
|
2015-10-12 09:13:01 +00:00
|
|
|
|
2015-09-18 17:39:16 +00:00
|
|
|
PageTypes: {
|
|
|
|
RoomView: "room_view",
|
|
|
|
UserSettings: "user_settings",
|
|
|
|
CreateRoom: "create_room",
|
2015-11-20 14:32:00 +00:00
|
|
|
RoomDirectory: "room_directory",
|
2015-09-18 17:39:16 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
AuxPanel: {
|
|
|
|
RoomSettings: "room_settings",
|
|
|
|
},
|
|
|
|
|
2015-06-11 17:25:29 +00:00
|
|
|
getInitialState: function() {
|
2015-09-18 17:39:16 +00:00
|
|
|
var s = {
|
2015-07-03 10:12:54 +00:00
|
|
|
logged_in: !!(MatrixClientPeg.get() && MatrixClientPeg.get().credentials),
|
2015-10-11 12:49:44 +00:00
|
|
|
collapse_lhs: false,
|
2015-10-11 15:07:01 +00:00
|
|
|
collapse_rhs: false,
|
2015-09-18 17:39:16 +00:00
|
|
|
ready: false,
|
2015-11-30 18:11:04 +00:00
|
|
|
width: 10000
|
2015-06-11 17:25:29 +00:00
|
|
|
};
|
2015-09-18 17:39:16 +00:00
|
|
|
if (s.logged_in) {
|
|
|
|
if (MatrixClientPeg.get().getRooms().length) {
|
|
|
|
s.page_type = this.PageTypes.RoomView;
|
|
|
|
} else {
|
2015-11-15 03:58:05 +00:00
|
|
|
// we don't need to default to the directoy here
|
|
|
|
// as we'll go there anyway after syncing
|
|
|
|
// s.page_type = this.PageTypes.RoomDirectory;
|
2015-09-18 17:39:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return s;
|
2015-06-11 17:25:29 +00:00
|
|
|
},
|
|
|
|
|
2015-12-17 14:56:55 +00:00
|
|
|
getDefaultProps: function() {
|
|
|
|
return {
|
|
|
|
startingQueryParams: {}
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
2015-12-21 12:55:13 +00:00
|
|
|
componentWillMount: function() {
|
|
|
|
this.favicon = new Favico({animation: 'none'});
|
|
|
|
},
|
|
|
|
|
2015-06-12 13:59:33 +00:00
|
|
|
componentDidMount: function() {
|
2015-06-12 16:34:17 +00:00
|
|
|
this.dispatcherRef = dis.register(this.onAction);
|
2015-06-12 13:59:33 +00:00
|
|
|
if (this.state.logged_in) {
|
|
|
|
this.startMatrixClient();
|
|
|
|
}
|
2015-06-18 14:03:57 +00:00
|
|
|
this.focusComposer = false;
|
2015-12-10 16:26:36 +00:00
|
|
|
// scrollStateMap is a map from room id to the scroll state returned by
|
|
|
|
// RoomView.getScrollState()
|
|
|
|
this.scrollStateMap = {};
|
2015-06-25 16:41:55 +00:00
|
|
|
document.addEventListener("keydown", this.onKeyDown);
|
2015-07-07 12:30:38 +00:00
|
|
|
window.addEventListener("focus", this.onFocus);
|
2015-07-15 18:25:36 +00:00
|
|
|
if (this.state.logged_in) {
|
|
|
|
this.notifyNewScreen('');
|
|
|
|
} else {
|
|
|
|
this.notifyNewScreen('login');
|
|
|
|
}
|
2015-10-27 09:58:55 +00:00
|
|
|
|
|
|
|
// this can technically be done anywhere but doing this here keeps all
|
|
|
|
// the routing url path logic together.
|
2015-10-27 10:44:41 +00:00
|
|
|
if (this.onAliasClick) {
|
|
|
|
linkifyMatrix.onAliasClick = this.onAliasClick;
|
|
|
|
}
|
|
|
|
if (this.onUserClick) {
|
|
|
|
linkifyMatrix.onUserClick = this.onUserClick;
|
|
|
|
}
|
2015-11-30 18:11:04 +00:00
|
|
|
|
|
|
|
window.addEventListener('resize', this.handleResize);
|
|
|
|
this.handleResize();
|
2015-06-12 13:59:33 +00:00
|
|
|
},
|
|
|
|
|
2015-06-12 16:34:17 +00:00
|
|
|
componentWillUnmount: function() {
|
|
|
|
dis.unregister(this.dispatcherRef);
|
2015-06-25 16:41:55 +00:00
|
|
|
document.removeEventListener("keydown", this.onKeyDown);
|
2015-09-18 17:39:16 +00:00
|
|
|
window.removeEventListener("focus", this.onFocus);
|
2015-11-30 18:11:04 +00:00
|
|
|
window.removeEventListener('resize', this.handleResize);
|
2015-06-12 16:34:17 +00:00
|
|
|
},
|
|
|
|
|
2015-06-18 14:03:57 +00:00
|
|
|
componentDidUpdate: function() {
|
|
|
|
if (this.focusComposer) {
|
|
|
|
dis.dispatch({action: 'focus_composer'});
|
|
|
|
this.focusComposer = false;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2015-06-12 16:34:17 +00:00
|
|
|
onAction: function(payload) {
|
2015-06-25 16:41:55 +00:00
|
|
|
var roomIndexDelta = 1;
|
|
|
|
|
2015-10-05 14:31:08 +00:00
|
|
|
var self = this;
|
2015-06-12 16:34:17 +00:00
|
|
|
switch (payload.action) {
|
|
|
|
case 'logout':
|
2015-07-16 15:12:54 +00:00
|
|
|
if (window.localStorage) {
|
|
|
|
window.localStorage.clear();
|
|
|
|
}
|
2015-07-03 10:12:54 +00:00
|
|
|
Notifier.stop();
|
2015-10-26 13:54:54 +00:00
|
|
|
UserActivity.stop();
|
2015-09-18 17:39:16 +00:00
|
|
|
Presence.stop();
|
|
|
|
MatrixClientPeg.get().stopClient();
|
2015-07-02 12:18:03 +00:00
|
|
|
MatrixClientPeg.get().removeAllListeners();
|
2015-09-18 17:39:16 +00:00
|
|
|
MatrixClientPeg.unset();
|
2015-10-05 14:31:08 +00:00
|
|
|
this.notifyNewScreen('login');
|
2015-10-09 12:48:17 +00:00
|
|
|
this.replaceState({
|
|
|
|
logged_in: false,
|
|
|
|
ready: false
|
|
|
|
});
|
2015-06-12 16:34:17 +00:00
|
|
|
break;
|
2015-07-13 18:14:02 +00:00
|
|
|
case 'start_registration':
|
|
|
|
if (this.state.logged_in) return;
|
2015-07-15 19:33:12 +00:00
|
|
|
var newState = payload.params || {};
|
|
|
|
newState.screen = 'register';
|
|
|
|
if (
|
|
|
|
payload.params &&
|
|
|
|
payload.params.client_secret &&
|
|
|
|
payload.params.session_id &&
|
|
|
|
payload.params.hs_url &&
|
|
|
|
payload.params.is_url &&
|
|
|
|
payload.params.sid
|
|
|
|
) {
|
|
|
|
newState.register_client_secret = payload.params.client_secret;
|
|
|
|
newState.register_session_id = payload.params.session_id;
|
|
|
|
newState.register_hs_url = payload.params.hs_url;
|
|
|
|
newState.register_is_url = payload.params.is_url;
|
|
|
|
newState.register_id_sid = payload.params.sid;
|
|
|
|
}
|
|
|
|
this.replaceState(newState);
|
2015-07-15 18:25:36 +00:00
|
|
|
this.notifyNewScreen('register');
|
2015-07-13 18:14:02 +00:00
|
|
|
break;
|
|
|
|
case 'start_login':
|
|
|
|
if (this.state.logged_in) return;
|
2015-07-15 18:25:36 +00:00
|
|
|
this.replaceState({
|
2015-07-13 18:14:02 +00:00
|
|
|
screen: 'login'
|
|
|
|
});
|
2015-07-15 18:25:36 +00:00
|
|
|
this.notifyNewScreen('login');
|
2015-10-08 21:25:33 +00:00
|
|
|
break;
|
2015-11-20 11:57:04 +00:00
|
|
|
case 'start_post_registration':
|
|
|
|
this.setState({ // don't clobber logged_in status
|
|
|
|
screen: 'post_registration'
|
|
|
|
});
|
|
|
|
break;
|
2015-11-06 11:21:13 +00:00
|
|
|
case 'token_login':
|
2015-10-08 21:25:33 +00:00
|
|
|
if (this.state.logged_in) return;
|
|
|
|
|
|
|
|
var self = this;
|
2015-11-06 11:21:13 +00:00
|
|
|
MatrixClientPeg.replaceUsingUrls(
|
|
|
|
payload.params.homeserver,
|
|
|
|
payload.params.identityServer
|
|
|
|
);
|
2015-10-08 21:25:33 +00:00
|
|
|
|
2015-11-06 11:21:13 +00:00
|
|
|
var client = MatrixClientPeg.get();
|
|
|
|
client.loginWithToken(payload.params.loginToken).done(function(data) {
|
2015-10-08 21:25:33 +00:00
|
|
|
MatrixClientPeg.replaceUsingAccessToken(
|
2015-10-12 09:13:01 +00:00
|
|
|
client.getHomeserverUrl(), client.getIdentityServerUrl(),
|
2015-10-08 21:25:33 +00:00
|
|
|
data.user_id, data.access_token
|
|
|
|
);
|
|
|
|
self.setState({
|
|
|
|
screen: undefined,
|
|
|
|
logged_in: true
|
|
|
|
});
|
2015-11-06 11:42:13 +00:00
|
|
|
|
|
|
|
// We're left with the login token, hs and is url as query params
|
|
|
|
// in the url, a little nasty but let's redirect to clear them
|
|
|
|
var parsedUrl = url.parse(window.location.href);
|
|
|
|
parsedUrl.search = "";
|
|
|
|
window.location.href = url.format(parsedUrl);
|
|
|
|
|
2015-10-08 21:25:33 +00:00
|
|
|
}, function(error) {
|
|
|
|
self.notifyNewScreen('login');
|
|
|
|
self.setState({errorText: 'Login failed.'});
|
|
|
|
});
|
|
|
|
|
2015-12-13 13:49:28 +00:00
|
|
|
break;
|
|
|
|
case 'leave_room':
|
|
|
|
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
|
|
|
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
|
|
|
|
|
|
|
var roomId = payload.room_id;
|
|
|
|
Modal.createDialog(QuestionDialog, {
|
|
|
|
title: "Leave room",
|
|
|
|
description: "Are you sure you want to leave the room?",
|
|
|
|
onFinished: function(should_leave) {
|
|
|
|
if (should_leave) {
|
|
|
|
var d = MatrixClientPeg.get().leave(roomId);
|
|
|
|
|
|
|
|
// FIXME: controller shouldn't be loading a view :(
|
|
|
|
var Loader = sdk.getComponent("elements.Spinner");
|
|
|
|
var modal = Modal.createDialog(Loader);
|
|
|
|
|
|
|
|
d.then(function() {
|
|
|
|
modal.close();
|
|
|
|
dis.dispatch({action: 'view_next_room'});
|
|
|
|
}, function(err) {
|
|
|
|
modal.close();
|
|
|
|
Modal.createDialog(ErrorDialog, {
|
|
|
|
title: "Failed to leave room",
|
|
|
|
description: err.toString()
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2015-07-13 18:14:02 +00:00
|
|
|
break;
|
2015-06-12 17:01:38 +00:00
|
|
|
case 'view_room':
|
2015-12-10 16:26:36 +00:00
|
|
|
this._viewRoom(payload.room_id);
|
2015-06-12 17:01:38 +00:00
|
|
|
break;
|
2015-06-25 16:41:55 +00:00
|
|
|
case 'view_prev_room':
|
|
|
|
roomIndexDelta = -1;
|
|
|
|
case 'view_next_room':
|
2015-07-08 18:47:58 +00:00
|
|
|
var allRooms = RoomListSorter.mostRecentActivityFirst(
|
|
|
|
MatrixClientPeg.get().getRooms()
|
|
|
|
);
|
2015-06-25 16:41:55 +00:00
|
|
|
var roomIndex = -1;
|
|
|
|
for (var i = 0; i < allRooms.length; ++i) {
|
|
|
|
if (allRooms[i].roomId == this.state.currentRoom) {
|
|
|
|
roomIndex = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
roomIndex = (roomIndex + roomIndexDelta) % allRooms.length;
|
2015-09-18 17:39:16 +00:00
|
|
|
if (roomIndex < 0) roomIndex = allRooms.length - 1;
|
2015-12-10 16:26:36 +00:00
|
|
|
this._viewRoom(allRooms[roomIndex].roomId);
|
2015-09-18 17:39:16 +00:00
|
|
|
break;
|
|
|
|
case 'view_indexed_room':
|
|
|
|
var allRooms = RoomListSorter.mostRecentActivityFirst(
|
|
|
|
MatrixClientPeg.get().getRooms()
|
|
|
|
);
|
|
|
|
var roomIndex = payload.roomIndex;
|
|
|
|
if (allRooms[roomIndex]) {
|
2015-12-10 16:26:36 +00:00
|
|
|
this._viewRoom(allRooms[roomIndex].roomId);
|
2015-09-18 17:39:16 +00:00
|
|
|
}
|
|
|
|
break;
|
2015-10-05 14:31:08 +00:00
|
|
|
case 'view_room_alias':
|
2015-10-27 09:58:55 +00:00
|
|
|
var foundRoom = MatrixTools.getRoomForAlias(
|
|
|
|
MatrixClientPeg.get().getRooms(), payload.room_alias
|
|
|
|
);
|
|
|
|
if (foundRoom) {
|
|
|
|
dis.dispatch({
|
|
|
|
action: 'view_room',
|
|
|
|
room_id: foundRoom.roomId
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// resolve the alias and *then* view it
|
|
|
|
MatrixClientPeg.get().getRoomIdForAlias(payload.room_alias).done(
|
|
|
|
function(result) {
|
2015-10-05 14:31:08 +00:00
|
|
|
dis.dispatch({
|
|
|
|
action: 'view_room',
|
|
|
|
room_id: result.room_id
|
|
|
|
});
|
|
|
|
});
|
|
|
|
break;
|
2015-09-18 17:39:16 +00:00
|
|
|
case 'view_user_settings':
|
2015-12-10 21:53:14 +00:00
|
|
|
this._setPage(this.PageTypes.UserSettings);
|
2015-11-11 01:01:48 +00:00
|
|
|
this.notifyNewScreen('settings');
|
2015-09-18 17:39:16 +00:00
|
|
|
break;
|
|
|
|
case 'view_create_room':
|
2015-12-10 21:53:14 +00:00
|
|
|
this._setPage(this.PageTypes.CreateRoom);
|
2015-11-11 01:01:48 +00:00
|
|
|
this.notifyNewScreen('new');
|
2015-09-18 17:39:16 +00:00
|
|
|
break;
|
|
|
|
case 'view_room_directory':
|
2015-12-10 21:53:14 +00:00
|
|
|
this._setPage(this.PageTypes.RoomDirectory);
|
2015-11-11 01:01:48 +00:00
|
|
|
this.notifyNewScreen('directory');
|
2015-09-18 17:39:16 +00:00
|
|
|
break;
|
|
|
|
case 'notifier_enabled':
|
|
|
|
this.forceUpdate();
|
2015-06-25 16:41:55 +00:00
|
|
|
break;
|
2015-10-11 12:49:44 +00:00
|
|
|
case 'hide_left_panel':
|
|
|
|
this.setState({
|
|
|
|
collapse_lhs: true,
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
case 'show_left_panel':
|
|
|
|
this.setState({
|
|
|
|
collapse_lhs: false,
|
|
|
|
});
|
|
|
|
break;
|
2015-10-11 15:07:01 +00:00
|
|
|
case 'hide_right_panel':
|
|
|
|
this.setState({
|
|
|
|
collapse_rhs: true,
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
case 'show_right_panel':
|
|
|
|
this.setState({
|
|
|
|
collapse_rhs: false,
|
|
|
|
});
|
|
|
|
break;
|
2015-06-12 16:34:17 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2015-12-10 21:53:14 +00:00
|
|
|
_setPage: function(pageType) {
|
|
|
|
// record the scroll state if we're in a room view.
|
|
|
|
this._updateScrollMap();
|
|
|
|
|
|
|
|
this.setState({
|
2015-12-14 11:07:59 +00:00
|
|
|
page_type: pageType,
|
2015-12-10 21:53:14 +00:00
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2015-12-10 16:26:36 +00:00
|
|
|
_viewRoom: function(roomId) {
|
|
|
|
// before we switch room, record the scroll state of the current room
|
|
|
|
this._updateScrollMap();
|
|
|
|
|
|
|
|
this.focusComposer = true;
|
|
|
|
var newState = {
|
|
|
|
currentRoom: roomId,
|
|
|
|
page_type: this.PageTypes.RoomView,
|
|
|
|
};
|
|
|
|
if (this.sdkReady) {
|
|
|
|
// if the SDK is not ready yet, remember what room
|
|
|
|
// we're supposed to be on but don't notify about
|
|
|
|
// the new screen yet (we won't be showing it yet)
|
|
|
|
// The normal case where this happens is navigating
|
|
|
|
// to the room in the URL bar on page load.
|
|
|
|
var presentedId = roomId;
|
|
|
|
var room = MatrixClientPeg.get().getRoom(roomId);
|
|
|
|
if (room) {
|
|
|
|
var theAlias = MatrixTools.getCanonicalAliasForRoom(room);
|
|
|
|
if (theAlias) presentedId = theAlias;
|
|
|
|
}
|
|
|
|
this.notifyNewScreen('room/'+presentedId);
|
|
|
|
newState.ready = true;
|
|
|
|
}
|
|
|
|
this.setState(newState);
|
|
|
|
if (this.scrollStateMap[roomId]) {
|
|
|
|
var scrollState = this.scrollStateMap[roomId];
|
2015-12-10 21:44:30 +00:00
|
|
|
this.refs.roomView.restoreScrollState(scrollState);
|
2015-12-10 16:26:36 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
// update scrollStateMap according to the current scroll state of the
|
|
|
|
// room view.
|
|
|
|
_updateScrollMap: function() {
|
2015-12-10 21:44:30 +00:00
|
|
|
if (!this.refs.roomView) {
|
2015-12-10 16:26:36 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-12-10 21:44:30 +00:00
|
|
|
var roomview = this.refs.roomView;
|
2015-12-10 16:26:36 +00:00
|
|
|
var state = roomview.getScrollState();
|
|
|
|
this.scrollStateMap[roomview.props.roomId] = state;
|
|
|
|
},
|
|
|
|
|
2015-11-12 15:15:00 +00:00
|
|
|
onLoggedIn: function(credentials) {
|
2015-11-20 11:57:04 +00:00
|
|
|
console.log("onLoggedIn => %s", credentials.userId);
|
|
|
|
MatrixClientPeg.replaceUsingAccessToken(
|
|
|
|
credentials.homeserverUrl, credentials.identityServerUrl,
|
|
|
|
credentials.userId, credentials.accessToken
|
|
|
|
);
|
2015-07-13 18:14:02 +00:00
|
|
|
this.setState({
|
2015-07-15 18:25:36 +00:00
|
|
|
screen: undefined,
|
2015-07-13 18:14:02 +00:00
|
|
|
logged_in: true
|
|
|
|
});
|
2015-06-12 13:59:33 +00:00
|
|
|
this.startMatrixClient();
|
2015-07-15 18:25:36 +00:00
|
|
|
this.notifyNewScreen('');
|
2015-06-12 13:59:33 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
startMatrixClient: function() {
|
2015-07-02 12:18:03 +00:00
|
|
|
var cli = MatrixClientPeg.get();
|
2015-09-15 12:34:36 +00:00
|
|
|
var self = this;
|
2015-12-15 14:23:58 +00:00
|
|
|
cli.on('sync', function(state, prevState) {
|
2015-12-21 12:55:13 +00:00
|
|
|
self.updateFavicon();
|
2015-12-15 14:23:58 +00:00
|
|
|
if (state === "SYNCING" && prevState === "SYNCING") {
|
|
|
|
return;
|
|
|
|
}
|
2015-11-12 15:15:00 +00:00
|
|
|
console.log("MatrixClient sync state => %s", state);
|
|
|
|
if (state !== "PREPARED") { return; }
|
2015-09-18 17:39:16 +00:00
|
|
|
self.sdkReady = true;
|
2015-09-25 16:22:42 +00:00
|
|
|
|
|
|
|
if (self.starting_room_alias) {
|
2015-10-05 14:31:08 +00:00
|
|
|
dis.dispatch({
|
|
|
|
action: 'view_room_alias',
|
|
|
|
room_alias: self.starting_room_alias
|
2015-09-25 16:22:42 +00:00
|
|
|
});
|
2015-10-05 14:31:08 +00:00
|
|
|
delete self.starting_room_alias;
|
2015-11-11 01:32:16 +00:00
|
|
|
} else if (!self.state.page_type) {
|
2015-09-25 16:22:42 +00:00
|
|
|
if (!self.state.currentRoom) {
|
|
|
|
var firstRoom = null;
|
|
|
|
if (cli.getRooms() && cli.getRooms().length) {
|
|
|
|
firstRoom = RoomListSorter.mostRecentActivityFirst(
|
|
|
|
cli.getRooms()
|
|
|
|
)[0].roomId;
|
|
|
|
self.setState({ready: true, currentRoom: firstRoom, page_type: self.PageTypes.RoomView});
|
|
|
|
} else {
|
|
|
|
self.setState({ready: true, page_type: self.PageTypes.RoomDirectory});
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
self.setState({ready: true, page_type: self.PageTypes.RoomView});
|
|
|
|
}
|
|
|
|
|
|
|
|
// we notifyNewScreen now because now the room will actually be displayed,
|
|
|
|
// and (mostly) now we can get the correct alias.
|
|
|
|
var presentedId = self.state.currentRoom;
|
|
|
|
var room = MatrixClientPeg.get().getRoom(self.state.currentRoom);
|
|
|
|
if (room) {
|
|
|
|
var theAlias = MatrixTools.getCanonicalAliasForRoom(room);
|
|
|
|
if (theAlias) presentedId = theAlias;
|
|
|
|
}
|
2015-11-11 01:32:16 +00:00
|
|
|
self.notifyNewScreen('room/'+presentedId);
|
2015-09-25 16:22:42 +00:00
|
|
|
dis.dispatch({action: 'focus_composer'});
|
2015-11-11 01:32:16 +00:00
|
|
|
} else {
|
|
|
|
self.setState({ready: true});
|
2015-10-05 14:31:08 +00:00
|
|
|
}
|
2015-06-12 13:59:33 +00:00
|
|
|
});
|
2015-09-18 17:39:16 +00:00
|
|
|
cli.on('Call.incoming', function(call) {
|
|
|
|
dis.dispatch({
|
|
|
|
action: 'incoming_call',
|
|
|
|
call: call
|
|
|
|
});
|
|
|
|
});
|
2015-07-03 10:12:54 +00:00
|
|
|
Notifier.start();
|
2015-10-26 13:54:54 +00:00
|
|
|
UserActivity.start();
|
2015-09-18 17:39:16 +00:00
|
|
|
Presence.start();
|
2015-12-07 15:33:58 +00:00
|
|
|
cli.startClient({
|
|
|
|
pendingEventOrdering: "end"
|
|
|
|
});
|
2015-06-11 17:25:29 +00:00
|
|
|
},
|
2015-06-25 16:41:55 +00:00
|
|
|
|
|
|
|
onKeyDown: function(ev) {
|
|
|
|
if (ev.altKey) {
|
2015-10-31 14:00:23 +00:00
|
|
|
/*
|
|
|
|
// Remove this for now as ctrl+alt = alt-gr so this breaks keyboards which rely on alt-gr for numbers
|
|
|
|
// Will need to find a better meta key if anyone actually cares about using this.
|
2015-09-18 17:39:16 +00:00
|
|
|
if (ev.ctrlKey && ev.keyCode > 48 && ev.keyCode < 58) {
|
|
|
|
dis.dispatch({
|
|
|
|
action: 'view_indexed_room',
|
|
|
|
roomIndex: ev.keyCode - 49,
|
|
|
|
});
|
|
|
|
ev.stopPropagation();
|
|
|
|
ev.preventDefault();
|
|
|
|
return;
|
|
|
|
}
|
2015-10-31 14:00:23 +00:00
|
|
|
*/
|
2015-06-25 16:41:55 +00:00
|
|
|
switch (ev.keyCode) {
|
|
|
|
case 38:
|
|
|
|
dis.dispatch({action: 'view_prev_room'});
|
|
|
|
ev.stopPropagation();
|
2015-09-18 17:39:16 +00:00
|
|
|
ev.preventDefault();
|
2015-06-25 16:41:55 +00:00
|
|
|
break;
|
|
|
|
case 40:
|
|
|
|
dis.dispatch({action: 'view_next_room'});
|
|
|
|
ev.stopPropagation();
|
2015-09-18 17:39:16 +00:00
|
|
|
ev.preventDefault();
|
2015-06-25 16:41:55 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2015-07-07 12:30:38 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
onFocus: function(ev) {
|
|
|
|
dis.dispatch({action: 'focus_composer'});
|
2015-07-15 18:25:36 +00:00
|
|
|
},
|
|
|
|
|
2015-07-16 11:44:04 +00:00
|
|
|
showScreen: function(screen, params) {
|
2015-07-15 19:33:12 +00:00
|
|
|
if (screen == 'register') {
|
|
|
|
dis.dispatch({
|
|
|
|
action: 'start_registration',
|
|
|
|
params: params
|
|
|
|
});
|
|
|
|
} else if (screen == 'login') {
|
|
|
|
dis.dispatch({
|
|
|
|
action: 'start_login',
|
|
|
|
params: params
|
|
|
|
});
|
2015-11-06 11:21:13 +00:00
|
|
|
} else if (screen == 'token_login') {
|
2015-10-08 21:25:33 +00:00
|
|
|
dis.dispatch({
|
2015-11-06 11:21:13 +00:00
|
|
|
action: 'token_login',
|
2015-10-08 21:25:33 +00:00
|
|
|
params: params
|
|
|
|
});
|
2015-11-11 01:01:48 +00:00
|
|
|
} else if (screen == 'new') {
|
|
|
|
dis.dispatch({
|
|
|
|
action: 'view_create_room',
|
|
|
|
});
|
|
|
|
} else if (screen == 'settings') {
|
|
|
|
dis.dispatch({
|
|
|
|
action: 'view_user_settings',
|
|
|
|
});
|
|
|
|
} else if (screen == 'directory') {
|
|
|
|
dis.dispatch({
|
|
|
|
action: 'view_room_directory',
|
|
|
|
});
|
2015-11-20 11:57:04 +00:00
|
|
|
} else if (screen == 'post_registration') {
|
|
|
|
dis.dispatch({
|
|
|
|
action: 'start_post_registration',
|
|
|
|
});
|
2015-09-18 17:39:16 +00:00
|
|
|
} else if (screen.indexOf('room/') == 0) {
|
|
|
|
var roomString = screen.split('/')[1];
|
|
|
|
if (roomString[0] == '#') {
|
2015-10-05 14:31:08 +00:00
|
|
|
if (this.state.logged_in) {
|
|
|
|
dis.dispatch({
|
|
|
|
action: 'view_room_alias',
|
|
|
|
room_alias: roomString
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
// Okay, we'll take you here soon...
|
|
|
|
this.starting_room_alias = roomString;
|
|
|
|
// ...but you're still going to have to log in.
|
|
|
|
this.notifyNewScreen('login');
|
|
|
|
}
|
2015-09-18 17:39:16 +00:00
|
|
|
} else {
|
|
|
|
dis.dispatch({
|
|
|
|
action: 'view_room',
|
2015-09-25 16:22:42 +00:00
|
|
|
room_id: roomString
|
2015-09-18 17:39:16 +00:00
|
|
|
});
|
2015-09-25 16:22:42 +00:00
|
|
|
}
|
2015-07-15 19:33:12 +00:00
|
|
|
}
|
2015-11-20 14:26:49 +00:00
|
|
|
else {
|
|
|
|
console.error("Unknown screen : %s", screen);
|
|
|
|
}
|
2015-07-15 18:25:36 +00:00
|
|
|
},
|
|
|
|
|
2015-12-17 15:12:09 +00:00
|
|
|
notifyNewScreen: function(screen) {
|
2015-07-15 18:25:36 +00:00
|
|
|
if (this.props.onNewScreen) {
|
2015-12-17 15:12:09 +00:00
|
|
|
this.props.onNewScreen(screen);
|
2015-07-15 18:25:36 +00:00
|
|
|
}
|
2015-11-30 18:11:04 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
onAliasClick: function(event, alias) {
|
|
|
|
event.preventDefault();
|
|
|
|
dis.dispatch({action: 'view_room_alias', room_alias: alias});
|
|
|
|
},
|
|
|
|
|
|
|
|
onUserClick: function(event, userId) {
|
|
|
|
event.preventDefault();
|
|
|
|
var MemberInfo = sdk.getComponent('rooms.MemberInfo');
|
|
|
|
var member = new Matrix.RoomMember(null, userId);
|
|
|
|
ContextualMenu.createMenu(MemberInfo, {
|
|
|
|
member: member,
|
|
|
|
right: window.innerWidth - event.pageX,
|
|
|
|
top: event.pageY
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
onLogoutClick: function(event) {
|
|
|
|
dis.dispatch({
|
|
|
|
action: 'logout'
|
|
|
|
});
|
|
|
|
event.stopPropagation();
|
|
|
|
event.preventDefault();
|
|
|
|
},
|
|
|
|
|
|
|
|
handleResize: function(e) {
|
|
|
|
var hideLhsThreshold = 1000;
|
|
|
|
var showLhsThreshold = 1000;
|
|
|
|
var hideRhsThreshold = 820;
|
|
|
|
var showRhsThreshold = 820;
|
|
|
|
|
|
|
|
if (this.state.width > hideLhsThreshold && window.innerWidth <= hideLhsThreshold) {
|
|
|
|
dis.dispatch({ action: 'hide_left_panel' });
|
|
|
|
}
|
|
|
|
if (this.state.width <= showLhsThreshold && window.innerWidth > showLhsThreshold) {
|
|
|
|
dis.dispatch({ action: 'show_left_panel' });
|
|
|
|
}
|
|
|
|
if (this.state.width > hideRhsThreshold && window.innerWidth <= hideRhsThreshold) {
|
|
|
|
dis.dispatch({ action: 'hide_right_panel' });
|
|
|
|
}
|
|
|
|
if (this.state.width <= showRhsThreshold && window.innerWidth > showRhsThreshold) {
|
|
|
|
dis.dispatch({ action: 'show_right_panel' });
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setState({width: window.innerWidth});
|
|
|
|
},
|
|
|
|
|
|
|
|
onRoomCreated: function(room_id) {
|
|
|
|
dis.dispatch({
|
|
|
|
action: "view_room",
|
|
|
|
room_id: room_id,
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
onRegisterClick: function() {
|
|
|
|
this.showScreen("register");
|
|
|
|
},
|
|
|
|
|
|
|
|
onLoginClick: function() {
|
|
|
|
this.showScreen("login");
|
|
|
|
},
|
|
|
|
|
|
|
|
onRegistered: function(credentials) {
|
|
|
|
this.onLoggedIn(credentials);
|
|
|
|
// do post-registration stuff
|
|
|
|
this.showScreen("post_registration");
|
|
|
|
},
|
|
|
|
|
|
|
|
onFinishPostRegistration: function() {
|
|
|
|
// Don't confuse this with "PageType" which is the middle window to show
|
|
|
|
this.setState({
|
|
|
|
screen: undefined
|
|
|
|
});
|
|
|
|
this.showScreen("settings");
|
|
|
|
},
|
|
|
|
|
2015-12-21 12:55:13 +00:00
|
|
|
updateFavicon: function() {
|
|
|
|
var notifCount = 0;
|
|
|
|
|
|
|
|
var rooms = MatrixClientPeg.get().getRooms();
|
|
|
|
for (var i = 0; i < rooms.length; ++i) {
|
2016-01-07 10:38:44 +00:00
|
|
|
if (rooms[i].unread_notification_count) {
|
|
|
|
notifCount += rooms[i].unread_notification_count;
|
|
|
|
}
|
2015-12-21 12:55:13 +00:00
|
|
|
}
|
|
|
|
this.favicon.badge(notifCount);
|
|
|
|
document.title = (notifCount > 0 ? "["+notifCount+"] " : "")+"Vector";
|
|
|
|
},
|
|
|
|
|
2015-12-23 11:47:56 +00:00
|
|
|
onUserSettingsClose: function() {
|
|
|
|
// XXX: use browser history instead to find the previous room?
|
|
|
|
if (this.state.currentRoom) {
|
|
|
|
dis.dispatch({
|
|
|
|
action: 'view_room',
|
|
|
|
room_id: this.state.currentRoom,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
dis.dispatch({
|
|
|
|
action: 'view_indexed_room',
|
|
|
|
roomIndex: 0,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2015-11-30 18:11:04 +00:00
|
|
|
render: function() {
|
2015-12-01 15:45:11 +00:00
|
|
|
var LeftPanel = sdk.getComponent('structures.LeftPanel');
|
2015-11-30 18:11:04 +00:00
|
|
|
var RoomView = sdk.getComponent('structures.RoomView');
|
2015-12-01 15:45:11 +00:00
|
|
|
var RightPanel = sdk.getComponent('structures.RightPanel');
|
2015-11-30 18:11:04 +00:00
|
|
|
var UserSettings = sdk.getComponent('structures.UserSettings');
|
|
|
|
var CreateRoom = sdk.getComponent('structures.CreateRoom');
|
2015-12-01 15:45:11 +00:00
|
|
|
var RoomDirectory = sdk.getComponent('structures.RoomDirectory');
|
2015-12-01 11:19:25 +00:00
|
|
|
var MatrixToolbar = sdk.getComponent('globals.MatrixToolbar');
|
2015-11-30 18:11:04 +00:00
|
|
|
|
|
|
|
// needs to be before normal PageTypes as you are logged in technically
|
|
|
|
if (this.state.screen == 'post_registration') {
|
|
|
|
return (
|
|
|
|
<PostRegistration
|
|
|
|
onComplete={this.onFinishPostRegistration} />
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else if (this.state.logged_in && this.state.ready) {
|
|
|
|
var page_element;
|
|
|
|
var right_panel = "";
|
|
|
|
|
|
|
|
switch (this.state.page_type) {
|
|
|
|
case this.PageTypes.RoomView:
|
|
|
|
page_element = (
|
|
|
|
<RoomView
|
2015-12-10 21:44:30 +00:00
|
|
|
ref="roomView"
|
2015-11-30 18:11:04 +00:00
|
|
|
roomId={this.state.currentRoom}
|
|
|
|
key={this.state.currentRoom}
|
|
|
|
ConferenceHandler={this.props.ConferenceHandler} />
|
|
|
|
);
|
|
|
|
right_panel = <RightPanel roomId={this.state.currentRoom} collapsed={this.state.collapse_rhs} />
|
|
|
|
break;
|
|
|
|
case this.PageTypes.UserSettings:
|
2015-12-23 11:47:56 +00:00
|
|
|
page_element = <UserSettings onClose={this.onUserSettingsClose} />
|
2015-11-30 18:11:04 +00:00
|
|
|
right_panel = <RightPanel collapsed={this.state.collapse_rhs}/>
|
|
|
|
break;
|
|
|
|
case this.PageTypes.CreateRoom:
|
|
|
|
page_element = <CreateRoom onRoomCreated={this.onRoomCreated}/>
|
|
|
|
right_panel = <RightPanel collapsed={this.state.collapse_rhs}/>
|
|
|
|
break;
|
|
|
|
case this.PageTypes.RoomDirectory:
|
|
|
|
page_element = <RoomDirectory />
|
|
|
|
right_panel = <RightPanel collapsed={this.state.collapse_rhs}/>
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Fix duplication here and do conditionals like we do above
|
|
|
|
if (Notifier.supportsDesktopNotifications() && !Notifier.isEnabled() && !Notifier.isToolbarHidden()) {
|
|
|
|
return (
|
|
|
|
<div className="mx_MatrixChat_wrapper">
|
|
|
|
<MatrixToolbar />
|
|
|
|
<div className="mx_MatrixChat mx_MatrixChat_toolbarShowing">
|
|
|
|
<LeftPanel selectedRoom={this.state.currentRoom} collapsed={this.state.collapse_lhs} />
|
|
|
|
<main className="mx_MatrixChat_middlePanel">
|
|
|
|
{page_element}
|
|
|
|
</main>
|
|
|
|
{right_panel}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return (
|
|
|
|
<div className="mx_MatrixChat">
|
|
|
|
<LeftPanel selectedRoom={this.state.currentRoom} collapsed={this.state.collapse_lhs} />
|
|
|
|
<main className="mx_MatrixChat_middlePanel">
|
|
|
|
{page_element}
|
|
|
|
</main>
|
|
|
|
{right_panel}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
} else if (this.state.logged_in) {
|
|
|
|
var Spinner = sdk.getComponent('elements.Spinner');
|
|
|
|
return (
|
|
|
|
<div className="mx_MatrixChat_splash">
|
|
|
|
<Spinner />
|
|
|
|
<a href="#" className="mx_MatrixChat_splashButtons" onClick={ this.onLogoutClick }>Logout</a>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
} else if (this.state.screen == 'register') {
|
|
|
|
return (
|
|
|
|
<Registration
|
|
|
|
clientSecret={this.state.register_client_secret}
|
|
|
|
sessionId={this.state.register_session_id}
|
|
|
|
idSid={this.state.register_id_sid}
|
2015-12-17 14:56:55 +00:00
|
|
|
email={this.props.startingQueryParams.email}
|
2015-12-01 15:36:40 +00:00
|
|
|
hsUrl={this.props.config.default_hs_url}
|
|
|
|
isUrl={this.props.config.default_is_url}
|
2015-11-30 18:11:04 +00:00
|
|
|
registrationUrl={this.props.registrationUrl}
|
|
|
|
onLoggedIn={this.onRegistered}
|
|
|
|
onLoginClick={this.onLoginClick} />
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
return (
|
|
|
|
<Login
|
|
|
|
onLoggedIn={this.onLoggedIn}
|
|
|
|
onRegisterClick={this.onRegisterClick}
|
2015-12-01 15:36:40 +00:00
|
|
|
homeserverUrl={this.props.config.default_hs_url}
|
|
|
|
identityServerUrl={this.props.config.default_is_url} />
|
2015-11-30 18:11:04 +00:00
|
|
|
);
|
|
|
|
}
|
2015-06-25 16:41:55 +00:00
|
|
|
}
|
2015-11-30 18:11:04 +00:00
|
|
|
});
|