Merge remote-tracking branch 'upstream/develop' into compact-reply-rendering
This commit is contained in:
commit
db5121aeca
744 changed files with 33568 additions and 22073 deletions
|
@ -21,7 +21,7 @@ import { _t } from '../../../languageHandler';
|
|||
import {formatFullDateNoTime} from '../../../DateUtils';
|
||||
|
||||
function getdaysArray() {
|
||||
return [
|
||||
return [
|
||||
_t('Sunday'),
|
||||
_t('Monday'),
|
||||
_t('Tuesday'),
|
||||
|
|
|
@ -22,6 +22,7 @@ import MFileBody from './MFileBody';
|
|||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
||||
import { decryptFile } from '../../../utils/DecryptFile';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import InlineSpinner from '../elements/InlineSpinner';
|
||||
|
||||
export default class MAudioBody extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -94,7 +95,7 @@ export default class MAudioBody extends React.Component {
|
|||
// Not sure how tall the audio player is so not sure how tall it should actually be.
|
||||
return (
|
||||
<span className="mx_MAudioBody">
|
||||
<img src={require("../../../../res/img/spinner.gif")} alt={content.body} width="16" height="16" />
|
||||
<InlineSpinner />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import { decryptFile } from '../../../utils/DecryptFile';
|
|||
import { _t } from '../../../languageHandler';
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import InlineSpinner from '../elements/InlineSpinner';
|
||||
|
||||
export default class MImageBody extends React.Component {
|
||||
static propTypes = {
|
||||
|
@ -365,12 +366,7 @@ export default class MImageBody extends React.Component {
|
|||
|
||||
// e2e image hasn't been decrypted yet
|
||||
if (content.file !== undefined && this.state.decryptedUrl === null) {
|
||||
placeholder = <img
|
||||
src={require("../../../../res/img/spinner.gif")}
|
||||
alt={content.body}
|
||||
width="32"
|
||||
height="32"
|
||||
/>;
|
||||
placeholder = <InlineSpinner w={32} h={32} />;
|
||||
} else if (!this.state.imgLoaded) {
|
||||
// Deliberately, getSpinner is left unimplemented here, MStickerBody overides
|
||||
placeholder = this.getPlaceholder();
|
||||
|
|
|
@ -22,7 +22,8 @@ import { _t } from '../../../languageHandler';
|
|||
import {getNameForEventRoom, userLabelForEventRoom}
|
||||
from '../../../utils/KeyVerificationStateObserver';
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
import {RIGHT_PANEL_PHASES} from "../../../stores/RightPanelStorePhases";
|
||||
import {RightPanelPhases} from "../../../stores/RightPanelStorePhases";
|
||||
import {Action} from "../../../dispatcher/actions";
|
||||
|
||||
export default class MKeyVerificationRequest extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -48,8 +49,8 @@ export default class MKeyVerificationRequest extends React.Component {
|
|||
const {verificationRequest} = this.props.mxEvent;
|
||||
const member = MatrixClientPeg.get().getUser(verificationRequest.otherUserId);
|
||||
dis.dispatch({
|
||||
action: "set_right_panel_phase",
|
||||
phase: RIGHT_PANEL_PHASES.EncryptionPanel,
|
||||
action: Action.SetRightPanelPhase,
|
||||
phase: RightPanelPhases.EncryptionPanel,
|
||||
refireParams: {verificationRequest, member},
|
||||
});
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
|||
import { decryptFile } from '../../../utils/DecryptFile';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import InlineSpinner from '../elements/InlineSpinner';
|
||||
|
||||
export default createReactClass({
|
||||
displayName: 'MVideoBody',
|
||||
|
@ -147,7 +148,7 @@ export default createReactClass({
|
|||
return (
|
||||
<span className="mx_MVideoBody">
|
||||
<div className="mx_MImageBody_thumbnail mx_MImageBody_thumbnail_spinner">
|
||||
<img src={require("../../../../res/img/spinner.gif")} alt={content.body} width="16" height="16" />
|
||||
<InlineSpinner />
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
|
|
|
@ -22,12 +22,15 @@ import PropTypes from 'prop-types';
|
|||
import { _t } from '../../../languageHandler';
|
||||
import * as sdk from '../../../index';
|
||||
import dis from '../../../dispatcher/dispatcher';
|
||||
import {aboveLeftOf, ContextMenu, ContextMenuButton, useContextMenu} from '../../structures/ContextMenu';
|
||||
import {aboveLeftOf, ContextMenu, ContextMenuTooltipButton, useContextMenu} from '../../structures/ContextMenu';
|
||||
import { isContentActionable, canEditContent } from '../../../utils/EventUtils';
|
||||
import RoomContext from "../../../contexts/RoomContext";
|
||||
import Toolbar from "../../../accessibility/Toolbar";
|
||||
import {RovingAccessibleTooltipButton, useRovingTabIndex} from "../../../accessibility/RovingTabIndex";
|
||||
|
||||
const OptionsButton = ({mxEvent, getTile, getReplyThread, permalinkCreator, onFocusChange}) => {
|
||||
const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu();
|
||||
const [onFocus, isActive, ref] = useRovingTabIndex(button);
|
||||
useEffect(() => {
|
||||
onFocusChange(menuDisplayed);
|
||||
}, [onFocusChange, menuDisplayed]);
|
||||
|
@ -52,12 +55,14 @@ const OptionsButton = ({mxEvent, getTile, getReplyThread, permalinkCreator, onFo
|
|||
}
|
||||
|
||||
return <React.Fragment>
|
||||
<ContextMenuButton
|
||||
<ContextMenuTooltipButton
|
||||
className="mx_MessageActionBar_maskButton mx_MessageActionBar_optionsButton"
|
||||
label={_t("Options")}
|
||||
title={_t("Options")}
|
||||
onClick={openMenu}
|
||||
isExpanded={menuDisplayed}
|
||||
inputRef={button}
|
||||
inputRef={ref}
|
||||
onFocus={onFocus}
|
||||
tabIndex={isActive ? 0 : -1}
|
||||
/>
|
||||
|
||||
{ contextMenu }
|
||||
|
@ -66,6 +71,7 @@ const OptionsButton = ({mxEvent, getTile, getReplyThread, permalinkCreator, onFo
|
|||
|
||||
const ReactButton = ({mxEvent, reactions, onFocusChange}) => {
|
||||
const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu();
|
||||
const [onFocus, isActive, ref] = useRovingTabIndex(button);
|
||||
useEffect(() => {
|
||||
onFocusChange(menuDisplayed);
|
||||
}, [onFocusChange, menuDisplayed]);
|
||||
|
@ -80,12 +86,14 @@ const ReactButton = ({mxEvent, reactions, onFocusChange}) => {
|
|||
}
|
||||
|
||||
return <React.Fragment>
|
||||
<ContextMenuButton
|
||||
<ContextMenuTooltipButton
|
||||
className="mx_MessageActionBar_maskButton mx_MessageActionBar_reactButton"
|
||||
label={_t("React")}
|
||||
title={_t("React")}
|
||||
onClick={openMenu}
|
||||
isExpanded={menuDisplayed}
|
||||
inputRef={button}
|
||||
inputRef={ref}
|
||||
onFocus={onFocus}
|
||||
tabIndex={isActive ? 0 : -1}
|
||||
/>
|
||||
|
||||
{ contextMenu }
|
||||
|
@ -148,8 +156,6 @@ export default class MessageActionBar extends React.PureComponent {
|
|||
};
|
||||
|
||||
render() {
|
||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||
|
||||
let reactButton;
|
||||
let replyButton;
|
||||
let editButton;
|
||||
|
@ -161,7 +167,7 @@ export default class MessageActionBar extends React.PureComponent {
|
|||
);
|
||||
}
|
||||
if (this.context.canReply) {
|
||||
replyButton = <AccessibleButton
|
||||
replyButton = <RovingAccessibleTooltipButton
|
||||
className="mx_MessageActionBar_maskButton mx_MessageActionBar_replyButton"
|
||||
title={_t("Reply")}
|
||||
onClick={this.onReplyClick}
|
||||
|
@ -169,7 +175,7 @@ export default class MessageActionBar extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
if (canEditContent(this.props.mxEvent)) {
|
||||
editButton = <AccessibleButton
|
||||
editButton = <RovingAccessibleTooltipButton
|
||||
className="mx_MessageActionBar_maskButton mx_MessageActionBar_editButton"
|
||||
title={_t("Edit")}
|
||||
onClick={this.onEditClick}
|
||||
|
@ -177,7 +183,7 @@ export default class MessageActionBar extends React.PureComponent {
|
|||
}
|
||||
|
||||
// aria-live=off to not have this read out automatically as navigating around timeline, gets repetitive.
|
||||
return <div className="mx_MessageActionBar" role="toolbar" aria-label={_t("Message Actions")} aria-live="off">
|
||||
return <Toolbar className="mx_MessageActionBar" aria-label={_t("Message Actions")} aria-live="off">
|
||||
{reactButton}
|
||||
{replyButton}
|
||||
{editButton}
|
||||
|
@ -188,6 +194,6 @@ export default class MessageActionBar extends React.PureComponent {
|
|||
permalinkCreator={this.props.permalinkCreator}
|
||||
onFocusChange={this.onFocusChange}
|
||||
/>
|
||||
</div>;
|
||||
</Toolbar>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ export default class ReactionsRowButton extends React.PureComponent {
|
|||
});
|
||||
}
|
||||
|
||||
onMouseOut = () => {
|
||||
onMouseLeave = () => {
|
||||
this.setState({
|
||||
tooltipVisible: false,
|
||||
});
|
||||
|
@ -129,11 +129,12 @@ export default class ReactionsRowButton extends React.PureComponent {
|
|||
}
|
||||
|
||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||
return <AccessibleButton className={classes}
|
||||
return <AccessibleButton
|
||||
className={classes}
|
||||
aria-label={label}
|
||||
onClick={this.onClick}
|
||||
onMouseOver={this.onMouseOver}
|
||||
onMouseOut={this.onMouseOut}
|
||||
onMouseLeave={this.onMouseLeave}
|
||||
>
|
||||
<span className="mx_ReactionsRowButton_content" aria-hidden="true">
|
||||
{content}
|
||||
|
|
|
@ -55,7 +55,7 @@ export default class ReactionsRowButtonTooltip extends React.PureComponent {
|
|||
},
|
||||
{
|
||||
reactors: () => {
|
||||
return <div className="mx_ReactionsRowButtonTooltip_senders">
|
||||
return <div className="mx_Tooltip_title">
|
||||
{formatCommaSeparatedList(senders, 6)}
|
||||
</div>;
|
||||
},
|
||||
|
@ -63,7 +63,7 @@ export default class ReactionsRowButtonTooltip extends React.PureComponent {
|
|||
if (!shortName) {
|
||||
return null;
|
||||
}
|
||||
return <div className="mx_ReactionsRowButtonTooltip_reactedWith">
|
||||
return <div className="mx_Tooltip_sub">
|
||||
{sub}
|
||||
</div>;
|
||||
},
|
||||
|
@ -73,11 +73,7 @@ export default class ReactionsRowButtonTooltip extends React.PureComponent {
|
|||
|
||||
let tooltip;
|
||||
if (tooltipLabel) {
|
||||
tooltip = <Tooltip
|
||||
tooltipClassName="mx_Tooltip_timeline"
|
||||
visible={visible}
|
||||
label={tooltipLabel}
|
||||
/>;
|
||||
tooltip = <Tooltip visible={visible} label={tooltipLabel} />;
|
||||
}
|
||||
|
||||
return tooltip;
|
||||
|
|
|
@ -19,6 +19,8 @@ import {MatrixClient} from "matrix-js-sdk/src/client";
|
|||
import {MatrixEvent} from "matrix-js-sdk/src/models/event";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import {formatFullDate} from "../../../DateUtils";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
|
||||
interface IProps {
|
||||
mxEvent: MatrixEvent;
|
||||
|
@ -36,8 +38,12 @@ const RedactedBody = React.forwardRef<any, IProps>(({mxEvent}, ref) => {
|
|||
text = _t("Message deleted by %(name)s", { name: sender ? sender.name : redactedBecauseUserId });
|
||||
}
|
||||
|
||||
const showTwelveHour = SettingsStore.getValue("showTwelveHourTimestamps");
|
||||
const fullDate = formatFullDate(new Date(unsigned.redacted_because.origin_server_ts), showTwelveHour);
|
||||
const titleText = _t("Message deleted on %(date)s", { date: fullDate });
|
||||
|
||||
return (
|
||||
<span className="mx_RedactedBody" ref={ref}>
|
||||
<span className="mx_RedactedBody" ref={ref} title={titleText}>
|
||||
{ text }
|
||||
</span>
|
||||
);
|
||||
|
|
|
@ -125,8 +125,10 @@ export default createReactClass({
|
|||
</span>;
|
||||
|
||||
const content = this.props.text ?
|
||||
<span className="mx_SenderProfile_aux">
|
||||
{ _t(this.props.text, { senderName: () => nameElem }) }
|
||||
<span>
|
||||
<span className="mx_SenderProfile_aux">
|
||||
{ _t(this.props.text, { senderName: () => nameElem }) }
|
||||
</span>
|
||||
</span> : nameFlair;
|
||||
|
||||
return (
|
||||
|
|
|
@ -35,6 +35,7 @@ import {IntegrationManagers} from "../../../integrations/IntegrationManagers";
|
|||
import {isPermalinkHost} from "../../../utils/permalinks/Permalinks";
|
||||
import {toRightOf} from "../../structures/ContextMenu";
|
||||
import {copyPlaintext} from "../../../utils/strings";
|
||||
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||
|
||||
export default createReactClass({
|
||||
displayName: 'TextualBody',
|
||||
|
@ -106,7 +107,7 @@ export default createReactClass({
|
|||
} else {
|
||||
// Only syntax highlight if there's a class starting with language-
|
||||
const classes = blocks[i].className.split(/\s+/).filter(function(cl) {
|
||||
return cl.startsWith('language-');
|
||||
return cl.startsWith('language-') && !cl.startsWith('language-_');
|
||||
});
|
||||
|
||||
if (classes.length != 0) {
|
||||
|
@ -146,7 +147,6 @@ export default createReactClass({
|
|||
nextProps.showUrlPreview !== this.props.showUrlPreview ||
|
||||
nextProps.editState !== this.props.editState ||
|
||||
nextState.links !== this.state.links ||
|
||||
nextState.editedMarkerHovered !== this.state.editedMarkerHovered ||
|
||||
nextState.widgetHidden !== this.state.widgetHidden);
|
||||
},
|
||||
|
||||
|
@ -367,42 +367,33 @@ export default createReactClass({
|
|||
});
|
||||
},
|
||||
|
||||
_onMouseEnterEditedMarker: function() {
|
||||
this.setState({editedMarkerHovered: true});
|
||||
},
|
||||
|
||||
_onMouseLeaveEditedMarker: function() {
|
||||
this.setState({editedMarkerHovered: false});
|
||||
},
|
||||
|
||||
_openHistoryDialog: async function() {
|
||||
const MessageEditHistoryDialog = sdk.getComponent("views.dialogs.MessageEditHistoryDialog");
|
||||
Modal.createDialog(MessageEditHistoryDialog, {mxEvent: this.props.mxEvent});
|
||||
},
|
||||
|
||||
_renderEditedMarker: function() {
|
||||
let editedTooltip;
|
||||
if (this.state.editedMarkerHovered) {
|
||||
const Tooltip = sdk.getComponent('elements.Tooltip');
|
||||
const date = this.props.mxEvent.replacingEventDate();
|
||||
const dateString = date && formatDate(date);
|
||||
editedTooltip = <Tooltip
|
||||
tooltipClassName="mx_Tooltip_timeline"
|
||||
label={_t("Edited at %(date)s. Click to view edits.", {date: dateString})}
|
||||
/>;
|
||||
}
|
||||
const date = this.props.mxEvent.replacingEventDate();
|
||||
const dateString = date && formatDate(date);
|
||||
|
||||
const tooltip = <div>
|
||||
<div className="mx_Tooltip_title">
|
||||
{_t("Edited at %(date)s", {date: dateString})}
|
||||
</div>
|
||||
<div className="mx_Tooltip_sub">
|
||||
{_t("Click to view edits")}
|
||||
</div>
|
||||
</div>;
|
||||
|
||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||
return (
|
||||
<AccessibleButton
|
||||
key="editedMarker"
|
||||
<AccessibleTooltipButton
|
||||
className="mx_EventTile_edited"
|
||||
onClick={this._openHistoryDialog}
|
||||
onMouseEnter={this._onMouseEnterEditedMarker}
|
||||
onMouseLeave={this._onMouseLeaveEditedMarker}
|
||||
title={_t("Edited at %(date)s. Click to view edits.", {date: dateString})}
|
||||
tooltip={tooltip}
|
||||
>
|
||||
{ editedTooltip }<span>{`(${_t("edited")})`}</span>
|
||||
</AccessibleButton>
|
||||
<span>{`(${_t("edited")})`}</span>
|
||||
</AccessibleTooltipButton>
|
||||
);
|
||||
},
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue