diff --git a/src/components/views/dialogs/ExportDialog.tsx b/src/components/views/dialogs/ExportDialog.tsx index 62fa7b5bc6..21239edb3c 100644 --- a/src/components/views/dialogs/ExportDialog.tsx +++ b/src/components/views/dialogs/ExportDialog.tsx @@ -212,151 +212,154 @@ const ExportDialog: React.FC = ({ room, onFinished }) => { const sizePostFix = { _t("MB") }; - let componentToDisplay: JSX.Element; if (exportCancelled) { // Display successful cancellation message - return -

{ _t("The export was cancelled successfully") }

+ return ( + +

{ _t("The export was cancelled successfully") }

- -
+ +
+ ); } else if (exportSuccessful) { // Display successful export message - return -

{ _t("Your messages were successfully exported") }

+ return ( + +

{ _t("Your messages were successfully exported") }

- -
+ +
+ ); } else if (!isExporting) { // Display export settings - -

- {_t( - "Select from the options below to export chats from your timeline", - )} -

- - { _t("Format") } - - setExportFormat(exportFormats[key])} - definitions={exportFormatOptions} - /> - - { _t("Messages") } - - { - setExportType(exportTypes[e.target.value]); - }} + return ( + - { exportTypeOptions } - - { messageCount } +

+ { _t("Select from the options below to export chats from your timeline") } +

- - { _t("Size Limit") } - + { _t("Format") } - setSizeLimit(parseInt(e.target.value))} - /> + setExportFormat(exportFormats[key])} + definitions={exportFormatOptions} + /> - - setAttachments((e.target as HTMLInputElement).checked) - } - > - { _t("Include Attachments") } - + { _t("Messages") } - onFinished(false)} - /> -
+ { + setExportType(exportTypes[e.target.value]); + }} + > + { exportTypeOptions } + + { messageCount } + + { _t("Size Limit") } + + setSizeLimit(parseInt(e.target.value))} + /> + + + setAttachments((e.target as HTMLInputElement).checked) + } + > + { _t("Include Attachments") } + + + onFinished(false)} + /> + + ); } else if (displayCancel) { // Display cancel warning - -

- {_t( - "Are you sure you want to stop exporting your data? If you do, you'll need to start over.", - )} -

- setCancelWarning(false)} - onPrimaryButtonClick={confirmCanel} - /> -
+ return ( + +

+ {_t( + "Are you sure you want to stop exporting your data? If you do, you'll need to start over.", + )} +

+ setCancelWarning(false)} + onPrimaryButtonClick={confirmCanel} + /> +
+ ); } else { // Display progress dialog - return - - + return ( + + + + ); } - - return componentToDisplay; }; export default ExportDialog; diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index cda237f69d..a9bea25851 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -73,16 +73,16 @@ export default class ReplyThread extends React.Component { this.unmounted = false; - if (this.props.forExport) return; + if (this.props.forExport) { + this.context.on("Event.replaced", this.onEventReplaced); + this.room = this.context.getRoom(this.props.parentEv.getRoomId()); + this.room.on("Room.redaction", this.onRoomRedaction); + this.room.on("Room.redactionCancelled", this.onRoomRedaction); - this.context.on("Event.replaced", this.onEventReplaced); - this.room = this.context.getRoom(this.props.parentEv.getRoomId()); - this.room.on("Room.redaction", this.onRoomRedaction); - this.room.on("Room.redactionCancelled", this.onRoomRedaction); - - this.onQuoteClick = this.onQuoteClick.bind(this); - this.canCollapse = this.canCollapse.bind(this); - this.collapse = this.collapse.bind(this); + this.onQuoteClick = this.onQuoteClick.bind(this); + this.canCollapse = this.canCollapse.bind(this); + this.collapse = this.collapse.bind(this); + } } static getParentEventId(ev) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 7489846008..3929cfa1a6 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2261,19 +2261,19 @@ "Enter a number between %(min)s and %(max)s": "Enter a number between %(min)s and %(max)s", "Number of messages": "Number of messages", "MB": "MB", - "Are you sure you want to stop exporting your data? If you do, you'll need to start over.": "Are you sure you want to stop exporting your data? If you do, you'll need to start over.", - "Abort export process": "Abort export process", + "Export Cancelled": "Export Cancelled", + "The export was cancelled successfully": "The export was cancelled successfully", + "Okay": "Okay", + "Export Successful": "Export Successful", + "Your messages were successfully exported": "Your messages were successfully exported", "Export Chat": "Export Chat", "Select from the options below to export chats from your timeline": "Select from the options below to export chats from your timeline", "Format": "Format", "Size Limit": "Size Limit", "Include Attachments": "Include Attachments", "Export": "Export", - "Export Successful": "Export Successful", - "Your messages were successfully exported": "Your messages were successfully exported", - "Okay": "Okay", - "Export Cancelled": "Export Cancelled", - "The export was cancelled successfully": "The export was cancelled successfully", + "Are you sure you want to stop exporting your data? If you do, you'll need to start over.": "Are you sure you want to stop exporting your data? If you do, you'll need to start over.", + "Abort export process": "Abort export process", "Exporting your data...": "Exporting your data...", "Feedback sent": "Feedback sent", "Rate %(brand)s": "Rate %(brand)s", diff --git a/src/utils/exportUtils/JSONExport.ts b/src/utils/exportUtils/JSONExport.ts index cbdc78a711..5c3b44da1b 100644 --- a/src/utils/exportUtils/JSONExport.ts +++ b/src/utils/exportUtils/JSONExport.ts @@ -10,35 +10,30 @@ import { EventType } from "matrix-js-sdk/src/@types/event"; export default class JSONExporter extends Exporter { protected totalSize: number; + protected messages: any[]; constructor(room: Room, exportType: exportTypes, exportOptions: exportOptions) { super(room, exportType, exportOptions); this.totalSize = 0; + this.messages = []; } - protected wrapJSON(json: string): string { + protected createJSONString(): string { const exportDate = formatFullDateNoDayNoTime(new Date()); const creator = this.room.currentState.getStateEvents(EventType.RoomCreate, "")?.getSender(); const creatorName = this.room?.getMember(creator)?.rawDisplayName || creator; const topic = this.room.currentState.getStateEvents(EventType.RoomTopic, "")?.getContent()?.topic || ""; const exporter = this.client.getUserId(); const exporterName = this.room?.getMember(exporter)?.rawDisplayName || exporter; - return `{ - "room_name": "${this.room.name}", - "room_creator": "${creatorName}", - "topic": "${topic}", - "export_date": "${exportDate}", - "exported_by": "${exporterName}", - "messages": [ -${json} - ] -}` - } - - protected indentEachLine(JSONString: string, spaces: number) { - const indent = ' '; - const regex = /^(?!\s*$)/gm; - return JSONString.replace(regex, indent.repeat(spaces)); + const jsonObject = { + room_name: this.room.name, + room_creator: creatorName, + topic, + export_date: exportDate, + exported_by: exporterName, + messages: this.messages, + } + return JSON.stringify(jsonObject, null, 2); } protected async getJSONString(mxEv: MatrixEvent) { @@ -57,18 +52,16 @@ ${json} } const jsonEvent: any = mxEv.toJSON(); const clearEvent = mxEv.isEncrypted() ? jsonEvent.decrypted : jsonEvent; - const jsonString = JSON.stringify(clearEvent, null, 2); - return jsonString.length > 2 ? jsonString + ",\n" : ""; + return clearEvent; } protected async createOutput(events: MatrixEvent[]) { - let content = ""; for (const event of events) { if (this.cancelled) return this.cleanUp(); if (!haveTileForEvent(event)) continue; - content += await this.getJSONString(event); + this.messages.push(await this.getJSONString(event)); } - return this.wrapJSON(this.indentEachLine(content.slice(0, -2), 2)); + return this.createJSONString(); } public async export() {