diff --git a/src/DateUtils.ts b/src/DateUtils.ts index 20227354f02..bac7481a4f2 100644 --- a/src/DateUtils.ts +++ b/src/DateUtils.ts @@ -177,6 +177,10 @@ export function formatFullDateNoDay(date: Date) { }); } +export function formatFullDateNoDayISO(date: Date) { + return date.toISOString(); +} + export function formatFullDateNoDayNoTime(date: Date) { return ( date.getFullYear() + diff --git a/src/utils/exportUtils/Exporter.ts b/src/utils/exportUtils/Exporter.ts index 7b4a7bf342f..d7603463119 100644 --- a/src/utils/exportUtils/Exporter.ts +++ b/src/utils/exportUtils/Exporter.ts @@ -22,14 +22,13 @@ import { saveAs } from "file-saver"; import { logger } from "matrix-js-sdk/src/logger"; import { MatrixClientPeg } from "../../MatrixClientPeg"; -import { ExportType, IExportOptions } from "./exportUtils"; +import { ExportType, IExportOptions, formatFilename } from "./exportUtils"; import { decryptFile } from "../DecryptFile"; import { mediaFromContent } from "../../customisations/Media"; import { formatFullDateNoDay } from "../../DateUtils"; import { isVoiceMessage } from "../EventUtils"; import { IMediaEventContent } from "../../customisations/models/IMediaEventContent"; import { _t } from "../../languageHandler"; -import SdkConfig from "../../SdkConfig"; type BlobFile = { name: string; @@ -76,8 +75,7 @@ export default abstract class Exporter { } protected async downloadZIP(): Promise { - const brand = SdkConfig.get().brand; - const filenameWithoutExt = `${brand} - Chat Export - ${formatFullDateNoDay(new Date())}`; + const filenameWithoutExt = formatFilename(this.room.name); const filename = `${filenameWithoutExt}.zip`; const { default: JSZip } = await import('jszip'); diff --git a/src/utils/exportUtils/JSONExport.ts b/src/utils/exportUtils/JSONExport.ts index b0b4b330b06..09792fb9ca4 100644 --- a/src/utils/exportUtils/JSONExport.ts +++ b/src/utils/exportUtils/JSONExport.ts @@ -20,8 +20,8 @@ import { EventType } from "matrix-js-sdk/src/@types/event"; import { logger } from "matrix-js-sdk/src/logger"; import Exporter from "./Exporter"; -import { formatFullDateNoDay, formatFullDateNoDayNoTime } from "../../DateUtils"; -import { ExportType, IExportOptions } from "./exportUtils"; +import { formatFullDateNoDayNoTime } from "../../DateUtils"; +import { ExportType, formatFilename, IExportOptions } from "./exportUtils"; import { _t } from "../../languageHandler"; import { haveRendererForEvent } from "../../events/EventTileFactory"; @@ -108,7 +108,7 @@ export default class JSONExporter extends Exporter { this.addFile("export.json", new Blob([text])); await this.downloadZIP(); } else { - const fileName = `matrix-export-${formatFullDateNoDay(new Date())}.json`; + const fileName = `${formatFilename(this.room.name)}.json`; this.downloadPlainText(fileName, text); } diff --git a/src/utils/exportUtils/PlainTextExport.ts b/src/utils/exportUtils/PlainTextExport.ts index e86c56e9f4c..156adbcba71 100644 --- a/src/utils/exportUtils/PlainTextExport.ts +++ b/src/utils/exportUtils/PlainTextExport.ts @@ -19,9 +19,8 @@ import { IContent, MatrixEvent } from "matrix-js-sdk/src/models/event"; import { logger } from "matrix-js-sdk/src/logger"; import Exporter from "./Exporter"; -import { formatFullDateNoDay } from "../../DateUtils"; import { _t } from "../../languageHandler"; -import { ExportType, IExportOptions } from "./exportUtils"; +import { ExportType, formatFilename, IExportOptions } from "./exportUtils"; import { textForEvent } from "../../TextForEvent"; import { haveRendererForEvent } from "../../events/EventTileFactory"; @@ -136,7 +135,7 @@ export default class PlainTextExporter extends Exporter { this.addFile("export.txt", new Blob([text])); await this.downloadZIP(); } else { - const fileName = `matrix-export-${formatFullDateNoDay(new Date())}.txt`; + const fileName = `${formatFilename(this.room.name)}.txt`; this.downloadPlainText(fileName, text); } diff --git a/src/utils/exportUtils/exportUtils.ts b/src/utils/exportUtils/exportUtils.ts index 139e3a37407..e41e634fbcf 100644 --- a/src/utils/exportUtils/exportUtils.ts +++ b/src/utils/exportUtils/exportUtils.ts @@ -15,6 +15,8 @@ limitations under the License. */ import { _t } from "../../languageHandler"; +import { formatFullDateNoDayISO } from "../../DateUtils"; +import SdkConfig from "../../SdkConfig"; export enum ExportFormat { Html = "Html", @@ -63,3 +65,20 @@ export interface IExportOptions { attachmentsIncluded: boolean; maxSize: number; } + +export const formatFilename = (roomName: string): string => { + const brand = SdkConfig.get().brand; + const regex = /([^\x20-~.]+)|([\\/.:?"<>|]+)/g; + let filename = ""; + + if (roomName.match(regex)?.length > 0) { + const roomnameStripped = roomName.replace(regex, ""); + filename = `${brand}-${roomnameStripped}-${formatFullDateNoDayISO(new Date())}`; + //after stripping off invalid characters but left with empty string + if (roomnameStripped === "") filename = `${brand}-Chat-Export-${(new Date()).toISOString()}`; + } else { + filename = `${brand}-${roomName}-${(new Date()).toISOString()}`; + } + + return filename; +};