Merge branch 'develop' into gsouquet/switch-rooms

This commit is contained in:
Germain Souquet 2021-05-26 09:51:27 +01:00
commit c7c6a818f0
89 changed files with 2555 additions and 1232 deletions

View file

@ -17,7 +17,8 @@
import React, { FunctionComponent, useEffect, useRef } from 'react';
import dis from '../../../dispatcher/dispatcher';
import ICanvasEffect from '../../../effects/ICanvasEffect';
import {CHAT_EFFECTS} from '../../../effects'
import { CHAT_EFFECTS } from '../../../effects'
import UIStore, { UI_EVENTS } from "../../../stores/UIStore";
interface IProps {
roomWidth: number;
@ -45,8 +46,8 @@ const EffectsOverlay: FunctionComponent<IProps> = ({ roomWidth }) => {
useEffect(() => {
const resize = () => {
if (canvasRef.current) {
canvasRef.current.height = window.innerHeight;
if (canvasRef.current && canvasRef.current?.height !== UIStore.instance.windowHeight) {
canvasRef.current.height = UIStore.instance.windowHeight;
}
};
const onAction = (payload: { action: string }) => {
@ -58,12 +59,12 @@ const EffectsOverlay: FunctionComponent<IProps> = ({ roomWidth }) => {
}
const dispatcherRef = dis.register(onAction);
const canvas = canvasRef.current;
canvas.height = window.innerHeight;
window.addEventListener('resize', resize, true);
canvas.height = UIStore.instance.windowHeight;
UIStore.instance.on(UI_EVENTS.Resize, resize);
return () => {
dis.unregister(dispatcherRef);
window.removeEventListener('resize', resize);
UIStore.instance.off(UI_EVENTS.Resize, resize);
// eslint-disable-next-line react-hooks/exhaustive-deps
const currentEffects = effectsRef.current; // this is not a react node ref, warning can be safely ignored
for (const effect in currentEffects) {

View file

@ -16,32 +16,31 @@ limitations under the License.
import React from "react";
import {_t} from "../../../languageHandler";
import SettingsStore from "../../../settings/SettingsStore";
import {replaceableComponent} from "../../../utils/replaceableComponent";
interface IProps {
w?: number;
h?: number;
children?: React.ReactNode;
}
@replaceableComponent("views.elements.InlineSpinner")
export default class InlineSpinner extends React.Component {
export default class InlineSpinner extends React.PureComponent<IProps> {
static defaultProps = {
w: 16,
h: 16,
}
render() {
const w = this.props.w || 16;
const h = this.props.h || 16;
const imgClass = this.props.imgClassName || "";
let imageSource;
if (SettingsStore.getValue('feature_new_spinner')) {
imageSource = require("../../../../res/img/spinner.svg");
} else {
imageSource = require("../../../../res/img/spinner.gif");
}
return (
<div className="mx_InlineSpinner">
<img
src={imageSource}
width={w}
height={h}
className={imgClass}
<div
className="mx_InlineSpinner_icon mx_Spinner_icon"
style={{width: this.props.w, height: this.props.h}}
aria-label={_t("Loading...")}
/>
>
{this.props.children}
</div>
</div>
);
}

View file

@ -19,6 +19,7 @@ import {EventType} from 'matrix-js-sdk/src/@types/event';
import classNames from 'classnames';
import AccessibleButton from "./AccessibleButton";
import Spinner from "./Spinner";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import {useTimeout} from "../../../hooks/useTimeout";
import Analytics from "../../../Analytics";
@ -88,6 +89,12 @@ const MiniAvatarUploader: React.FC<IProps> = ({ hasAvatar, hasAvatarLabel, noAva
>
{ children }
<div className="mx_MiniAvatarUploader_indicator">
{ busy ?
<Spinner w={20} h={20} /> :
<div className="mx_MiniAvatarUploader_cameraIcon"></div> }
</div>
<div className={classNames("mx_Tooltip", {
"mx_Tooltip_visible": visible,
"mx_Tooltip_invisible": !visible,

View file

@ -18,33 +18,21 @@ limitations under the License.
import React from "react";
import PropTypes from "prop-types";
import {_t} from "../../../languageHandler";
import SettingsStore from "../../../settings/SettingsStore";
const Spinner = ({w = 32, h = 32, imgClassName, message}) => {
let imageSource;
if (SettingsStore.getValue('feature_new_spinner')) {
imageSource = require("../../../../res/img/spinner.svg");
} else {
imageSource = require("../../../../res/img/spinner.gif");
}
const Spinner = ({w = 32, h = 32, message}) => (
<div className="mx_Spinner">
{ message && <React.Fragment><div className="mx_Spinner_Msg">{ message }</div>&nbsp;</React.Fragment> }
<div
className="mx_Spinner_icon"
style={{width: w, height: h}}
aria-label={_t("Loading...")}
></div>
</div>
);
return (
<div className="mx_Spinner">
{ message && <React.Fragment><div className="mx_Spinner_Msg">{ message}</div>&nbsp;</React.Fragment> }
<img
src={imageSource}
width={w}
height={h}
className={imgClassName}
aria-label={_t("Loading...")}
/>
</div>
);
};
Spinner.propTypes = {
w: PropTypes.number,
h: PropTypes.number,
imgClassName: PropTypes.string,
message: PropTypes.node,
};

View file

@ -22,6 +22,7 @@ import React, {Component, CSSProperties} from 'react';
import ReactDOM from 'react-dom';
import classNames from 'classnames';
import {replaceableComponent} from "../../../utils/replaceableComponent";
import UIStore from "../../../stores/UIStore";
const MIN_TOOLTIP_HEIGHT = 25;
@ -97,15 +98,15 @@ export default class Tooltip extends React.Component<IProps> {
// we need so that we're still centered.
offset = Math.floor(parentBox.height - MIN_TOOLTIP_HEIGHT);
}
const width = UIStore.instance.windowWidth;
const baseTop = (parentBox.top - 2 + this.props.yOffset) + window.pageYOffset;
const top = baseTop + offset;
const right = window.innerWidth - parentBox.right - window.pageXOffset - 16;
const right = width - parentBox.right - window.pageXOffset - 16;
const left = parentBox.right + window.pageXOffset + 6;
const horizontalCenter = parentBox.right - window.pageXOffset - (parentBox.width / 2);
switch (this.props.alignment) {
case Alignment.Natural:
if (parentBox.right > window.innerWidth / 2) {
if (parentBox.right > width / 2) {
style.right = right;
style.top = top;
break;

View file

@ -19,19 +19,30 @@ import React from 'react';
import * as sdk from '../../../index';
import {replaceableComponent} from "../../../utils/replaceableComponent";
@replaceableComponent("views.elements.TooltipButton")
export default class TooltipButton extends React.Component {
state = {
hover: false,
};
interface IProps {
helpText: string;
}
onMouseOver = () => {
interface IState {
hover: boolean;
}
@replaceableComponent("views.elements.TooltipButton")
export default class TooltipButton extends React.Component<IProps, IState> {
constructor(props) {
super(props);
this.state = {
hover: false,
};
}
private onMouseOver = () => {
this.setState({
hover: true,
});
};
onMouseLeave = () => {
private onMouseLeave = () => {
this.setState({
hover: false,
});