Merge branch 'develop' into travis/feature/wellknown2

This commit is contained in:
Travis Ralston 2019-05-22 23:05:54 -06:00
commit 14dc4b47fa
82 changed files with 1104 additions and 770 deletions

View file

@ -129,7 +129,7 @@ export default class IndicatorScrollbar extends React.Component {
// the harshness of the scroll behaviour. Should be a value between 0 and 1.
const yRetention = 1.0;
if (Math.abs(e.deltaX) < xyThreshold) {
if (Math.abs(e.deltaX) <= xyThreshold) {
// noinspection JSSuspiciousNameCombination
this._scrollElement.scrollLeft += e.deltaY * yRetention;
}

View file

@ -1,5 +1,6 @@
/*
Copyright 2017 Vector Creations Ltd.
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -60,7 +61,7 @@ export default React.createClass({
inputs: PropTypes.object,
// As js-sdk interactive-auth
makeRegistrationUrl: PropTypes.func,
requestEmailToken: PropTypes.func,
sessionId: PropTypes.string,
clientSecret: PropTypes.string,
emailSid: PropTypes.string,
@ -96,6 +97,7 @@ export default React.createClass({
sessionId: this.props.sessionId,
clientSecret: this.props.clientSecret,
emailSid: this.props.emailSid,
requestEmailToken: this.props.requestEmailToken,
});
this._authLogic.attemptAuth().then((result) => {
@ -202,7 +204,6 @@ export default React.createClass({
stageState={this.state.stageState}
fail={this._onAuthStageFailed}
setEmailSid={this._setEmailSid}
makeRegistrationUrl={this.props.makeRegistrationUrl}
showContinue={!this.props.continueIsManaged}
/>
);

View file

@ -24,6 +24,7 @@ import { DragDropContext } from 'react-beautiful-dnd';
import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard';
import PageTypes from '../../PageTypes';
import CallMediaHandler from '../../CallMediaHandler';
import { fixupColorFonts } from '../../utils/FontManager';
import sdk from '../../index';
import dis from '../../dispatcher';
import sessionStore from '../../stores/SessionStore';
@ -118,6 +119,8 @@ const LoggedInView = React.createClass({
this._matrixClient.on("accountData", this.onAccountData);
this._matrixClient.on("sync", this.onSync);
this._matrixClient.on("RoomState.events", this.onRoomStateEvents);
fixupColorFonts();
},
componentDidUpdate(prevProps) {
@ -322,6 +325,18 @@ const LoggedInView = React.createClass({
handled = true;
}
break;
case KeyCode.KEY_I:
// Ideally this would be CTRL+P for "Profile", but that's
// taken by the print dialog. CTRL+I for "Information"
// will have to do.
if (ctrlCmdOnly) {
dis.dispatch({
action: 'toggle_top_left_menu',
});
handled = true;
}
break;
}
if (handled) {

View file

@ -96,6 +96,9 @@ module.exports = React.createClass({
// helper function to access relations for an event
getRelationsForEvent: PropTypes.func,
// whether to show reactions for an event
showReactions: PropTypes.bool,
},
componentWillMount: function() {
@ -541,6 +544,7 @@ module.exports = React.createClass({
last={last}
isSelectedEvent={highlight}
getRelationsForEvent={this.props.getRelationsForEvent}
showReactions={this.props.showReactions}
/>
</li>,
);

View file

@ -1,5 +1,6 @@
/*
Copyright 2016 OpenMarket Ltd
Copyright 2019 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -15,12 +16,9 @@ limitations under the License.
*/
const React = require('react');
const ReactDOM = require("react-dom");
import { _t } from '../../languageHandler';
const Matrix = require("matrix-js-sdk");
const sdk = require('../../index');
const MatrixClientPeg = require("../../MatrixClientPeg");
const dis = require("../../dispatcher");
/*
* Component which shows the global notification list using a TimelinePanel
@ -44,7 +42,7 @@ const NotificationPanel = React.createClass({
manageReadReceipts={false}
manageReadMarkers={false}
timelineSet={timelineSet}
showUrlPreview = {false}
showUrlPreview={false}
tileShape="notif"
empty={_t('You have no visible notifications')}
/>

View file

@ -304,8 +304,6 @@ module.exports = React.createClass({
// return suitable content for the main (text) part of the status bar.
_getContent: function() {
const EmojiText = sdk.getComponent('elements.EmojiText');
if (this._shouldShowConnectionError()) {
return (
<div className="mx_RoomStatusBar_connectionLostBar">

View file

@ -29,6 +29,7 @@ import { Group } from 'matrix-js-sdk';
import PropTypes from 'prop-types';
import RoomTile from "../views/rooms/RoomTile";
import LazyRenderList from "../views/elements/LazyRenderList";
import {_t} from "../../languageHandler";
// turn this on for drop & drag console debugging galore
const debug = false;
@ -42,6 +43,7 @@ const RoomSubList = React.createClass({
list: PropTypes.arrayOf(PropTypes.object).isRequired,
label: PropTypes.string.isRequired,
tagName: PropTypes.string,
addRoomLabel: PropTypes.string,
order: PropTypes.string.isRequired,
@ -232,7 +234,11 @@ const RoomSubList = React.createClass({
let addRoomButton;
if (this.props.onAddRoom) {
addRoomButton = (
<AccessibleButton onClick={ this.props.onAddRoom } className="mx_RoomSubList_addRoom" />
<AccessibleButton
onClick={ this.props.onAddRoom }
className="mx_RoomSubList_addRoom"
title={this.props.addRoomLabel || _t("Add room")}
/>
);
}

View file

@ -1832,6 +1832,7 @@ module.exports = React.createClass({
membersLoaded={this.state.membersLoaded}
permalinkCreator={this._getPermalinkCreatorForRoom(this.state.room)}
resizeNotifier={this.props.resizeNotifier}
showReactions={true}
/>);
let topUnreadMessagesBar = null;

View file

@ -106,6 +106,9 @@ const TimelinePanel = React.createClass({
// placeholder text to use if the timeline is empty
empty: PropTypes.string,
// whether to show reactions for an event
showReactions: PropTypes.bool,
},
statics: {
@ -553,6 +556,9 @@ const TimelinePanel = React.createClass({
},
onEventDecrypted: function(ev) {
// Can be null for the notification timeline, etc.
if (!this.props.timelineSet.room) return;
// Need to update as we don't display event tiles for events that
// haven't yet been decrypted. The event will have just been updated
// in place so we just need to re-render.
@ -1261,6 +1267,7 @@ const TimelinePanel = React.createClass({
resizeNotifier={this.props.resizeNotifier}
getRelationsForEvent={this.getRelationsForEvent}
editEvent={this.state.editEvent}
showReactions={this.props.showReactions}
/>
);
},

View file

@ -1,5 +1,6 @@
/*
Copyright 2018 New Vector Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -23,6 +24,8 @@ import BaseAvatar from '../views/avatars/BaseAvatar';
import MatrixClientPeg from '../../MatrixClientPeg';
import Avatar from '../../Avatar';
import { _t } from '../../languageHandler';
import dis from "../../dispatcher";
import {focusCapturedRef} from "../../utils/Accessibility";
const AVATAR_SIZE = 28;
@ -37,6 +40,7 @@ export default class TopLeftMenuButton extends React.Component {
super();
this.state = {
menuDisplayed: false,
menuFunctions: null, // should be { close: fn }
profileInfo: null,
};
@ -59,6 +63,8 @@ export default class TopLeftMenuButton extends React.Component {
}
async componentDidMount() {
this._dispatcherRef = dis.register(this.onAction);
try {
const profileInfo = await this._getProfileInfo();
this.setState({profileInfo});
@ -68,6 +74,17 @@ export default class TopLeftMenuButton extends React.Component {
}
}
componentWillUnmount() {
dis.unregister(this._dispatcherRef);
}
onAction = (payload) => {
// For accessibility
if (payload.action === "toggle_top_left_menu") {
if (this._buttonRef) this._buttonRef.click();
}
};
_getDisplayName() {
if (MatrixClientPeg.get().isGuest()) {
return _t("Guest");
@ -88,7 +105,13 @@ export default class TopLeftMenuButton extends React.Component {
}
return (
<AccessibleButton className="mx_TopLeftMenuButton" onClick={this.onToggleMenu}>
<AccessibleButton
className="mx_TopLeftMenuButton"
role="button"
onClick={this.onToggleMenu}
inputRef={(r) => this._buttonRef = r}
aria-label={_t("Your profile")}
>
<BaseAvatar
idName={MatrixClientPeg.get().getUserId()}
name={name}
@ -98,7 +121,7 @@ export default class TopLeftMenuButton extends React.Component {
resizeMethod="crop"
/>
{ nameElement }
<span className="mx_TopLeftMenuButton_chevron"></span>
<span className="mx_TopLeftMenuButton_chevron" />
</AccessibleButton>
);
}
@ -107,20 +130,26 @@ export default class TopLeftMenuButton extends React.Component {
e.preventDefault();
e.stopPropagation();
if (this.state.menuDisplayed && this.state.menuFunctions) {
this.state.menuFunctions.close();
return;
}
const elementRect = e.currentTarget.getBoundingClientRect();
const x = elementRect.left;
const y = elementRect.top + elementRect.height;
ContextualMenu.createMenu(TopLeftMenu, {
const menuFunctions = ContextualMenu.createMenu(TopLeftMenu, {
chevronFace: "none",
left: x,
top: y,
userId: MatrixClientPeg.get().getUserId(),
displayName: this._getDisplayName(),
containerRef: focusCapturedRef, // Focus the TopLeftMenu on first render
onFinished: () => {
this.setState({ menuDisplayed: false });
this.setState({ menuDisplayed: false, menuFunctions: null });
},
});
this.setState({ menuDisplayed: true });
this.setState({ menuDisplayed: true, menuFunctions });
}
}

View file

@ -2,6 +2,7 @@
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
Copyright 2018, 2019 New Vector Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -187,6 +188,20 @@ module.exports = React.createClass({
});
},
_requestEmailToken: function(emailAddress, clientSecret, sendAttempt, sessionId) {
return this._matrixClient.requestRegisterEmailToken(
emailAddress,
clientSecret,
sendAttempt,
this.props.makeRegistrationUrl({
client_secret: clientSecret,
hs_url: this._matrixClient.getHomeserverUrl(),
is_url: this._matrixClient.getIdentityServerUrl(),
session_id: sessionId,
}),
);
},
_onUIAuthFinished: async function(success, response, extra) {
if (!success) {
let msg = response.message || response.toString();
@ -400,7 +415,7 @@ module.exports = React.createClass({
makeRequest={this._makeRegisterRequest}
onAuthFinished={this._onUIAuthFinished}
inputs={this._getUIAuthInputs()}
makeRegistrationUrl={this.props.makeRegistrationUrl}
requestEmailToken={this._requestEmailToken}
sessionId={this.props.sessionId}
clientSecret={this.props.clientSecret}
emailSid={this.props.idSid}