diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index b8220d8a5c..d854baec46 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -432,7 +432,7 @@ export default class MImageBody extends React.Component { // Overidden by MStickerBody wrapImage(contentUrl, children) { - return + return {children} ; } diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index a0055e1b5c..3b507763fa 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -82,7 +82,12 @@ export default class RoomHeader extends React.Component { _exportConversationalHistory = async () => { - await exportConversationalHistory(this.props.room, exportFormats.HTML, exportTypes.LAST_N_MESSAGES, 100); + await exportConversationalHistory( + this.props.room, + exportFormats.HTML, + exportTypes.START_DATE, + { startDate: parseInt(new Date("2021.05.20").getTime().toFixed(0)) }, + ); } render() { diff --git a/src/utils/exportUtils/Exporter.ts b/src/utils/exportUtils/Exporter.ts index 36494e13ef..5b0d2df188 100644 --- a/src/utils/exportUtils/Exporter.ts +++ b/src/utils/exportUtils/Exporter.ts @@ -1,37 +1,15 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { Room } from "matrix-js-sdk/src/models/room"; import { MatrixClientPeg } from "../../MatrixClientPeg"; -import { TimelineWindow } from "matrix-js-sdk/src/timeline-window"; -import { arrayFastClone } from "../arrays"; import { exportTypes } from "./exportUtils"; +import { exportOptions } from "./exportUtils"; export default abstract class Exporter { - protected constructor(protected room: Room, protected exportType: exportTypes, protected numberOfEvents?: number) {} - - protected getTimelineConversation = (): MatrixEvent[] => { - if (!this.room) return; - - const cli = MatrixClientPeg.get(); - - const timelineSet = this.room.getUnfilteredTimelineSet(); - - const timelineWindow = new TimelineWindow( - cli, timelineSet, - {windowLimit: Number.MAX_VALUE}); - - timelineWindow.load(null, 30); - - const events: MatrixEvent[] = timelineWindow.getEvents(); - - // Clone and reverse the events so that we preserve the order - arrayFastClone(events) - .reverse() - .forEach(async (event) => { - await cli.decryptEventIfNeeded(event); - }); - - return events; - }; + protected constructor( + protected room: Room, + protected exportType: exportTypes, + protected exportOptions?: exportOptions, + ) {} protected setEventMetadata = (event: MatrixEvent) => { const client = MatrixClientPeg.get(); @@ -47,12 +25,27 @@ export default abstract class Exporter { return event; } + protected getLimit = () => { + let limit: number; + switch (this.exportType) { + case exportTypes.LAST_N_MESSAGES: + limit = this.exportOptions.numberOfMessages; + break; + case exportTypes.TIMELINE: + limit = 40; + break; + default: + limit = Number.MAX_VALUE; + } + return limit; + } + protected getRequiredEvents = async () : Promise => { const client = MatrixClientPeg.get(); const eventMapper = client.getEventMapper(); let prevToken: string|null = null; - let limit = this.numberOfEvents || Number.MAX_VALUE; + let limit = this.getLimit(); let events: MatrixEvent[] = []; while (limit) { @@ -65,7 +58,14 @@ export default abstract class Exporter { const matrixEvents: MatrixEvent[] = res.chunk.map(eventMapper); - matrixEvents.forEach(mxEv => events.push(mxEv)); + for (const mxEv of matrixEvents) { + if (this.exportOptions.startDate && mxEv.getTs() < this.exportOptions.startDate) { + // Once the last message received is older than the start date, we break out of both the loops + limit = 0; + break; + } + events.push(mxEv); + } prevToken = res.end; } diff --git a/src/utils/exportUtils/HtmlExport.tsx b/src/utils/exportUtils/HtmlExport.tsx index 3472d99507..ded4e82b84 100644 --- a/src/utils/exportUtils/HtmlExport.tsx +++ b/src/utils/exportUtils/HtmlExport.tsx @@ -23,6 +23,7 @@ import exportCSS from "./exportCSS"; import exportJS from "./exportJS"; import exportIcons from "./exportIcons"; import { exportTypes } from "./exportUtils"; +import { exportOptions } from "./exportUtils"; import MatrixClientContext from "../../contexts/MatrixClientContext"; import { MatrixClient } from "matrix-js-sdk"; @@ -32,8 +33,8 @@ export default class HTMLExporter extends Exporter { protected permalinkCreator: RoomPermalinkCreator; protected matrixClient: MatrixClient; - constructor(room: Room, exportType: exportTypes, numberOfEvents?: number) { - super(room, exportType, numberOfEvents); + constructor(room: Room, exportType: exportTypes, exportOptions: exportOptions) { + super(room, exportType, exportOptions); this.zip = new JSZip(); this.avatars = new Map(); this.matrixClient = MatrixClientPeg.get(); @@ -282,7 +283,7 @@ export default class HTMLExporter extends Exporter { protected async getEventTile(mxEv: MatrixEvent, continuation: boolean, filePath?: string) { const hasAvatar = this.hasAvatar(mxEv); if (hasAvatar) await this.saveAvatarIfNeeded(mxEv); - const eventTile =
  • + const eventTile =
    -
  • + let eventTileMarkup = renderToStaticMarkup(eventTile); - if (filePath) eventTileMarkup = eventTileMarkup.replace(/(src=|href=)"forExport"/, `$1"${filePath}"`); + if (filePath) eventTileMarkup = eventTileMarkup.replace(/(src=|href=)"forExport"/g, `$1"${filePath}"`); if (hasAvatar) { - eventTileMarkup = eventTileMarkup.replace(/src="AvatarForExport"/, `src="users/${mxEv.sender.userId}"`); + eventTileMarkup = eventTileMarkup.replace(/src="AvatarForExport"/g, `src="users/${mxEv.sender.userId}"`); } return eventTileMarkup; } diff --git a/src/utils/exportUtils/exportCSS.ts b/src/utils/exportUtils/exportCSS.ts index 7813c1651a..cbba088361 100644 --- a/src/utils/exportUtils/exportCSS.ts +++ b/src/utils/exportUtils/exportCSS.ts @@ -19537,7 +19537,7 @@ a.mx_reply_anchor:hover{ } -li.mx_Export_EventWrapper:target { +.mx_Export_EventWrapper:target { background: white; animation: mx_event_highlight_animation 2s linear; } diff --git a/src/utils/exportUtils/exportUtils.ts b/src/utils/exportUtils/exportUtils.ts index 531b5d98e4..ed285b47bc 100644 --- a/src/utils/exportUtils/exportUtils.ts +++ b/src/utils/exportUtils/exportUtils.ts @@ -14,15 +14,20 @@ export enum exportTypes { LAST_N_MESSAGES = "LAST_N_MESSAGES", } +export interface exportOptions { + startDate?: number; + numberOfMessages?: number; +} + const exportConversationalHistory = async ( room: Room, format: string, exportType: exportTypes, - exportTypeMetadata?: number, + exportOptions?: exportOptions, ) => { switch (format) { case exportFormats.HTML: - await new HTMLExporter(room, exportType, exportTypeMetadata).export(); + await new HTMLExporter(room, exportType, exportOptions).export(); break; case exportFormats.JSON: break;