Refactor
This commit is contained in:
parent
183166c460
commit
4c22d1f2a1
3 changed files with 55 additions and 52 deletions
|
@ -1,7 +1,36 @@
|
||||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
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";
|
||||||
|
|
||||||
export abstract class Exporter {
|
export abstract class Exporter {
|
||||||
constructor(protected res: MatrixEvent[], protected room: Room) {}
|
constructor(protected room: Room) {}
|
||||||
|
|
||||||
|
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 = timelineWindow.getEvents();
|
||||||
|
|
||||||
|
// Clone and reverse the events so that we preserve the order
|
||||||
|
arrayFastClone(events)
|
||||||
|
.reverse()
|
||||||
|
.forEach(event => {
|
||||||
|
cli.decryptEventIfNeeded(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
return events;
|
||||||
|
};
|
||||||
|
|
||||||
abstract export(): Promise<Blob>;
|
abstract export(): Promise<Blob>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,25 +11,25 @@ import { Layout } from "../../settings/Layout";
|
||||||
import { shouldFormContinuation } from "../../components/structures/MessagePanel";
|
import { shouldFormContinuation } from "../../components/structures/MessagePanel";
|
||||||
import { formatFullDateNoDay, formatFullDateNoDayNoTime, wantsDateSeparator } from "../../DateUtils";
|
import { formatFullDateNoDay, formatFullDateNoDayNoTime, wantsDateSeparator } from "../../DateUtils";
|
||||||
import { RoomPermalinkCreator } from "../permalinks/Permalinks";
|
import { RoomPermalinkCreator } from "../permalinks/Permalinks";
|
||||||
|
import { _t } from "../../languageHandler";
|
||||||
|
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
||||||
|
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||||
import * as ponyfill from "web-streams-polyfill/ponyfill"
|
import * as ponyfill from "web-streams-polyfill/ponyfill"
|
||||||
import * as Avatar from "../../Avatar";
|
import * as Avatar from "../../Avatar";
|
||||||
import EventTile, { haveTileForEvent } from "../../components/views/rooms/EventTile";
|
import EventTile, { haveTileForEvent } from "../../components/views/rooms/EventTile";
|
||||||
import DateSeparator from "../../components/views/messages/DateSeparator";
|
import DateSeparator from "../../components/views/messages/DateSeparator";
|
||||||
|
import BaseAvatar from "../../components/views/avatars/BaseAvatar";
|
||||||
import exportCSS from "./exportCSS";
|
import exportCSS from "./exportCSS";
|
||||||
import exportJS from "./exportJS";
|
import exportJS from "./exportJS";
|
||||||
import BaseAvatar from "../../components/views/avatars/BaseAvatar";
|
|
||||||
import exportIcons from "./exportIcons";
|
import exportIcons from "./exportIcons";
|
||||||
import { _t } from "../../languageHandler";
|
|
||||||
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
|
||||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
|
||||||
|
|
||||||
export default class HTMLExporter extends Exporter {
|
export default class HTMLExporter extends Exporter {
|
||||||
protected zip: JSZip;
|
protected zip: JSZip;
|
||||||
protected avatars: Map<string, boolean>;
|
protected avatars: Map<string, boolean>;
|
||||||
protected permalinkCreator: RoomPermalinkCreator;
|
protected permalinkCreator: RoomPermalinkCreator;
|
||||||
|
|
||||||
constructor(res: MatrixEvent[], room: Room) {
|
constructor(room: Room) {
|
||||||
super(res, room);
|
super(room);
|
||||||
this.zip = new JSZip();
|
this.zip = new JSZip();
|
||||||
this.avatars = new Map<string, boolean>();
|
this.avatars = new Map<string, boolean>();
|
||||||
this.permalinkCreator = new RoomPermalinkCreator(this.room);
|
this.permalinkCreator = new RoomPermalinkCreator(this.room);
|
||||||
|
@ -57,16 +57,16 @@ export default class HTMLExporter extends Exporter {
|
||||||
return renderToStaticMarkup(avatar);
|
return renderToStaticMarkup(avatar);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async wrapHTML(content: string, room: Room) {
|
protected async wrapHTML(content: string) {
|
||||||
const roomAvatar32 = await this.getRoomAvatar(32);
|
const roomAvatar32 = await this.getRoomAvatar(32);
|
||||||
const exportDate = formatFullDateNoDayNoTime(new Date());
|
const exportDate = formatFullDateNoDayNoTime(new Date());
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const creator = room.currentState.getStateEvents(EventType.RoomCreate, "")?.getSender();
|
const creator = this.room.currentState.getStateEvents(EventType.RoomCreate, "")?.getSender();
|
||||||
const creatorName = room?.getMember(creator)?.rawDisplayName || creator;
|
const creatorName = this.room?.getMember(creator)?.rawDisplayName || creator;
|
||||||
const exporter = cli.getUserId();
|
const exporter = cli.getUserId();
|
||||||
const exporterName = room?.getMember(exporter)?.rawDisplayName;
|
const exporterName = this.room?.getMember(exporter)?.rawDisplayName;
|
||||||
const topic = room.currentState.getStateEvents(EventType.RoomTopic, "")?.getContent()?.topic
|
const topic = this.room.currentState.getStateEvents(EventType.RoomTopic, "")?.getContent()?.topic
|
||||||
|| room.topic || "";
|
|| this.room.topic || "";
|
||||||
const createdText = _t("%(creatorName)s created this room.", {
|
const createdText = _t("%(creatorName)s created this room.", {
|
||||||
creatorName,
|
creatorName,
|
||||||
});
|
});
|
||||||
|
@ -74,7 +74,7 @@ export default class HTMLExporter extends Exporter {
|
||||||
const exportedText = _t(`This is the start of export of <b>%(roomName)s</b>.
|
const exportedText = _t(`This is the start of export of <b>%(roomName)s</b>.
|
||||||
Exported by %(exporterDetails)s at %(exportDate)s. `, {
|
Exported by %(exporterDetails)s at %(exportDate)s. `, {
|
||||||
exportDate,
|
exportDate,
|
||||||
roomName: room.name,
|
roomName: this.room.name,
|
||||||
exporterDetails: `<a href="https://matrix.to/#/${exporter}" target="_blank" rel="noopener noreferrer">
|
exporterDetails: `<a href="https://matrix.to/#/${exporter}" target="_blank" rel="noopener noreferrer">
|
||||||
${exporterName ? `<b>${ exporterName }</b>(${ exporter })` : `<b>${ exporter }</b>`}
|
${exporterName ? `<b>${ exporterName }</b>(${ exporter })` : `<b>${ exporter }</b>`}
|
||||||
</a>`,
|
</a>`,
|
||||||
|
@ -115,9 +115,9 @@ export default class HTMLExporter extends Exporter {
|
||||||
<div
|
<div
|
||||||
dir="auto"
|
dir="auto"
|
||||||
class="mx_RoomHeader_nametext"
|
class="mx_RoomHeader_nametext"
|
||||||
title="${room.name}"
|
title="${this.room.name}"
|
||||||
>
|
>
|
||||||
${room.name}
|
${this.room.name}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mx_RoomHeader_topic" dir="auto"> ${topic} </div>
|
<div class="mx_RoomHeader_topic" dir="auto"> ${topic} </div>
|
||||||
|
@ -144,7 +144,7 @@ export default class HTMLExporter extends Exporter {
|
||||||
>
|
>
|
||||||
<div class="mx_NewRoomIntro">
|
<div class="mx_NewRoomIntro">
|
||||||
${roomAvatar52}
|
${roomAvatar52}
|
||||||
<h2> ${room.name} </h2>
|
<h2> ${this.room.name} </h2>
|
||||||
<p> ${createdText} <br/><br/> ${exportedText} </p>
|
<p> ${createdText} <br/><br/> ${exportedText} </p>
|
||||||
<p> ${topicText} </p>
|
<p> ${topicText} </p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -294,7 +294,7 @@ export default class HTMLExporter extends Exporter {
|
||||||
return renderToStaticMarkup(eventTile);
|
return renderToStaticMarkup(eventTile);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async createHTML(events: MatrixEvent[], room: Room) {
|
protected async createHTML(events: MatrixEvent[]) {
|
||||||
let content = "";
|
let content = "";
|
||||||
let prevEvent = null;
|
let prevEvent = null;
|
||||||
for (const event of events) {
|
for (const event of events) {
|
||||||
|
@ -308,17 +308,21 @@ export default class HTMLExporter extends Exporter {
|
||||||
content += body;
|
content += body;
|
||||||
prevEvent = event;
|
prevEvent = event;
|
||||||
}
|
}
|
||||||
return await this.wrapHTML(content, room);
|
return await this.wrapHTML(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async export() {
|
public async export() {
|
||||||
const html = await this.createHTML(this.res, this.room);
|
const res = this.getTimelineConversation();
|
||||||
|
const html = await this.createHTML(res);
|
||||||
|
|
||||||
this.zip.file("index.html", html);
|
this.zip.file("index.html", html);
|
||||||
this.zip.file("css/style.css", exportCSS);
|
this.zip.file("css/style.css", exportCSS);
|
||||||
this.zip.file("js/script.js", exportJS);
|
this.zip.file("js/script.js", exportJS);
|
||||||
|
|
||||||
for (const iconName in exportIcons) {
|
for (const iconName in exportIcons) {
|
||||||
this.zip.file(`icons/${iconName}`, exportIcons[iconName]);
|
this.zip.file(`icons/${iconName}`, exportIcons[iconName]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const filename = `matrix-export-${formatFullDateNoDay(new Date())}.zip`;
|
const filename = `matrix-export-${formatFullDateNoDay(new Date())}.zip`;
|
||||||
|
|
||||||
//Generate the zip file asynchronously
|
//Generate the zip file asynchronously
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
import { Room } from 'matrix-js-sdk/src/models/room';
|
||||||
import { arrayFastClone } from "../arrays";
|
|
||||||
import { TimelineWindow } from "matrix-js-sdk/src/timeline-window";
|
|
||||||
import Room from 'matrix-js-sdk/src/models/room';
|
|
||||||
import HTMLExporter from "./HtmlExport";
|
import HTMLExporter from "./HtmlExport";
|
||||||
|
|
||||||
export enum exportFormats {
|
export enum exportFormats {
|
||||||
|
@ -14,37 +11,10 @@ export enum exportOptions {
|
||||||
TIMELINE = "TIMELINE",
|
TIMELINE = "TIMELINE",
|
||||||
}
|
}
|
||||||
|
|
||||||
const getTimelineConversation = (room: Room) => {
|
|
||||||
if (!room) return;
|
|
||||||
|
|
||||||
const cli = MatrixClientPeg.get();
|
|
||||||
|
|
||||||
const timelineSet = room.getUnfilteredTimelineSet();
|
|
||||||
|
|
||||||
const timelineWindow = new TimelineWindow(
|
|
||||||
cli, timelineSet,
|
|
||||||
{windowLimit: Number.MAX_VALUE});
|
|
||||||
|
|
||||||
timelineWindow.load(null, 30);
|
|
||||||
|
|
||||||
const events = timelineWindow.getEvents();
|
|
||||||
|
|
||||||
// Clone and reverse the events so that we preserve the order
|
|
||||||
arrayFastClone(events)
|
|
||||||
.reverse()
|
|
||||||
.forEach(event => {
|
|
||||||
cli.decryptEventIfNeeded(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
return events;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const exportConversationalHistory = async (room: Room, format: string, options) => {
|
const exportConversationalHistory = async (room: Room, format: string, options) => {
|
||||||
const res = getTimelineConversation(room);
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case exportFormats.HTML:
|
case exportFormats.HTML:
|
||||||
await new HTMLExporter(res, room).export();
|
await new HTMLExporter(room).export();
|
||||||
break;
|
break;
|
||||||
case exportFormats.JSON:
|
case exportFormats.JSON:
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue