Merge branch 'develop' into kegan/rageshake-ui
This commit is contained in:
commit
602ce37ba7
38 changed files with 1764 additions and 479 deletions
|
@ -21,6 +21,7 @@ import KeyCode from '../../KeyCode';
|
|||
import Notifier from '../../Notifier';
|
||||
import PageTypes from '../../PageTypes';
|
||||
import sdk from '../../index';
|
||||
import dis from '../../dispatcher';
|
||||
|
||||
/**
|
||||
* This is what our MatrixChat shows when we are logged in. The precise view is
|
||||
|
|
|
@ -259,8 +259,6 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onAction: function(payload) {
|
||||
console.log("onAction: "+payload.action);
|
||||
|
||||
var roomIndexDelta = 1;
|
||||
|
||||
var self = this;
|
||||
|
@ -1008,8 +1006,8 @@ module.exports = React.createClass({
|
|||
var ForgotPassword = sdk.getComponent('structures.login.ForgotPassword');
|
||||
var LoggedInView = sdk.getComponent('structures.LoggedInView');
|
||||
|
||||
console.log("rendering; loading="+this.state.loading+"; screen="+this.state.screen +
|
||||
"; logged_in="+this.state.logged_in+"; ready="+this.state.ready);
|
||||
// console.log("rendering; loading="+this.state.loading+"; screen="+this.state.screen +
|
||||
// "; logged_in="+this.state.logged_in+"; ready="+this.state.ready);
|
||||
|
||||
if (this.state.loading) {
|
||||
var Spinner = sdk.getComponent('elements.Spinner');
|
||||
|
|
|
@ -281,7 +281,6 @@ module.exports = React.createClass({
|
|||
|
||||
var isMembershipChange = (e) =>
|
||||
e.getType() === 'm.room.member'
|
||||
&& ['join', 'leave'].indexOf(e.getContent().membership) !== -1
|
||||
&& (!e.getPrevContent() || e.getContent().membership !== e.getPrevContent().membership);
|
||||
|
||||
for (i = 0; i < this.props.events.length; i++) {
|
||||
|
|
|
@ -21,8 +21,6 @@ var WhoIsTyping = require("../../WhoIsTyping");
|
|||
var MatrixClientPeg = require("../../MatrixClientPeg");
|
||||
const MemberAvatar = require("../views/avatars/MemberAvatar");
|
||||
|
||||
const TYPING_AVATARS_LIMIT = 2;
|
||||
|
||||
const HIDE_DEBOUNCE_MS = 10000;
|
||||
const STATUS_BAR_HIDDEN = 0;
|
||||
const STATUS_BAR_EXPANDED = 1;
|
||||
|
@ -53,6 +51,10 @@ module.exports = React.createClass({
|
|||
// more interesting)
|
||||
hasActiveCall: React.PropTypes.bool,
|
||||
|
||||
// Number of names to display in typing indication. E.g. set to 3, will
|
||||
// result in "X, Y, Z and 100 others are typing."
|
||||
whoIsTypingLimit: React.PropTypes.number,
|
||||
|
||||
// callback for when the user clicks on the 'resend all' button in the
|
||||
// 'unsent messages' bar
|
||||
onResendAllClick: React.PropTypes.func,
|
||||
|
@ -77,10 +79,19 @@ module.exports = React.createClass({
|
|||
onVisible: React.PropTypes.func,
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
whoIsTypingLimit: 2,
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
syncState: MatrixClientPeg.get().getSyncState(),
|
||||
whoisTypingString: WhoIsTyping.whoIsTypingString(this.props.room),
|
||||
whoisTypingString: WhoIsTyping.whoIsTypingString(
|
||||
this.props.room,
|
||||
this.props.whoIsTypingLimit
|
||||
),
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -127,7 +138,10 @@ module.exports = React.createClass({
|
|||
|
||||
onRoomMemberTyping: function(ev, member) {
|
||||
this.setState({
|
||||
whoisTypingString: WhoIsTyping.whoIsTypingString(this.props.room),
|
||||
whoisTypingString: WhoIsTyping.whoIsTypingString(
|
||||
this.props.room,
|
||||
this.props.whoIsTypingLimit
|
||||
),
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -135,7 +149,11 @@ module.exports = React.createClass({
|
|||
// changed - so we use '0' to indicate normal size, and other values to
|
||||
// indicate other sizes.
|
||||
_getSize: function(state, props) {
|
||||
if (state.syncState === "ERROR" || state.whoisTypingString) {
|
||||
if (state.syncState === "ERROR" ||
|
||||
state.whoisTypingString ||
|
||||
props.numUnreadMessages ||
|
||||
!props.atEndOfLiveTimeline ||
|
||||
props.hasActiveCall) {
|
||||
return STATUS_BAR_EXPANDED;
|
||||
} else if (props.tabCompleteEntries) {
|
||||
return STATUS_BAR_HIDDEN;
|
||||
|
@ -190,7 +208,7 @@ module.exports = React.createClass({
|
|||
if (wantPlaceholder) {
|
||||
return (
|
||||
<div className="mx_RoomStatusBar_typingIndicatorAvatars">
|
||||
{this._renderTypingIndicatorAvatars(TYPING_AVATARS_LIMIT)}
|
||||
{this._renderTypingIndicatorAvatars(this.props.whoIsTypingLimit)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -722,15 +722,11 @@ module.exports = React.createClass({
|
|||
if (!result.displayname) {
|
||||
var SetDisplayNameDialog = sdk.getComponent('views.dialogs.SetDisplayNameDialog');
|
||||
var dialog_defer = q.defer();
|
||||
var dialog_ref;
|
||||
Modal.createDialog(SetDisplayNameDialog, {
|
||||
currentDisplayName: result.displayname,
|
||||
ref: (r) => {
|
||||
dialog_ref = r;
|
||||
},
|
||||
onFinished: (submitted) => {
|
||||
onFinished: (submitted, newDisplayName) => {
|
||||
if (submitted) {
|
||||
cli.setDisplayName(dialog_ref.getValue()).done(() => {
|
||||
cli.setDisplayName(newDisplayName).done(() => {
|
||||
dialog_defer.resolve();
|
||||
});
|
||||
}
|
||||
|
@ -1531,6 +1527,7 @@ module.exports = React.createClass({
|
|||
onResize={this.onChildResize}
|
||||
onVisible={this.onStatusBarVisible}
|
||||
onHidden={this.onStatusBarHidden}
|
||||
whoIsTypingLimit={2}
|
||||
/>;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ var GeminiScrollbar = require('react-gemini-scrollbar');
|
|||
var Email = require('../../email');
|
||||
var AddThreepid = require('../../AddThreepid');
|
||||
var SdkConfig = require('../../SdkConfig');
|
||||
import AccessibleButton from '../views/elements/AccessibleButton';
|
||||
|
||||
// if this looks like a release, use the 'version' from package.json; else use
|
||||
// the git sha.
|
||||
|
@ -229,8 +230,26 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onLogoutClicked: function(ev) {
|
||||
var LogoutPrompt = sdk.getComponent('dialogs.LogoutPrompt');
|
||||
this.logoutModal = Modal.createDialog(LogoutPrompt);
|
||||
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
Modal.createDialog(QuestionDialog, {
|
||||
title: "Sign out?",
|
||||
description:
|
||||
<div>
|
||||
For security, logging out will delete any end-to-end encryption keys from this browser,
|
||||
making previous encrypted chat history unreadable if you log back in.
|
||||
In future this <a href="https://github.com/vector-im/riot-web/issues/2108">will be improved</a>,
|
||||
but for now be warned.
|
||||
</div>,
|
||||
button: "Sign out",
|
||||
onFinished: (confirmed) => {
|
||||
if (confirmed) {
|
||||
dis.dispatch({action: 'logout'});
|
||||
if (this.props.onFinished) {
|
||||
this.props.onFinished();
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
onPasswordChangeError: function(err) {
|
||||
|
@ -398,6 +417,30 @@ module.exports = React.createClass({
|
|||
}).done();
|
||||
},
|
||||
|
||||
_onExportE2eKeysClicked: function() {
|
||||
Modal.createDialogAsync(
|
||||
(cb) => {
|
||||
require.ensure(['../../async-components/views/dialogs/ExportE2eKeysDialog'], () => {
|
||||
cb(require('../../async-components/views/dialogs/ExportE2eKeysDialog'));
|
||||
}, "e2e-export");
|
||||
}, {
|
||||
matrixClient: MatrixClientPeg.get(),
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
_onImportE2eKeysClicked: function() {
|
||||
Modal.createDialogAsync(
|
||||
(cb) => {
|
||||
require.ensure(['../../async-components/views/dialogs/ImportE2eKeysDialog'], () => {
|
||||
cb(require('../../async-components/views/dialogs/ImportE2eKeysDialog'));
|
||||
}, "e2e-export");
|
||||
}, {
|
||||
matrixClient: MatrixClientPeg.get(),
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
_renderUserInterfaceSettings: function() {
|
||||
var client = MatrixClientPeg.get();
|
||||
|
||||
|
@ -468,6 +511,23 @@ module.exports = React.createClass({
|
|||
const deviceId = client.deviceId;
|
||||
const identityKey = client.getDeviceEd25519Key() || "<not supported>";
|
||||
|
||||
let exportButton = null,
|
||||
importButton = null;
|
||||
|
||||
if (client.isCryptoEnabled) {
|
||||
exportButton = (
|
||||
<AccessibleButton className="mx_UserSettings_button"
|
||||
onClick={this._onExportE2eKeysClicked}>
|
||||
Export E2E room keys
|
||||
</AccessibleButton>
|
||||
);
|
||||
importButton = (
|
||||
<AccessibleButton className="mx_UserSettings_button"
|
||||
onClick={this._onImportE2eKeysClicked}>
|
||||
Import E2E room keys
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<h3>Cryptography</h3>
|
||||
|
@ -476,6 +536,8 @@ module.exports = React.createClass({
|
|||
<li><label>Device ID:</label> <span><code>{deviceId}</code></span></li>
|
||||
<li><label>Device key:</label> <span><code><b>{identityKey}</b></code></span></li>
|
||||
</ul>
|
||||
{exportButton}
|
||||
{importButton}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -554,9 +616,9 @@ module.exports = React.createClass({
|
|||
return <div>
|
||||
<h3>Deactivate Account</h3>
|
||||
<div className="mx_UserSettings_section">
|
||||
<button className="mx_UserSettings_button danger"
|
||||
<AccessibleButton className="mx_UserSettings_button danger"
|
||||
onClick={this._onDeactivateAccountClicked}>Deactivate my account
|
||||
</button>
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
</div>;
|
||||
},
|
||||
|
@ -576,10 +638,10 @@ module.exports = React.createClass({
|
|||
// bind() the invited rooms so any new invites that may come in as this button is clicked
|
||||
// don't inadvertently get rejected as well.
|
||||
reject = (
|
||||
<button className="mx_UserSettings_button danger"
|
||||
<AccessibleButton className="mx_UserSettings_button danger"
|
||||
onClick={this._onRejectAllInvitesClicked.bind(this, invitedRooms)}>
|
||||
Reject all {invitedRooms.length} invites
|
||||
</button>
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -747,9 +809,9 @@ module.exports = React.createClass({
|
|||
|
||||
<div className="mx_UserSettings_section">
|
||||
|
||||
<div className="mx_UserSettings_logout mx_UserSettings_button" onClick={this.onLogoutClicked}>
|
||||
<AccessibleButton className="mx_UserSettings_logout mx_UserSettings_button" onClick={this.onLogoutClicked}>
|
||||
Sign out
|
||||
</div>
|
||||
</AccessibleButton>
|
||||
|
||||
{accountJsx}
|
||||
</div>
|
||||
|
|
|
@ -87,10 +87,26 @@ module.exports = React.createClass({
|
|||
this.showErrorDialog("New passwords must match each other.");
|
||||
}
|
||||
else {
|
||||
this.submitPasswordReset(
|
||||
this.state.enteredHomeserverUrl, this.state.enteredIdentityServerUrl,
|
||||
this.state.email, this.state.password
|
||||
);
|
||||
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
Modal.createDialog(QuestionDialog, {
|
||||
title: "Warning",
|
||||
description:
|
||||
<div>
|
||||
Resetting password will currently reset any end-to-end encryption keys on all devices,
|
||||
making encrypted chat history unreadable.
|
||||
In future this <a href="https://github.com/vector-im/riot-web/issues/2671">may be improved</a>,
|
||||
but for now be warned.
|
||||
</div>,
|
||||
button: "Continue",
|
||||
onFinished: (confirmed) => {
|
||||
if (confirmed) {
|
||||
this.submitPasswordReset(
|
||||
this.state.enteredHomeserverUrl, this.state.enteredIdentityServerUrl,
|
||||
this.state.email, this.state.password
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue