Merge branch 'develop' into export-conversations

This commit is contained in:
Jaiwanth 2021-09-29 19:32:05 +05:30
commit 208b914cb0
62 changed files with 936 additions and 678 deletions

View file

@ -16,6 +16,8 @@ limitations under the License.
*/
import React from 'react';
import classNames from 'classnames';
import { _t } from '../../../languageHandler';
import dis from '../../../dispatcher/dispatcher';
import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
@ -35,6 +37,12 @@ import ReplyTile from "../rooms/ReplyTile";
import Pill from './Pill';
import { Room } from 'matrix-js-sdk/src/models/room';
/**
* This number is based on the previous behavior - if we have message of height
* over 60px then we want to show button that will allow to expand it.
*/
const SHOW_EXPAND_QUOTE_PIXELS = 60;
interface IProps {
// the latest event in this chain of replies
parentEv?: MatrixEvent;
@ -46,6 +54,8 @@ interface IProps {
// Whether to always show a timestamp
alwaysShowTimestamps?: boolean;
forExport?: boolean;
isQuoteExpanded?: boolean;
setQuoteExpanded: (isExpanded: boolean) => void;
}
interface IState {
@ -67,6 +77,7 @@ export default class ReplyThread extends React.Component<IProps, IState> {
static contextType = MatrixClientContext;
private unmounted = false;
private room: Room;
private blockquoteRef = React.createRef<HTMLElement>();
constructor(props, context) {
super(props, context);
@ -81,7 +92,7 @@ export default class ReplyThread extends React.Component<IProps, IState> {
this.room = this.context.getRoom(this.props.parentEv.getRoomId());
}
public static getParentEventId(ev: MatrixEvent): string {
public static getParentEventId(ev: MatrixEvent): string | undefined {
if (!ev || ev.isRedacted()) return;
// XXX: For newer relations (annotations, replacements, etc.), we now
@ -138,7 +149,7 @@ export default class ReplyThread extends React.Component<IProps, IState> {
public static getNestedReplyText(
ev: MatrixEvent,
permalinkCreator: RoomPermalinkCreator,
): { body: string, html: string } {
): { body: string, html: string } | null {
if (!ev) return null;
let { body, formatted_body: html } = ev.getContent();
@ -238,39 +249,38 @@ export default class ReplyThread extends React.Component<IProps, IState> {
return replyMixin;
}
public static makeThread(
parentEv: MatrixEvent,
onHeightChanged: () => void,
permalinkCreator: RoomPermalinkCreator,
ref: React.RefObject<ReplyThread>,
layout: Layout,
forExport: boolean,
alwaysShowTimestamps: boolean,
): JSX.Element {
if (!ReplyThread.getParentEventId(parentEv)) return null;
return <ReplyThread
parentEv={parentEv}
forExport={forExport}
onHeightChanged={onHeightChanged}
ref={ref}
permalinkCreator={permalinkCreator}
layout={layout}
alwaysShowTimestamps={alwaysShowTimestamps}
/>;
public static hasThreadReply(event: MatrixEvent) {
return Boolean(ReplyThread.getParentEventId(event));
}
componentDidMount() {
this.initialize();
this.trySetExpandableQuotes();
}
componentDidUpdate() {
this.props.onHeightChanged();
this.trySetExpandableQuotes();
}
componentWillUnmount() {
this.unmounted = true;
}
private trySetExpandableQuotes() {
if (this.props.isQuoteExpanded === undefined && this.blockquoteRef.current) {
const el: HTMLElement | null = this.blockquoteRef.current.querySelector('.mx_EventTile_body');
if (el) {
const code: HTMLElement | null = el.querySelector('code');
const isCodeEllipsisShown = code ? code.offsetHeight >= SHOW_EXPAND_QUOTE_PIXELS : false;
const isElipsisShown = el.offsetHeight >= SHOW_EXPAND_QUOTE_PIXELS || isCodeEllipsisShown;
if (isElipsisShown) {
this.props.setQuoteExpanded(false);
}
}
}
}
private async initialize(): Promise<void> {
const { parentEv } = this.props;
// at time of making this component we checked that props.parentEv has a parentEventId
@ -324,7 +334,7 @@ export default class ReplyThread extends React.Component<IProps, IState> {
this.initialize();
};
private onQuoteClick = async (): Promise<void> => {
private onQuoteClick = async (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>): Promise<void> => {
const events = [this.state.loadedEv, ...this.state.events];
let loadedEv = null;
@ -387,14 +397,26 @@ export default class ReplyThread extends React.Component<IProps, IState> {
header = <Spinner w={16} h={16} />;
}
const { isQuoteExpanded } = this.props;
const evTiles = this.state.events.map((ev) => {
return <blockquote className={`mx_ReplyThread ${this.getReplyThreadColorClass(ev)}`} key={ev.getId()}>
<ReplyTile
mxEvent={ev}
onHeightChanged={this.props.onHeightChanged}
permalinkCreator={this.props.permalinkCreator}
/>
</blockquote>;
const classname = classNames({
'mx_ReplyThread': true,
[this.getReplyThreadColorClass(ev)]: true,
// We don't want to add the class if it's undefined, it should only be expanded/collapsed when it's true/false
'mx_ReplyThread--expanded': isQuoteExpanded === true,
// We don't want to add the class if it's undefined, it should only be expanded/collapsed when it's true/false
'mx_ReplyThread--collapsed': isQuoteExpanded === false,
});
return (
<blockquote ref={this.blockquoteRef} className={classname} key={ev.getId()}>
<ReplyTile
mxEvent={ev}
onHeightChanged={this.props.onHeightChanged}
permalinkCreator={this.props.permalinkCreator}
toggleExpandedQuote={() => this.props.setQuoteExpanded(!this.props.isQuoteExpanded)}
/>
</blockquote>
);
});
return <div className="mx_ReplyThread_wrapper">