Merge branch 'develop' into bwindels/bacat-scrolling
This commit is contained in:
commit
494779393f
42 changed files with 860 additions and 212 deletions
|
@ -70,6 +70,11 @@ module.exports = React.createClass({
|
|||
fieldErrors: {},
|
||||
// The ISO2 country code selected in the phone number entry
|
||||
phoneCountry: this.props.defaultPhoneCountry,
|
||||
username: "",
|
||||
email: "",
|
||||
phoneNumber: "",
|
||||
password: "",
|
||||
passwordConfirm: "",
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -89,7 +94,7 @@ module.exports = React.createClass({
|
|||
|
||||
const self = this;
|
||||
if (this.allFieldsValid()) {
|
||||
if (this.refs.email.value == '') {
|
||||
if (this.state.email == '') {
|
||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
Modal.createTrackedDialog('If you don\'t specify an email address...', '', QuestionDialog, {
|
||||
title: _t("Warning!"),
|
||||
|
@ -112,13 +117,13 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_doSubmit: function(ev) {
|
||||
const email = this.refs.email.value.trim();
|
||||
const email = this.state.email.trim();
|
||||
const promise = this.props.onRegisterClick({
|
||||
username: this.refs.username.value.trim(),
|
||||
password: this.refs.password.value.trim(),
|
||||
username: this.state.username.trim(),
|
||||
password: this.state.password.trim(),
|
||||
email: email,
|
||||
phoneCountry: this.state.phoneCountry,
|
||||
phoneNumber: this.refs.phoneNumber ? this.refs.phoneNumber.value.trim() : '',
|
||||
phoneNumber: this.state.phoneNumber,
|
||||
});
|
||||
|
||||
if (promise) {
|
||||
|
@ -143,13 +148,13 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
validateField: function(fieldID, eventType) {
|
||||
const pwd1 = this.refs.password.value.trim();
|
||||
const pwd2 = this.refs.passwordConfirm.value.trim();
|
||||
const pwd1 = this.state.password.trim();
|
||||
const pwd2 = this.state.passwordConfirm.trim();
|
||||
const allowEmpty = eventType === "blur";
|
||||
|
||||
switch (fieldID) {
|
||||
case FIELD_EMAIL: {
|
||||
const email = this.refs.email.value;
|
||||
const email = this.state.email;
|
||||
const emailValid = email === '' || Email.looksValid(email);
|
||||
if (this._authStepIsRequired('m.login.email.identity') && (!emailValid || email === '')) {
|
||||
this.markFieldValid(fieldID, false, "RegistrationForm.ERR_MISSING_EMAIL");
|
||||
|
@ -157,7 +162,7 @@ module.exports = React.createClass({
|
|||
break;
|
||||
}
|
||||
case FIELD_PHONE_NUMBER: {
|
||||
const phoneNumber = this.refs.phoneNumber ? this.refs.phoneNumber.value : '';
|
||||
const phoneNumber = this.state.phoneNumber;
|
||||
const phoneNumberValid = phoneNumber === '' || phoneNumberLooksValid(phoneNumber);
|
||||
if (this._authStepIsRequired('m.login.msisdn') && (!phoneNumberValid || phoneNumber === '')) {
|
||||
this.markFieldValid(fieldID, false, "RegistrationForm.ERR_MISSING_PHONE_NUMBER");
|
||||
|
@ -165,7 +170,7 @@ module.exports = React.createClass({
|
|||
break;
|
||||
}
|
||||
case FIELD_USERNAME: {
|
||||
const username = this.refs.username.value.trim();
|
||||
const username = this.state.username;
|
||||
if (allowEmpty && username === '') {
|
||||
this.markFieldValid(fieldID, true);
|
||||
} else if (!SAFE_LOCALPART_REGEX.test(username)) {
|
||||
|
@ -230,21 +235,6 @@ module.exports = React.createClass({
|
|||
this.props.onValidationChange(fieldErrors);
|
||||
},
|
||||
|
||||
fieldElementById(fieldID) {
|
||||
switch (fieldID) {
|
||||
case FIELD_EMAIL:
|
||||
return this.refs.email;
|
||||
case FIELD_PHONE_NUMBER:
|
||||
return this.refs.phoneNumber;
|
||||
case FIELD_USERNAME:
|
||||
return this.refs.username;
|
||||
case FIELD_PASSWORD:
|
||||
return this.refs.password;
|
||||
case FIELD_PASSWORD_CONFIRM:
|
||||
return this.refs.passwordConfirm;
|
||||
}
|
||||
},
|
||||
|
||||
_classForField: function(fieldID, ...baseClasses) {
|
||||
let cls = baseClasses.join(' ');
|
||||
if (this.state.fieldErrors[fieldID]) {
|
||||
|
@ -258,14 +248,32 @@ module.exports = React.createClass({
|
|||
this.validateField(FIELD_EMAIL, ev.type);
|
||||
},
|
||||
|
||||
onEmailChange(ev) {
|
||||
this.setState({
|
||||
email: ev.target.value,
|
||||
});
|
||||
},
|
||||
|
||||
onPasswordBlur(ev) {
|
||||
this.validateField(FIELD_PASSWORD, ev.type);
|
||||
},
|
||||
|
||||
onPasswordChange(ev) {
|
||||
this.setState({
|
||||
password: ev.target.value,
|
||||
});
|
||||
},
|
||||
|
||||
onPasswordConfirmBlur(ev) {
|
||||
this.validateField(FIELD_PASSWORD_CONFIRM, ev.type);
|
||||
},
|
||||
|
||||
onPasswordConfirmChange(ev) {
|
||||
this.setState({
|
||||
passwordConfirm: ev.target.value,
|
||||
});
|
||||
},
|
||||
|
||||
onPhoneCountryChange(newVal) {
|
||||
this.setState({
|
||||
phoneCountry: newVal.iso2,
|
||||
|
@ -277,10 +285,22 @@ module.exports = React.createClass({
|
|||
this.validateField(FIELD_PHONE_NUMBER, ev.type);
|
||||
},
|
||||
|
||||
onPhoneNumberChange(ev) {
|
||||
this.setState({
|
||||
phoneNumber: ev.target.value,
|
||||
});
|
||||
},
|
||||
|
||||
onUsernameBlur(ev) {
|
||||
this.validateField(FIELD_USERNAME, ev.type);
|
||||
},
|
||||
|
||||
onUsernameChange(ev) {
|
||||
this.setState({
|
||||
username: ev.target.value,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* A step is required if all flows include that step.
|
||||
*
|
||||
|
@ -343,12 +363,12 @@ module.exports = React.createClass({
|
|||
<Field
|
||||
className={this._classForField(FIELD_EMAIL)}
|
||||
id="mx_RegistrationForm_email"
|
||||
ref="email"
|
||||
type="text"
|
||||
label={emailPlaceholder}
|
||||
defaultValue={this.props.defaultEmail}
|
||||
value={this.state.email}
|
||||
onBlur={this.onEmailBlur}
|
||||
onChange={this.onEmailChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -370,13 +390,13 @@ module.exports = React.createClass({
|
|||
phoneSection = <Field
|
||||
className={this._classForField(FIELD_PHONE_NUMBER)}
|
||||
id="mx_RegistrationForm_phoneNumber"
|
||||
ref="phoneNumber"
|
||||
type="text"
|
||||
label={phoneLabel}
|
||||
defaultValue={this.props.defaultPhoneNumber}
|
||||
value={this.state.phoneNumber}
|
||||
prefix={phoneCountry}
|
||||
onBlur={this.onPhoneNumberBlur}
|
||||
onChange={this.onPhoneNumberChange}
|
||||
/>;
|
||||
}
|
||||
|
||||
|
@ -395,32 +415,35 @@ module.exports = React.createClass({
|
|||
<Field
|
||||
className={this._classForField(FIELD_USERNAME)}
|
||||
id="mx_RegistrationForm_username"
|
||||
ref="username"
|
||||
type="text"
|
||||
autoFocus={true}
|
||||
label={_t("Username")}
|
||||
defaultValue={this.props.defaultUsername}
|
||||
value={this.state.username}
|
||||
onBlur={this.onUsernameBlur}
|
||||
onChange={this.onUsernameChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="mx_AuthBody_fieldRow">
|
||||
<Field
|
||||
className={this._classForField(FIELD_PASSWORD)}
|
||||
id="mx_RegistrationForm_password"
|
||||
ref="password"
|
||||
type="password"
|
||||
label={_t("Password")}
|
||||
defaultValue={this.props.defaultPassword}
|
||||
value={this.state.password}
|
||||
onBlur={this.onPasswordBlur}
|
||||
onChange={this.onPasswordChange}
|
||||
/>
|
||||
<Field
|
||||
className={this._classForField(FIELD_PASSWORD_CONFIRM)}
|
||||
id="mx_RegistrationForm_passwordConfirm"
|
||||
ref="passwordConfirm"
|
||||
type="password"
|
||||
label={_t("Confirm")}
|
||||
defaultValue={this.props.defaultPassword}
|
||||
value={this.state.passwordConfirm}
|
||||
onBlur={this.onPasswordConfirmBlur}
|
||||
onChange={this.onPasswordConfirmChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="mx_AuthBody_fieldRow">
|
||||
|
|
|
@ -21,7 +21,7 @@ import sdk from '../../../index';
|
|||
import Analytics from '../../../Analytics';
|
||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import * as Lifecycle from '../../../Lifecycle';
|
||||
import Velocity from 'velocity-vector';
|
||||
import Velocity from 'velocity-animate';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
export default class DeactivateAccountDialog extends React.Component {
|
||||
|
|
|
@ -336,9 +336,14 @@ export default class AppTile extends React.Component {
|
|||
* Called when widget iframe has finished loading
|
||||
*/
|
||||
_onLoaded() {
|
||||
if (!ActiveWidgetStore.getWidgetMessaging(this.props.id)) {
|
||||
this._setupWidgetMessaging();
|
||||
// Destroy the old widget messaging before starting it back up again. Some widgets
|
||||
// have startup routines that run when they are loaded, so we just need to reinitialize
|
||||
// the messaging for them.
|
||||
if (ActiveWidgetStore.getWidgetMessaging(this.props.id)) {
|
||||
ActiveWidgetStore.delWidgetMessaging(this.props.id);
|
||||
}
|
||||
this._setupWidgetMessaging();
|
||||
|
||||
ActiveWidgetStore.setRoomId(this.props.id, this.props.room.roomId);
|
||||
this.setState({loading: false});
|
||||
}
|
||||
|
|
|
@ -53,12 +53,6 @@ export default class Field extends React.PureComponent {
|
|||
};
|
||||
}
|
||||
|
||||
/* TODO: Remove this once `RegistrationForm` no longer uses refs */
|
||||
get value() {
|
||||
if (!this.refs.fieldInput) return null;
|
||||
return this.refs.fieldInput.value;
|
||||
}
|
||||
|
||||
onChange = (ev) => {
|
||||
if (this.props.onValidate) {
|
||||
const result = this.props.onValidate(ev.target.value);
|
||||
|
|
|
@ -431,7 +431,7 @@ module.exports = React.createClass({
|
|||
|
||||
const stripReply = ReplyThread.getParentEventId(mxEvent);
|
||||
let body = HtmlUtils.bodyToHtml(content, this.props.highlights, {
|
||||
disableBigEmoji: !SettingsStore.getValue('TextualBody.enableBigEmoji'),
|
||||
disableBigEmoji: content.msgtype === "m.emote" || !SettingsStore.getValue('TextualBody.enableBigEmoji'),
|
||||
// Part of Replies fallback support
|
||||
stripReplyFallback: stripReply,
|
||||
});
|
||||
|
|
|
@ -34,14 +34,20 @@ export default class RoomProfileSettings extends React.Component {
|
|||
const client = MatrixClientPeg.get();
|
||||
const room = client.getRoom(props.roomId);
|
||||
if (!room) throw new Error("Expected a room for ID: ", props.roomId);
|
||||
|
||||
const avatarEvent = room.currentState.getStateEvents("m.room.avatar", "");
|
||||
let avatarUrl = avatarEvent && avatarEvent.getContent() ? avatarEvent.getContent()["url"] : null;
|
||||
if (avatarUrl) avatarUrl = client.mxcUrlToHttp(avatarUrl, 96, 96, 'crop', false);
|
||||
|
||||
const topicEvent = room.currentState.getStateEvents("m.room.topic", "");
|
||||
const topic = topicEvent && topicEvent.getContent() ? topicEvent.getContent()['topic'] : '';
|
||||
|
||||
const nameEvent = room.currentState.getStateEvents('m.room.name', '');
|
||||
const name = nameEvent && nameEvent.getContent() ? nameEvent.getContent()['name'] : '';
|
||||
|
||||
this.state = {
|
||||
originalDisplayName: room.name,
|
||||
displayName: room.name,
|
||||
originalDisplayName: name,
|
||||
displayName: name,
|
||||
originalAvatarUrl: avatarUrl,
|
||||
avatarUrl: avatarUrl,
|
||||
avatarFile: null,
|
||||
|
|
|
@ -37,41 +37,43 @@ module.exports = React.createClass({
|
|||
render: function() {
|
||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||
|
||||
let upgradeText = (
|
||||
<div>
|
||||
return (
|
||||
<div className="mx_RoomUpgradeWarningBar">
|
||||
<div className="mx_RoomUpgradeWarningBar_header">
|
||||
{_t(
|
||||
"This room is running room version <roomVersion />, which this homeserver has " +
|
||||
"marked as <i>unstable</i>.",
|
||||
{},
|
||||
{
|
||||
"roomVersion": () => <code>{this.props.room.getVersion()}</code>,
|
||||
"i": (sub) => <i>{sub}</i>,
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
<div className="mx_RoomUpgradeWarningBar_body">
|
||||
{_t("This room is using an unstable room version. If you aren't expecting " +
|
||||
"this, please upgrade the room.")}
|
||||
<p>
|
||||
{_t(
|
||||
"Upgrading this room will shut down the current instance of the room and create " +
|
||||
"an upgraded room with the same name.",
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members " +
|
||||
"to the new version of the room.</i> We'll post a link to the new room in the old " +
|
||||
"version of the room - room members will have to click this link to join the new room.",
|
||||
{}, {
|
||||
"b": (sub) => <b>{sub}</b>,
|
||||
"i": (sub) => <i>{sub}</i>,
|
||||
},
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<p className="mx_RoomUpgradeWarningBar_upgradelink">
|
||||
<AccessibleButton onClick={this.onUpgradeClick}>
|
||||
{_t("Click here to upgrade to the latest room version.")}
|
||||
{_t("Upgrade this room to the recommended room version")}
|
||||
</AccessibleButton>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
if (this.props.recommendation.urgent) {
|
||||
upgradeText = (
|
||||
<div>
|
||||
<div className="mx_RoomUpgradeWarningBar_header">
|
||||
{_t("There is a known vulnerability affecting this room.")}
|
||||
</div>
|
||||
<div className="mx_RoomUpgradeWarningBar_body">
|
||||
{_t("This room version is vulnerable to malicious modification of room state.")}
|
||||
</div>
|
||||
<p className="mx_RoomUpgradeWarningBar_upgradelink">
|
||||
<AccessibleButton onClick={this.onUpgradeClick}>
|
||||
{_t("Click here to upgrade to the latest room version and ensure room integrity " +
|
||||
"is protected.")}
|
||||
</AccessibleButton>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_RoomUpgradeWarningBar">
|
||||
{upgradeText}
|
||||
<div className="mx_RoomUpgradeWarningBar_small">
|
||||
{_t("Only room administrators will see this warning")}
|
||||
</div>
|
||||
|
|
|
@ -25,6 +25,7 @@ import dis from '../../../dispatcher';
|
|||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import WidgetUtils from '../../../utils/WidgetUtils';
|
||||
import ActiveWidgetStore from '../../../stores/ActiveWidgetStore';
|
||||
import PersistedElement from "../elements/PersistedElement";
|
||||
|
||||
const widgetType = 'm.stickerpicker';
|
||||
|
||||
|
@ -32,6 +33,9 @@ const widgetType = 'm.stickerpicker';
|
|||
// above it, so it needs a greater z-index than the ContextMenu
|
||||
const STICKERPICKER_Z_INDEX = 5000;
|
||||
|
||||
// Key to store the widget's AppTile under in PersistedElement
|
||||
const PERSISTED_ELEMENT_KEY = "stickerPicker";
|
||||
|
||||
export default class Stickerpicker extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -126,6 +130,23 @@ export default class Stickerpicker extends React.Component {
|
|||
|
||||
_updateWidget() {
|
||||
const stickerpickerWidget = WidgetUtils.getStickerpickerWidgets()[0];
|
||||
|
||||
const currentWidget = this.state.stickerpickerWidget;
|
||||
let currentUrl = null;
|
||||
if (currentWidget && currentWidget.content && currentWidget.content.url) {
|
||||
currentUrl = currentWidget.content.url;
|
||||
}
|
||||
|
||||
let newUrl = null;
|
||||
if (stickerpickerWidget && stickerpickerWidget.content && stickerpickerWidget.content.url) {
|
||||
newUrl = stickerpickerWidget.content.url;
|
||||
}
|
||||
|
||||
if (newUrl !== currentUrl) {
|
||||
// Destroy the existing frame so a new one can be created
|
||||
PersistedElement.destroyElement(PERSISTED_ELEMENT_KEY);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
stickerpickerWidget,
|
||||
widgetId: stickerpickerWidget ? stickerpickerWidget.id : null,
|
||||
|
@ -211,7 +232,7 @@ export default class Stickerpicker extends React.Component {
|
|||
width: this.popoverWidth,
|
||||
}}
|
||||
>
|
||||
<PersistedElement persistKey="stickerPicker" style={{zIndex: STICKERPICKER_Z_INDEX}}>
|
||||
<PersistedElement persistKey={PERSISTED_ELEMENT_KEY} style={{zIndex: STICKERPICKER_Z_INDEX}}>
|
||||
<AppTile
|
||||
id={stickerpickerWidget.id}
|
||||
url={stickerpickerWidget.content.url}
|
||||
|
|
|
@ -67,9 +67,22 @@ export default class AdvancedRoomSettingsTab extends React.Component {
|
|||
let roomUpgradeButton;
|
||||
if (this.state.upgradeRecommendation && this.state.upgradeRecommendation.needsUpgrade) {
|
||||
roomUpgradeButton = (
|
||||
<AccessibleButton onClick={this._upgradeRoom} kind='primary'>
|
||||
{_t("Upgrade room to version %(ver)s", {ver: this.state.upgradeRecommendation.version})}
|
||||
</AccessibleButton>
|
||||
<div>
|
||||
<p className='mx_SettingsTab_warningText'>
|
||||
{_t(
|
||||
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members " +
|
||||
"to the new version of the room.</i> We'll post a link to the new room in the old " +
|
||||
"version of the room - room members will have to click this link to join the new room.",
|
||||
{}, {
|
||||
"b": (sub) => <b>{sub}</b>,
|
||||
"i": (sub) => <i>{sub}</i>,
|
||||
},
|
||||
)}
|
||||
</p>
|
||||
<AccessibleButton onClick={this._upgradeRoom} kind='primary'>
|
||||
{_t("Upgrade this room to the recommended room version")}
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue