diff --git a/src/utils/exportUtils/Exporter.ts b/src/utils/exportUtils/Exporter.ts index 39ab352b94..5f94405568 100644 --- a/src/utils/exportUtils/Exporter.ts +++ b/src/utils/exportUtils/Exporter.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { MatrixEvent, Room, Direction } from "matrix-js-sdk/src/matrix"; +import { Direction, MatrixEvent, Room } from "matrix-js-sdk/src/matrix"; import { saveAs } from "file-saver"; import { logger } from "matrix-js-sdk/src/logger"; import sanitizeFilename from "sanitize-filename"; @@ -135,9 +135,6 @@ export default abstract class Exporter { // when export type is LastNMessages limit = this.exportOptions.numberOfMessages!; break; - case ExportType.Timeline: - limit = 40; - break; default: limit = 10 ** 8; } @@ -148,58 +145,60 @@ export default abstract class Exporter { const eventMapper = this.room.client.getEventMapper(); let prevToken: string | null = null; - let limit = this.getLimit(); - const events: MatrixEvent[] = []; - while (limit) { - const eventsPerCrawl = Math.min(limit, 1000); - const res = await this.room.client.createMessagesRequest( - this.room.roomId, - prevToken, - eventsPerCrawl, - Direction.Backward, - ); - - if (this.cancelled) { - this.cleanUp(); - return []; - } - - if (res.chunk.length === 0) break; - - limit -= res.chunk.length; - - const matrixEvents: MatrixEvent[] = res.chunk.map(eventMapper); - - 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); - } - - if (this.exportType === ExportType.LastNMessages) { - this.updateProgress( - _t("Fetched %(count)s events out of %(total)s", { - count: events.length, - total: this.exportOptions.numberOfMessages, - }), + let events: MatrixEvent[] = []; + if (this.exportType === ExportType.Timeline) { + events = this.room.getLiveTimeline().getEvents(); + } else { + let limit = this.getLimit(); + while (limit) { + const eventsPerCrawl = Math.min(limit, 1000); + const res = await this.room.client.createMessagesRequest( + this.room.roomId, + prevToken, + eventsPerCrawl, + Direction.Backward, ); - } else { - this.updateProgress( - _t("Fetched %(count)s events so far", { - count: events.length, - }), - ); - } - prevToken = res.end ?? null; - } - // Reverse the events so that we preserve the order - for (let i = 0; i < Math.floor(events.length / 2); i++) { - [events[i], events[events.length - i - 1]] = [events[events.length - i - 1], events[i]]; + if (this.cancelled) { + this.cleanUp(); + return []; + } + + if (res.chunk.length === 0) break; + + limit -= res.chunk.length; + + const matrixEvents: MatrixEvent[] = res.chunk.map(eventMapper); + + 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); + } + + if (this.exportType === ExportType.LastNMessages) { + this.updateProgress( + _t("Fetched %(count)s events out of %(total)s", { + count: events.length, + total: this.exportOptions.numberOfMessages, + }), + ); + } else { + this.updateProgress( + _t("Fetched %(count)s events so far", { + count: events.length, + }), + ); + } + + prevToken = res.end ?? null; + } + // Reverse the events so that we preserve the order + events.reverse(); } const decryptionPromises = events diff --git a/test/utils/exportUtils/HTMLExport-test.ts b/test/utils/exportUtils/HTMLExport-test.ts index 53512dbad1..30f37d9a7a 100644 --- a/test/utils/exportUtils/HTMLExport-test.ts +++ b/test/utils/exportUtils/HTMLExport-test.ts @@ -152,9 +152,10 @@ describe("HTMLExport", () => { const stubOptions: IExportOptions = { attachmentsIncluded: false, maxSize: 50000000, + numberOfMessages: 40, }; const stubRoom = mkStubRoom("!myroom:example.org", roomName, client); - const exporter = new HTMLExporter(stubRoom, ExportType.Timeline, stubOptions, () => {}); + const exporter = new HTMLExporter(stubRoom, ExportType.LastNMessages, stubOptions, () => {}); expect(exporter.destinationFileName).toMatchSnapshot(); @@ -203,10 +204,11 @@ describe("HTMLExport", () => { const exporter = new HTMLExporter( room, - ExportType.Timeline, + ExportType.LastNMessages, { attachmentsIncluded: false, maxSize: 1_024 * 1_024, + numberOfMessages: 40, }, () => {}, ); @@ -234,10 +236,11 @@ describe("HTMLExport", () => { const exporter = new HTMLExporter( room, - ExportType.Timeline, + ExportType.LastNMessages, { attachmentsIncluded: false, maxSize: 1_024 * 1_024, + numberOfMessages: 40, }, () => {}, ); @@ -264,10 +267,11 @@ describe("HTMLExport", () => { const exporter = new HTMLExporter( room, - ExportType.Timeline, + ExportType.LastNMessages, { attachmentsIncluded: false, maxSize: 1_024 * 1_024, + numberOfMessages: 40, }, () => {}, ); @@ -287,10 +291,11 @@ describe("HTMLExport", () => { const exporter = new HTMLExporter( room, - ExportType.Timeline, + ExportType.LastNMessages, { attachmentsIncluded: false, maxSize: 1_024 * 1_024, + numberOfMessages: 40, }, () => {}, ); @@ -321,10 +326,11 @@ describe("HTMLExport", () => { const exporter = new HTMLExporter( room, - ExportType.Timeline, + ExportType.LastNMessages, { attachmentsIncluded: false, maxSize: 1_024 * 1_024, + numberOfMessages: 40, }, () => {}, ); @@ -342,10 +348,11 @@ describe("HTMLExport", () => { const exporter = new HTMLExporter( room, - ExportType.Timeline, + ExportType.LastNMessages, { attachmentsIncluded: false, maxSize: 1_024 * 1_024, + numberOfMessages: 40, }, () => {}, ); @@ -364,10 +371,11 @@ describe("HTMLExport", () => { const exporter = new HTMLExporter( room, - ExportType.Timeline, + ExportType.LastNMessages, { attachmentsIncluded: true, maxSize: 1_024 * 1_024, + numberOfMessages: 40, }, () => {}, ); @@ -392,10 +400,11 @@ describe("HTMLExport", () => { const exporter = new HTMLExporter( room, - ExportType.Timeline, + ExportType.LastNMessages, { attachmentsIncluded: true, maxSize: 1_024 * 1_024, + numberOfMessages: 40, }, () => {}, ); @@ -426,10 +435,11 @@ describe("HTMLExport", () => { const exporter = new HTMLExporter( room, - ExportType.Timeline, + ExportType.LastNMessages, { attachmentsIncluded: true, maxSize: 1_024 * 1_024, + numberOfMessages: 40, }, () => {}, ); @@ -451,10 +461,11 @@ describe("HTMLExport", () => { const exporter = new HTMLExporter( room, - ExportType.Timeline, + ExportType.LastNMessages, { attachmentsIncluded: false, maxSize: 1_024 * 1_024, + numberOfMessages: 40, }, () => {}, ); @@ -535,10 +546,11 @@ describe("HTMLExport", () => { const exporter = new HTMLExporter( room, - ExportType.Timeline, + ExportType.LastNMessages, { attachmentsIncluded: false, maxSize: 1_024 * 1_024, + numberOfMessages: 40, }, () => {}, ); @@ -551,4 +563,36 @@ describe("HTMLExport", () => { expect(html).not.toContain(`${topic}`); expect(html).toContain(`Topic: ${escapeHtml(topic)}`); }); + + it("should not make /messages requests when exporting 'Current Timeline'", async () => { + client.createMessagesRequest.mockRejectedValue(new Error("Should never be called")); + room.addLiveEvents([ + new MatrixEvent({ + event_id: `$eventId`, + type: EventType.RoomMessage, + sender: client.getSafeUserId(), + origin_server_ts: 123456789, + content: { + msgtype: "m.text", + body: `testing testing`, + }, + }), + ]); + + const exporter = new HTMLExporter( + room, + ExportType.Timeline, + { + attachmentsIncluded: false, + maxSize: 1_024 * 1_024, + }, + () => {}, + ); + + await exporter.export(); + + const file = getMessageFile(exporter); + expect(await file.text()).toContain("testing testing"); + expect(client.createMessagesRequest).not.toHaveBeenCalled(); + }); });