isExporting -> forExport and wrap EventTile with Context Provider
parent
9e298e9f45
commit
6f8c1638aa
|
@ -46,7 +46,7 @@ export default class ReplyThread extends React.Component {
|
|||
permalinkCreator: PropTypes.instanceOf(RoomPermalinkCreator).isRequired,
|
||||
// Specifies which layout to use.
|
||||
layout: LayoutPropType,
|
||||
isExporting: PropTypes.bool,
|
||||
forExport: PropTypes.bool,
|
||||
};
|
||||
|
||||
static contextType = MatrixClientContext;
|
||||
|
@ -69,7 +69,7 @@ export default class ReplyThread extends React.Component {
|
|||
|
||||
this.unmounted = false;
|
||||
|
||||
if (this.props.isExporting) return;
|
||||
if (this.props.forExport) return;
|
||||
|
||||
this.context.on("Event.replaced", this.onEventReplaced);
|
||||
this.room = this.context.getRoom(this.props.parentEv.getRoomId());
|
||||
|
@ -216,13 +216,13 @@ export default class ReplyThread extends React.Component {
|
|||
};
|
||||
}
|
||||
|
||||
static makeThread(parentEv, onHeightChanged, permalinkCreator, ref, layout, isExporting) {
|
||||
static makeThread(parentEv, onHeightChanged, permalinkCreator, ref, layout, forExport) {
|
||||
if (!ReplyThread.getParentEventId(parentEv)) {
|
||||
return null;
|
||||
}
|
||||
return <ReplyThread
|
||||
parentEv={parentEv}
|
||||
isExporting={isExporting}
|
||||
forExport={forExport}
|
||||
onHeightChanged={onHeightChanged}
|
||||
ref={ref}
|
||||
permalinkCreator={permalinkCreator}
|
||||
|
@ -367,7 +367,7 @@ export default class ReplyThread extends React.Component {
|
|||
})
|
||||
}
|
||||
</blockquote>;
|
||||
} else if (this.props.isExporting) {
|
||||
} else if (this.props.forExport) {
|
||||
const eventId = ReplyThread.getParentEventId(this.props.parentEv);
|
||||
header = <p style={{ marginTop: -5, marginBottom: 5 }}>
|
||||
In reply to <a className="mx_reply_anchor" href={`#${eventId}`} scroll-to={eventId}>this message</a>
|
||||
|
|
|
@ -37,14 +37,14 @@ function getdaysArray() {
|
|||
export default class DateSeparator extends React.Component {
|
||||
static propTypes = {
|
||||
ts: PropTypes.number.isRequired,
|
||||
isExporting: PropTypes.bool,
|
||||
forExport: PropTypes.bool,
|
||||
};
|
||||
|
||||
getLabel() {
|
||||
const date = new Date(this.props.ts);
|
||||
|
||||
// During the time the archive is being viewed, a specific day might not make sense, so we return the full date
|
||||
if (this.props.isExporting) return formatFullDateNoTime(date);
|
||||
if (this.props.forExport) return formatFullDateNoTime(date);
|
||||
|
||||
const today = new Date();
|
||||
const yesterday = new Date();
|
||||
|
|
|
@ -104,7 +104,7 @@ export default class MFileBody extends React.Component {
|
|||
showGenericPlaceholder: PropTypes.bool,
|
||||
/* to set source to local file path during export */
|
||||
mediaSrc: PropTypes.string,
|
||||
isExporting: PropTypes.bool,
|
||||
forExport: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
@ -176,7 +176,7 @@ export default class MFileBody extends React.Component {
|
|||
placeholder = (
|
||||
<div className="mx_MFileBody_info">
|
||||
<span className="mx_MFileBody_info_icon" >
|
||||
{this.props.isExporting ?
|
||||
{this.props.forExport ?
|
||||
<img alt="Attachment" className="mx_export_attach_icon" src="icons/attach.svg" />
|
||||
: null}
|
||||
</span>
|
||||
|
|
|
@ -48,7 +48,7 @@ export default class MessageEvent extends React.Component {
|
|||
mediaSrc: PropTypes.string,
|
||||
|
||||
/* to set source to local file path during export */
|
||||
isExporting: PropTypes.bool,
|
||||
forExport: PropTypes.bool,
|
||||
|
||||
/* the maximum image height to use, if the event is an image */
|
||||
maxImageHeight: PropTypes.number,
|
||||
|
@ -127,7 +127,7 @@ export default class MessageEvent extends React.Component {
|
|||
showUrlPreview={this.props.showUrlPreview}
|
||||
tileShape={this.props.tileShape}
|
||||
mediaSrc={this.props.mediaSrc}
|
||||
isExporting={this.props.isExporting}
|
||||
forExport={this.props.forExport}
|
||||
maxImageHeight={this.props.maxImageHeight}
|
||||
replacingEventId={this.props.replacingEventId}
|
||||
editState={this.props.editState}
|
||||
|
|
|
@ -21,17 +21,14 @@ import { _t } from "../../../languageHandler";
|
|||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import { formatFullDate } from "../../../DateUtils";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
|
||||
interface IProps {
|
||||
mxEvent: MatrixEvent;
|
||||
isExporting: boolean;
|
||||
forExport: boolean;
|
||||
}
|
||||
|
||||
const RedactedBody = React.forwardRef<any, IProps>(({mxEvent, isExporting}, ref) => {
|
||||
let cli: MatrixClient = useContext(MatrixClientContext);
|
||||
// As context doesn't propagate during export, we'll have to explicitly declare
|
||||
if (isExporting) cli = MatrixClientPeg.get();
|
||||
const RedactedBody = React.forwardRef<any, IProps>(({mxEvent, forExport}, ref) => {
|
||||
const cli: MatrixClient = useContext(MatrixClientContext);
|
||||
let text = _t("Message deleted");
|
||||
const unsigned = mxEvent.getUnsigned();
|
||||
const redactedBecauseUserId = unsigned && unsigned.redacted_because && unsigned.redacted_because.sender;
|
||||
|
@ -47,7 +44,7 @@ const RedactedBody = React.forwardRef<any, IProps>(({mxEvent, isExporting}, ref)
|
|||
|
||||
return (
|
||||
<span className="mx_RedactedBody" ref={ref} title={titleText}>
|
||||
{ isExporting ? <img alt="Redacted" className="mx_export_trash_icon" src="icons/trash.svg" /> : null }
|
||||
{ forExport ? <img alt="Redacted" className="mx_export_trash_icon" src="icons/trash.svg" /> : null }
|
||||
{ text }
|
||||
</span>
|
||||
);
|
||||
|
|
|
@ -249,7 +249,7 @@ interface IProps {
|
|||
// for now.
|
||||
tileShape?: 'notif' | 'file_grid' | 'reply' | 'reply_preview';
|
||||
|
||||
isExporting?: boolean;
|
||||
forExport?: boolean;
|
||||
|
||||
// Used while exporting to refer to the local source rather than the online one
|
||||
mediaSrc?: string;
|
||||
|
@ -320,7 +320,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
static defaultProps = {
|
||||
// no-op function because onHeightChanged is optional yet some sub-components assume its existence
|
||||
onHeightChanged: function() {},
|
||||
isExporting: false,
|
||||
forExport: false,
|
||||
};
|
||||
|
||||
static contextType = MatrixClientContext;
|
||||
|
@ -427,8 +427,6 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
// TODO: [REACT-WARNING] Move into constructor
|
||||
// eslint-disable-next-line camelcase
|
||||
UNSAFE_componentWillMount() {
|
||||
// Context isn't propagated through renderToStaticMarkup so we'll have to explicitly set it during export
|
||||
if (this.props.isExporting) this.context = MatrixClientPeg.get();
|
||||
this.verifyEvent(this.props.mxEvent);
|
||||
}
|
||||
|
||||
|
@ -631,7 +629,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
shouldHighlight() {
|
||||
if (this.props.isExporting) return false;
|
||||
if (this.props.forExport) return false;
|
||||
const actions = this.context.getPushActionsForEvent(this.props.mxEvent.replacingEvent() || this.props.mxEvent);
|
||||
if (!actions || !actions.tweaks) { return false; }
|
||||
|
||||
|
@ -981,7 +979,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
const MessageActionBar = sdk.getComponent('messages.MessageActionBar');
|
||||
const showMessageActionBar = !isEditing && !this.props.isExporting;
|
||||
const showMessageActionBar = !isEditing && !this.props.forExport;
|
||||
const actionBar = showMessageActionBar ? <MessageActionBar
|
||||
mxEvent={this.props.mxEvent}
|
||||
reactions={this.state.reactions}
|
||||
|
@ -1155,7 +1153,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
this.props.permalinkCreator,
|
||||
this.replyThread,
|
||||
this.props.layout,
|
||||
this.props.isExporting,
|
||||
this.props.forExport,
|
||||
);
|
||||
|
||||
// tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers
|
||||
|
@ -1179,7 +1177,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
{ thread }
|
||||
<EventTileType ref={this.tile}
|
||||
mxEvent={this.props.mxEvent}
|
||||
isExporting={this.props.isExporting}
|
||||
forExport={this.props.forExport}
|
||||
replacingEventId={this.props.replacingEventId}
|
||||
editState={this.props.editState}
|
||||
mediaSrc={this.props.mediaSrc}
|
||||
|
|
|
@ -23,16 +23,20 @@ import exportCSS from "./exportCSS";
|
|||
import exportJS from "./exportJS";
|
||||
import exportIcons from "./exportIcons";
|
||||
import { exportTypes } from "./exportUtils";
|
||||
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
||||
import { MatrixClient } from "matrix-js-sdk";
|
||||
|
||||
export default class HTMLExporter extends Exporter {
|
||||
protected zip: JSZip;
|
||||
protected avatars: Map<string, boolean>;
|
||||
protected permalinkCreator: RoomPermalinkCreator;
|
||||
protected matrixClient: MatrixClient;
|
||||
|
||||
constructor(room: Room, exportType: exportTypes, numberOfEvents?: number) {
|
||||
super(room, exportType, numberOfEvents);
|
||||
this.zip = new JSZip();
|
||||
this.avatars = new Map<string, boolean>();
|
||||
this.matrixClient = MatrixClientPeg.get();
|
||||
this.permalinkCreator = new RoomPermalinkCreator(this.room);
|
||||
window.addEventListener("beforeunload", this.onBeforeUnload)
|
||||
}
|
||||
|
@ -214,7 +218,7 @@ export default class HTMLExporter extends Exporter {
|
|||
|
||||
protected getDateSeparator(event: MatrixEvent) {
|
||||
const ts = event.getTs();
|
||||
const dateSeparator = <li key={ts}><DateSeparator isExporting={true} key={ts} ts={ts} /></li>;
|
||||
const dateSeparator = <li key={ts}><DateSeparator forExport={true} key={ts} ts={ts} /></li>;
|
||||
return renderToStaticMarkup(dateSeparator);
|
||||
}
|
||||
|
||||
|
@ -258,30 +262,32 @@ export default class HTMLExporter extends Exporter {
|
|||
if (hasAvatar) await this.saveAvatarIfNeeded(mxEv);
|
||||
|
||||
return <li className="mx_Export_EventWrapper" id={mxEv.getId()}>
|
||||
<EventTile
|
||||
mxEvent={mxEv}
|
||||
continuation={continuation}
|
||||
isRedacted={mxEv.isRedacted()}
|
||||
replacingEventId={mxEv.replacingEventId()}
|
||||
isExporting={true}
|
||||
readReceipts={null}
|
||||
readReceiptMap={null}
|
||||
showUrlPreview={false}
|
||||
checkUnmounting={() => false}
|
||||
isTwelveHour={false}
|
||||
last={false}
|
||||
mediaSrc={mediaSrc}
|
||||
avatarSrc={hasAvatar ? `users/${mxEv.sender.userId}` : null}
|
||||
lastInSection={false}
|
||||
permalinkCreator={this.permalinkCreator}
|
||||
lastSuccessful={false}
|
||||
isSelectedEvent={false}
|
||||
getRelationsForEvent={null}
|
||||
showReactions={false}
|
||||
layout={Layout.Group}
|
||||
enableFlair={false}
|
||||
showReadReceipts={false}
|
||||
/>
|
||||
<MatrixClientContext.Provider value = {this.matrixClient}>
|
||||
<EventTile
|
||||
mxEvent={mxEv}
|
||||
continuation={continuation}
|
||||
isRedacted={mxEv.isRedacted()}
|
||||
replacingEventId={mxEv.replacingEventId()}
|
||||
forExport={true}
|
||||
readReceipts={null}
|
||||
readReceiptMap={null}
|
||||
showUrlPreview={false}
|
||||
checkUnmounting={() => false}
|
||||
isTwelveHour={false}
|
||||
last={false}
|
||||
mediaSrc={mediaSrc}
|
||||
avatarSrc={hasAvatar ? `users/${mxEv.sender.userId}` : null}
|
||||
lastInSection={false}
|
||||
permalinkCreator={this.permalinkCreator}
|
||||
lastSuccessful={false}
|
||||
isSelectedEvent={false}
|
||||
getRelationsForEvent={null}
|
||||
showReactions={false}
|
||||
layout={Layout.Group}
|
||||
enableFlair={false}
|
||||
showReadReceipts={false}
|
||||
/>
|
||||
</MatrixClientContext.Provider>
|
||||
</li>
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ export enum exportFormats {
|
|||
export enum exportTypes {
|
||||
TIMELINE = "TIMELINE",
|
||||
BEGINNING = "BEGINNING",
|
||||
START_DATE = "START_DATE",
|
||||
LAST_N_MESSAGES = "LAST_N_MESSAGES",
|
||||
}
|
||||
|
||||
|
@ -17,11 +18,11 @@ const exportConversationalHistory = async (
|
|||
room: Room,
|
||||
format: string,
|
||||
exportType: exportTypes,
|
||||
numberOfEvents?: number,
|
||||
exportTypeMetadata?: number,
|
||||
) => {
|
||||
switch (format) {
|
||||
case exportFormats.HTML:
|
||||
await new HTMLExporter(room, exportType, numberOfEvents).export();
|
||||
await new HTMLExporter(room, exportType, exportTypeMetadata).export();
|
||||
break;
|
||||
case exportFormats.JSON:
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue