diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index ba3b72e779..ac621f7010 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -84,8 +84,8 @@ export default class RoomHeader extends React.Component { }, 500); - _exportConvertionalHistory = async () => { - await exportConversationalHistory(this.props.room, exportFormats.HTML, exportTypes.LAST_N_MESSAGES, 30); + _exportConversationalHistory = async () => { + await exportConversationalHistory(this.props.room, exportFormats.HTML, exportTypes.LAST_N_MESSAGES, 250); } render() { @@ -198,7 +198,7 @@ export default class RoomHeader extends React.Component { const exportButton = ; const rightRow = diff --git a/src/utils/exportUtils/Exporter.ts b/src/utils/exportUtils/Exporter.ts index 8e3a454e2e..b0f1104bd2 100644 --- a/src/utils/exportUtils/Exporter.ts +++ b/src/utils/exportUtils/Exporter.ts @@ -4,10 +4,9 @@ import { MatrixClientPeg } from "../../MatrixClientPeg"; import { TimelineWindow } from "matrix-js-sdk/src/timeline-window"; import { arrayFastClone } from "../arrays"; import { exportTypes } from "./exportUtils"; -import { RoomMember } from 'matrix-js-sdk/src/models/room-member'; export default abstract class Exporter { - constructor(protected room: Room, protected exportType: exportTypes, protected numberOfEvents?: number) {} + protected constructor(protected room: Room, protected exportType: exportTypes, protected numberOfEvents?: number) {} protected getTimelineConversation = () : MatrixEvent[] => { if (!this.room) return; @@ -34,37 +33,32 @@ export default abstract class Exporter { return events; }; - protected eventToJson(ev) { - const jsonEvent = ev.toJSON(); - const e = ev.isEncrypted() ? jsonEvent.decrypted : jsonEvent; - if (ev.isEncrypted()) { - e.curve25519Key = ev.getSenderKey(); - e.ed25519Key = ev.getClaimedEd25519Key(); - e.algorithm = ev.getWireContent().algorithm; - e.forwardingCurve25519KeyChain = ev.getForwardingCurve25519KeyChain(); - } else { - delete e.curve25519Key; - delete e.ed25519Key; - delete e.algorithm; - delete e.forwardingCurve25519KeyChain; + protected setEventMetadata = (event: MatrixEvent) => { + const client = MatrixClientPeg.get(); + const roomState = client.getRoom(this.room.roomId).currentState; + event.sender = roomState.getSentinelMember( + event.getSender(), + ); + if (event.getType() === "m.room.member") { + event.target = roomState.getSentinelMember( + event.getStateKey(), + ); } - return e; + return event; } - protected getRequiredEvents = async () : Promise => { const client = MatrixClientPeg.get(); - const eventMapper = client.getEventMapper({ preventReEmit: true }); + const eventMapper = client.getEventMapper(); let prevToken: string|null = null; let limit = this.numberOfEvents || Number.MAX_VALUE; let events: MatrixEvent[] = []; - const stateRes: any[] = []; + while (limit) { const eventsPerCrawl = Math.min(limit, 100); const res: any = await client.createMessagesRequest(this.room.roomId, prevToken, eventsPerCrawl, "b"); - if (res.state) stateRes.push(...res.state); if (res.chunk.length === 0) break; limit -= eventsPerCrawl; @@ -75,79 +69,25 @@ export default abstract class Exporter { prevToken = res.end; } - events = events.reverse() - let stateEvents = []; - if (stateRes !== undefined) { - stateEvents = stateRes.map(eventMapper); - } - - const profiles = {}; - - stateEvents.forEach(ev => { - if (ev.event.content && - ev.event.content.membership === "join") { - profiles[ev.event.sender] = { - displayname: ev.event.content.displayname, - avatar_url: ev.event.content.avatar_url, - }; - } - }); + events = events.reverse(); const decryptionPromises = events .filter(event => event.isEncrypted()) .map(event => { return client.decryptEventIfNeeded(event, { - isRetry: true, - emit: false, + isRetry: true, + emit: false, }); }); - // Let us wait for all the events to get decrypted. + //Wait for all the events to get decrypted. await Promise.all(decryptionPromises); - const eventsWithProfile = events.map((ev) => { - const e = this.eventToJson(ev); + events.map((event) => { + return this.setEventMetadata(event); + }) - let profile: any = {}; - if (e.sender in profiles) profile = profiles[e.sender]; - const object = { - event: e, - profile: profile, - }; - return object; - }); - - const matrixEvents = eventsWithProfile.map(e => { - const matrixEvent = eventMapper(e.event); - - const member = new RoomMember(this.room.roomId, matrixEvent.getSender()); - - member.name = e.profile.displayname; - - const memberEvent = eventMapper( - { - content: { - membership: "join", - avatar_url: e.profile.avatar_url, - displayname: e.profile.displayname, - }, - type: "m.room.member", - event_id: matrixEvent.getId() + ":eventIndex", - room_id: matrixEvent.getRoomId(), - sender: matrixEvent.getSender(), - origin_server_ts: matrixEvent.getTs(), - state_key: matrixEvent.getSender(), - }, - ); - - member.events.member = memberEvent; - matrixEvent.sender = member; - - return matrixEvent; - }); - - - return matrixEvents; + return events; } abstract export(): Promise; diff --git a/src/utils/exportUtils/HtmlExport.tsx b/src/utils/exportUtils/HtmlExport.tsx index 069e47d15b..7a2b615dbd 100644 --- a/src/utils/exportUtils/HtmlExport.tsx +++ b/src/utils/exportUtils/HtmlExport.tsx @@ -77,7 +77,7 @@ export default class HTMLExporter extends Exporter { exportDate, roomName: this.room.name, exporterDetails: ` - ${exporterName ? `${ exporterName }(${ exporter })` : `${ exporter }`} + ${exporterName ? `${ exporterName }(${ exporter })` : `${ exporter }`} `, }); @@ -108,7 +108,7 @@ export default class HTMLExporter extends Exporter {
- ${roomAvatar} + ${roomAvatar}
@@ -172,8 +172,7 @@ export default class HTMLExporter extends Exporter { protected hasAvatar(event: MatrixEvent): boolean { const member = event.sender; - if (member.getMxcAvatarUrl()) return true; - return false; + return !!member.getMxcAvatarUrl(); } protected async saveAvatarIfNeeded(event: MatrixEvent) { @@ -244,8 +243,7 @@ export default class HTMLExporter extends Exporter { } const fileDate = formatFullDateNoDay(new Date(event.getTs())); const [fileName, fileExt] = this.splitFileName(event.getContent().body); - const filePath = fileDirectory + "/" + fileName + '-' + fileDate + fileExt; - return filePath; + return fileDirectory + "/" + fileName + '-' + fileDate + fileExt; } @@ -313,7 +311,7 @@ export default class HTMLExporter extends Exporter { } public async export() { - const res = this.getTimelineConversation(); + const res = await this.getRequiredEvents(); const html = await this.createHTML(res); this.zip.file("index.html", html); @@ -342,7 +340,7 @@ export default class HTMLExporter extends Exporter { const blobPiece = blob.slice(fPointer, fPointer + sliceSize); const reader = new FileReader(); - const waiter = new Promise((resolve, reject) => { + const waiter = new Promise((resolve) => { reader.onloadend = evt => { const arrayBufferNew: any = evt.target.result; const uint8ArrayNew = new Uint8Array(arrayBufferNew); @@ -353,7 +351,7 @@ export default class HTMLExporter extends Exporter { }); await waiter; } - writer.close(); + await writer.close(); return blob; }