Merge branch 'develop' into better-spinners

This commit is contained in:
Robin Townsend 2021-05-16 07:47:34 -04:00
commit 74cc00b319
313 changed files with 9672 additions and 3902 deletions

View file

@ -32,6 +32,7 @@ export default class ActionButton extends React.Component {
label: PropTypes.string.isRequired,
iconPath: PropTypes.string,
className: PropTypes.string,
children: PropTypes.node,
};
static defaultProps = {
@ -70,8 +71,8 @@ export default class ActionButton extends React.Component {
}
const icon = this.props.iconPath ?
(<TintableSvg src={this.props.iconPath} width={this.props.size} height={this.props.size} />) :
undefined;
(<TintableSvg src={this.props.iconPath} width={this.props.size} height={this.props.size} />) :
undefined;
const classNames = ["mx_RoleButton"];
if (this.props.className) {
@ -79,7 +80,8 @@ export default class ActionButton extends React.Component {
}
return (
<AccessibleButton className={classNames.join(" ")}
<AccessibleButton
className={classNames.join(" ")}
onClick={this._onClick}
onMouseEnter={this._onMouseEnter}
onMouseLeave={this._onMouseLeave}
@ -87,6 +89,7 @@ export default class ActionButton extends React.Component {
>
{ icon }
{ tooltip }
{ this.props.children }
</AccessibleButton>
);
}

View file

@ -109,7 +109,7 @@ export default class AppTile extends React.Component {
const childContentProtocol = u.protocol;
if (parentContentProtocol === 'https:' && childContentProtocol !== 'https:') {
console.warn("Refusing to load mixed-content app:",
parentContentProtocol, childContentProtocol, window.location, this.props.app.url);
parentContentProtocol, childContentProtocol, window.location, this.props.app.url);
return true;
}
return false;

View file

@ -65,12 +65,18 @@ export class EditableItem extends React.Component {
<span className="mx_EditableItem_promptText">
{_t("Are you sure?")}
</span>
<AccessibleButton onClick={this._onActuallyRemove} kind="primary_sm"
className="mx_EditableItem_confirmBtn">
<AccessibleButton
onClick={this._onActuallyRemove}
kind="primary_sm"
className="mx_EditableItem_confirmBtn"
>
{_t("Yes")}
</AccessibleButton>
<AccessibleButton onClick={this._onDontRemove} kind="danger_sm"
className="mx_EditableItem_confirmBtn">
<AccessibleButton
onClick={this._onDontRemove}
kind="danger_sm"
className="mx_EditableItem_confirmBtn"
>
{_t("No")}
</AccessibleButton>
</div>
@ -121,11 +127,15 @@ export default class EditableItemList extends React.Component {
_renderNewItemField() {
return (
<form onSubmit={this._onItemAdded} autoComplete="off"
noValidate={true} className="mx_EditableItemList_newItem">
<form
onSubmit={this._onItemAdded}
autoComplete="off"
noValidate={true}
className="mx_EditableItemList_newItem"
>
<Field label={this.props.placeholder} type="text"
autoComplete="off" value={this.props.newItem || ""} onChange={this._onNewItemChanged}
list={this.props.suggestionsListId} />
autoComplete="off" value={this.props.newItem || ""} onChange={this._onNewItemChanged}
list={this.props.suggestionsListId} />
<AccessibleButton onClick={this._onItemAdded} kind="primary" type="submit" disabled={!this.props.newItem}>
{_t("Add")}
</AccessibleButton>

View file

@ -221,13 +221,15 @@ export default class EditableText extends React.Component {
</div>;
} else {
// show the content editable div, but manually manage its contents as react and contentEditable don't play nice together
editableEl = <div ref={this._editable_div}
contentEditable={true}
className={className}
onKeyDown={this.onKeyDown}
onKeyUp={this.onKeyUp}
onFocus={this.onFocus}
onBlur={this.onBlur} />;
editableEl = <div
ref={this._editable_div}
contentEditable={true}
className={className}
onKeyDown={this.onKeyDown}
onKeyUp={this.onKeyUp}
onFocus={this.onFocus}
onBlur={this.onBlur}
/>;
}
return editableEl;

View file

@ -108,23 +108,20 @@ export default class ImageView extends React.Component<IProps, IState> {
window.addEventListener("resize", this.calculateZoom);
// After the image loads for the first time we want to calculate the zoom
this.image.current.addEventListener("load", this.calculateZoom);
// Try to precalculate the zoom from width and height props
this.calculateZoom();
}
componentWillUnmount() {
this.focusLock.current.removeEventListener('wheel', this.onWheel);
window.removeEventListener("resize", this.calculateZoom);
this.image.current.removeEventListener("load", this.calculateZoom);
}
private calculateZoom = () => {
const image = this.image.current;
const imageWrapper = this.imageWrapper.current;
const width = this.props.width || image.naturalWidth;
const height = this.props.height || image.naturalHeight;
const zoomX = imageWrapper.clientWidth / width;
const zoomY = imageWrapper.clientHeight / height;
const zoomX = imageWrapper.clientWidth / image.naturalWidth;
const zoomY = imageWrapper.clientHeight / image.naturalHeight;
// If the image is smaller in both dimensions set its the zoom to 1 to
// display it in its original size
@ -210,6 +207,7 @@ export default class ImageView extends React.Component<IProps, IState> {
a.href = this.props.src;
a.download = this.props.name;
a.target = "_blank";
a.rel = "noreferrer noopener";
a.click();
};
@ -445,16 +443,16 @@ export default class ImageView extends React.Component<IProps, IState> {
<div className="mx_ImageView_panel">
{info}
<div className="mx_ImageView_toolbar">
<AccessibleTooltipButton
className="mx_ImageView_button mx_ImageView_button_rotateCW"
title={_t("Rotate Right")}
onClick={this.onRotateClockwiseClick}>
</AccessibleTooltipButton>
<AccessibleTooltipButton
className="mx_ImageView_button mx_ImageView_button_rotateCCW"
title={_t("Rotate Left")}
onClick={ this.onRotateCounterClockwiseClick }>
</AccessibleTooltipButton>
<AccessibleTooltipButton
className="mx_ImageView_button mx_ImageView_button_rotateCW"
title={_t("Rotate Right")}
onClick={this.onRotateClockwiseClick}>
</AccessibleTooltipButton>
{zoomOutButton}
{zoomInButton}
<AccessibleTooltipButton

View file

@ -46,8 +46,12 @@ export default class LabelledToggleSwitch extends React.Component {
// This is a minimal version of a SettingsFlag
let firstPart = <span className="mx_SettingsFlag_label">{this.props.label}</span>;
let secondPart = <ToggleSwitch checked={this.props.value} disabled={this.props.disabled}
onChange={this.props.onChange} aria-label={this.props.label} />;
let secondPart = <ToggleSwitch
checked={this.props.value}
disabled={this.props.disabled}
onChange={this.props.onChange}
aria-label={this.props.label}
/>;
if (this.props.toggleInFront) {
const temp = firstPart;

View file

@ -60,10 +60,10 @@ export default class LanguageDropdown extends React.Component {
// doesn't know this, therefore we do this.
const language = SettingsStore.getValue("language", null, /*excludeDefault:*/true);
if (language) {
this.props.onOptionChange(language);
this.props.onOptionChange(language);
} else {
const language = languageHandler.normalizeLanguageKey(languageHandler.getLanguageFromBrowser());
this.props.onOptionChange(language);
const language = languageHandler.normalizeLanguageKey(languageHandler.getLanguageFromBrowser());
this.props.onOptionChange(language);
}
}
}

View file

@ -225,19 +225,19 @@ class Pill extends React.Component {
}
break;
case Pill.TYPE_USER_MENTION: {
// If this user is not a member of this room, default to the empty member
const member = this.state.member;
if (member) {
userId = member.userId;
member.rawDisplayName = member.rawDisplayName || '';
linkText = member.rawDisplayName;
if (this.props.shouldShowPillAvatar) {
avatar = <MemberAvatar member={member} width={16} height={16} aria-hidden="true" />;
}
pillClass = 'mx_UserPill';
href = null;
onClick = this.onUserPillClicked;
// If this user is not a member of this room, default to the empty member
const member = this.state.member;
if (member) {
userId = member.userId;
member.rawDisplayName = member.rawDisplayName || '';
linkText = member.rawDisplayName;
if (this.props.shouldShowPillAvatar) {
avatar = <MemberAvatar member={member} width={16} height={16} aria-hidden="true" />;
}
pillClass = 'mx_UserPill';
href = null;
onClick = this.onUserPillClicked;
}
}
break;
case Pill.TYPE_ROOM_MENTION: {

View file

@ -135,9 +135,13 @@ export default class PowerSelector extends React.Component {
if (this.state.custom) {
picker = (
<Field type="number"
label={label} max={this.props.maxValue}
onBlur={this.onCustomBlur} onKeyDown={this.onCustomKeyDown} onChange={this.onCustomChange}
value={String(this.state.customValue)} disabled={this.props.disabled} />
label={label} max={this.props.maxValue}
onBlur={this.onCustomBlur}
onKeyDown={this.onCustomKeyDown}
onChange={this.onCustomChange}
value={String(this.state.customValue)}
disabled={this.props.disabled}
/>
);
} else {
// Each level must have a definition in this.state.levelRoleMap
@ -154,8 +158,9 @@ export default class PowerSelector extends React.Component {
picker = (
<Field element="select"
label={label} onChange={this.onSelectChange}
value={String(this.state.selectValue)} disabled={this.props.disabled}>
label={label} onChange={this.onSelectChange}
value={String(this.state.selectValue)} disabled={this.props.disabled}
>
{options}
</Field>
);

View file

@ -46,17 +46,18 @@ export default class RoomAliasField extends React.PureComponent {
const domain = (<span title={aliasPostfix}>{aliasPostfix}</span>);
const maxlength = 255 - this.props.domain.length - 2; // 2 for # and :
return (
<Field
label={_t("Room address")}
className="mx_RoomAliasField"
prefixComponent={poundSign}
postfixComponent={domain}
ref={ref => this._fieldRef = ref}
onValidate={this._onValidate}
placeholder={_t("e.g. my-room")}
onChange={this._onChange}
value={this.props.value.substring(1, this.props.value.length - this.props.domain.length - 1)}
maxLength={maxlength} />
<Field
label={_t("Room address")}
className="mx_RoomAliasField"
prefixComponent={poundSign}
postfixComponent={domain}
ref={ref => this._fieldRef = ref}
onValidate={this._onValidate}
placeholder={_t("e.g. my-room")}
onChange={this._onChange}
value={this.props.value.substring(1, this.props.value.length - this.props.domain.length - 1)}
maxLength={maxlength}
/>
);
}

View file

@ -1,5 +1,5 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Copyright 2020-2021 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.
@ -67,7 +67,7 @@ const ServerPicker = ({ title, dialogTitle, serverConfig, onServerConfigChange }
</AccessibleButton>;
}
let serverName = serverConfig.isNameResolvable ? serverConfig.hsName : serverConfig.hsUrl;
let serverName: React.ReactNode = serverConfig.isNameResolvable ? serverConfig.hsName : serverConfig.hsUrl;
if (serverConfig.hsNameIsDifferent) {
serverName = <TextWithTooltip class="mx_Login_underlinedServerName" tooltip={serverConfig.hsUrl}>
{serverConfig.hsName}

View file

@ -59,13 +59,13 @@ class TintableSvg extends React.Component {
render() {
return (
<object className={"mx_TintableSvg " + (this.props.className ? this.props.className : "")}
type="image/svg+xml"
data={this.props.src}
width={this.props.width}
height={this.props.height}
onLoad={this.onLoad}
tabIndex="-1"
/>
type="image/svg+xml"
data={this.props.src}
width={this.props.width}
height={this.props.height}
onLoad={this.onLoad}
tabIndex="-1"
/>
);
}
}