Merge branch 'develop' into 19245-improve-styling-of-search-initialization-errors
This commit is contained in:
commit
401e124df6
90 changed files with 562 additions and 398 deletions
|
@ -96,7 +96,7 @@ export default function AccessibleButton({
|
|||
// that might receive focus as a result of the AccessibleButtonClick action
|
||||
// It's because we are using html buttons at a few places e.g. inside dialogs
|
||||
// And divs which we report as role button to assistive technologies.
|
||||
// Browsers handle space and enter keypresses differently and we are only adjusting to the
|
||||
// Browsers handle space and enter key presses differently and we are only adjusting to the
|
||||
// inconsistencies here
|
||||
newProps.onKeyDown = (e) => {
|
||||
const action = getKeyBindingsManager().getAccessibilityAction(e);
|
||||
|
|
|
@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { SyntheticEvent } from 'react';
|
||||
import React, { SyntheticEvent, FocusEvent } from 'react';
|
||||
|
||||
import AccessibleButton from "./AccessibleButton";
|
||||
import Tooltip, { Alignment } from './Tooltip';
|
||||
|
@ -68,6 +68,12 @@ export default class AccessibleTooltipButton extends React.PureComponent<IProps,
|
|||
this.props.onHideTooltip?.(ev);
|
||||
};
|
||||
|
||||
private onFocus = (ev: FocusEvent) => {
|
||||
// We only show the tooltip if focus arrived here from some other
|
||||
// element, to avoid leaving tooltips hanging around when a modal closes
|
||||
if (ev.relatedTarget) this.showTooltip();
|
||||
};
|
||||
|
||||
render() {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { title, tooltip, children, tooltipClassName, forceHide, yOffset, alignment, onHideTooltip,
|
||||
|
@ -84,7 +90,7 @@ export default class AccessibleTooltipButton extends React.PureComponent<IProps,
|
|||
{...props}
|
||||
onMouseOver={this.showTooltip}
|
||||
onMouseLeave={this.hideTooltip}
|
||||
onFocus={this.showTooltip}
|
||||
onFocus={this.onFocus}
|
||||
onBlur={this.hideTooltip}
|
||||
aria-label={title}
|
||||
>
|
||||
|
|
|
@ -57,7 +57,7 @@ interface IProps {
|
|||
// which bypasses permission prompts as it was added explicitly by that user
|
||||
room?: Room;
|
||||
threadId?: string | null;
|
||||
// Specifying 'fullWidth' as true will render the app tile to fill the width of the app drawer continer.
|
||||
// Specifying 'fullWidth' as true will render the app tile to fill the width of the app drawer container.
|
||||
// This should be set to true when there is only one widget in the app drawer, otherwise it should be false.
|
||||
fullWidth?: boolean;
|
||||
// Optional. If set, renders a smaller view of the widget
|
||||
|
@ -288,7 +288,7 @@ export default class AppTile extends React.Component<IProps, IState> {
|
|||
private setupSgListeners() {
|
||||
this.sgWidget.on("preparing", this.onWidgetPreparing);
|
||||
this.sgWidget.on("ready", this.onWidgetReady);
|
||||
// emits when the capabilites have been setup or changed
|
||||
// emits when the capabilities have been set up or changed
|
||||
this.sgWidget.on("capabilitiesNotified", this.onWidgetCapabilitiesNotified);
|
||||
}
|
||||
|
||||
|
@ -543,7 +543,7 @@ export default class AppTile extends React.Component<IProps, IState> {
|
|||
const sandboxFlags = "allow-forms allow-popups allow-popups-to-escape-sandbox " +
|
||||
"allow-same-origin allow-scripts allow-presentation allow-downloads";
|
||||
|
||||
// Additional iframe feature pemissions
|
||||
// Additional iframe feature permissions
|
||||
// (see - https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-permissions-in-cross-origin-iframes and https://wicg.github.io/feature-policy/)
|
||||
const iframeFeatures = "microphone; camera; encrypted-media; autoplay; display-capture; clipboard-write;";
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ export default class ErrorBoundary extends React.PureComponent<{}, IState> {
|
|||
// in their own `console.error` invocation.
|
||||
logger.error(error);
|
||||
logger.error(
|
||||
"The above error occured while React was rendering the following components:",
|
||||
"The above error occurred while React was rendering the following components:",
|
||||
componentStack,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ export default class LanguageDropdown extends React.Component<IProps, IState> {
|
|||
});
|
||||
|
||||
// default value here too, otherwise we need to handle null / undefined
|
||||
// values between mounting and the initial value propgating
|
||||
// values between mounting and the initial value propagating
|
||||
let language = SettingsStore.getValue("language", null, /*excludeDefault:*/true);
|
||||
let value = null;
|
||||
if (language) {
|
||||
|
|
|
@ -14,18 +14,18 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useContext, useRef, useState } from 'react';
|
||||
import { EventType } from 'matrix-js-sdk/src/@types/event';
|
||||
import classNames from 'classnames';
|
||||
import { EventType } from 'matrix-js-sdk/src/@types/event';
|
||||
import React, { useContext, useRef, useState, MouseEvent } from 'react';
|
||||
|
||||
import Analytics from "../../../Analytics";
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import RoomContext from "../../../contexts/RoomContext";
|
||||
import { useTimeout } from "../../../hooks/useTimeout";
|
||||
import { TranslatedString } from '../../../languageHandler';
|
||||
import { chromeFileInputFix } from "../../../utils/BrowserWorkarounds";
|
||||
import AccessibleButton from "./AccessibleButton";
|
||||
import Spinner from "./Spinner";
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import { useTimeout } from "../../../hooks/useTimeout";
|
||||
import Analytics from "../../../Analytics";
|
||||
import { TranslatedString } from '../../../languageHandler';
|
||||
import RoomContext from "../../../contexts/RoomContext";
|
||||
import { chromeFileInputFix } from "../../../utils/BrowserWorkarounds";
|
||||
|
||||
export const AVATAR_SIZE = 52;
|
||||
|
||||
|
@ -34,9 +34,13 @@ interface IProps {
|
|||
noAvatarLabel?: TranslatedString;
|
||||
hasAvatarLabel?: TranslatedString;
|
||||
setAvatarUrl(url: string): Promise<unknown>;
|
||||
isUserAvatar?: boolean;
|
||||
onClick?(ev: MouseEvent<HTMLInputElement>): void;
|
||||
}
|
||||
|
||||
const MiniAvatarUploader: React.FC<IProps> = ({ hasAvatar, hasAvatarLabel, noAvatarLabel, setAvatarUrl, children }) => {
|
||||
const MiniAvatarUploader: React.FC<IProps> = ({
|
||||
hasAvatar, hasAvatarLabel, noAvatarLabel, setAvatarUrl, isUserAvatar, children, onClick,
|
||||
}) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [hover, setHover] = useState(false);
|
||||
|
@ -54,7 +58,7 @@ const MiniAvatarUploader: React.FC<IProps> = ({ hasAvatar, hasAvatarLabel, noAva
|
|||
const label = (hasAvatar || busy) ? hasAvatarLabel : noAvatarLabel;
|
||||
|
||||
const { room } = useContext(RoomContext);
|
||||
const canSetAvatar = room?.currentState.maySendStateEvent(EventType.RoomAvatar, cli.getUserId());
|
||||
const canSetAvatar = isUserAvatar || room?.currentState?.maySendStateEvent(EventType.RoomAvatar, cli.getUserId());
|
||||
if (!canSetAvatar) return <React.Fragment>{ children }</React.Fragment>;
|
||||
|
||||
const visible = !!label && (hover || show);
|
||||
|
@ -63,7 +67,10 @@ const MiniAvatarUploader: React.FC<IProps> = ({ hasAvatar, hasAvatarLabel, noAva
|
|||
type="file"
|
||||
ref={uploadRef}
|
||||
className="mx_MiniAvatarUploader_input"
|
||||
onClick={chromeFileInputFix}
|
||||
onClick={(ev) => {
|
||||
chromeFileInputFix(ev);
|
||||
onClick?.(ev);
|
||||
}}
|
||||
onChange={async (ev) => {
|
||||
if (!ev.target.files?.length) return;
|
||||
setBusy(true);
|
||||
|
|
|
@ -167,7 +167,7 @@ export default class ReplyChain extends React.Component<IProps, IState> {
|
|||
await this.matrixClient.getEventTimeline(this.room.getUnfilteredTimelineSet(), eventId);
|
||||
} catch (e) {
|
||||
// if it fails catch the error and return early, there's no point trying to find the event in this case.
|
||||
// Return null as it is falsey and thus should be treated as an error (as the event cannot be resolved).
|
||||
// Return null as it is falsy and thus should be treated as an error (as the event cannot be resolved).
|
||||
return null;
|
||||
}
|
||||
return this.room.findEventById(eventId);
|
||||
|
|
|
@ -99,7 +99,7 @@ export default class SpellCheckLanguagesDropdown extends React.Component<SpellCh
|
|||
});
|
||||
|
||||
// default value here too, otherwise we need to handle null / undefined;
|
||||
// values between mounting and the initial value propgating
|
||||
// values between mounting and the initial value propagating
|
||||
let language = SettingsStore.getValue("language", null, /*excludeDefault:*/true);
|
||||
let value = null;
|
||||
if (language) {
|
||||
|
|
|
@ -52,7 +52,7 @@ export default class TruncatedList extends React.Component<IProps> {
|
|||
return this.props.getChildren(start, end);
|
||||
} else {
|
||||
// XXX: I'm not sure why anything would pass null into this, it seems
|
||||
// like a bizzare case to handle, but I'm preserving the behaviour.
|
||||
// like a bizarre case to handle, but I'm preserving the behaviour.
|
||||
// (see commit 38d5c7d5c5d5a34dc16ef5d46278315f5c57f542)
|
||||
return React.Children.toArray(this.props.children).filter((c) => {
|
||||
return c != null;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue