Skip to content

Commit

Permalink
Strict fixes for HtmlExport
Browse files Browse the repository at this point in the history
Signed-off-by: Clark Fischer <[email protected]>
  • Loading branch information
clarkf committed Jan 26, 2023
1 parent 406edfc commit b69b64a
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/DateUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ function withinCurrentYear(prevDate: Date, nextDate: Date): boolean {
return prevDate.getFullYear() === nextDate.getFullYear();
}

export function wantsDateSeparator(prevEventDate: Date, nextEventDate: Date): boolean {
export function wantsDateSeparator(prevEventDate: Date | undefined, nextEventDate: Date | undefined): boolean {
if (!nextEventDate || !prevEventDate) {
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/structures/MessagePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const groupedStateEvents = [
// check if there is a previous event and it has the same sender as this event
// and the types are the same/is in continuedTypes and the time between them is <= CONTINUATION_MAX_INTERVAL
export function shouldFormContinuation(
prevEvent: MatrixEvent,
prevEvent: MatrixEvent | null,
mxEvent: MatrixEvent,
showHiddenEvents: boolean,
threadsEnabled: boolean,
Expand Down Expand Up @@ -821,7 +821,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
// here.
return !this.props.canBackPaginate;
}
return wantsDateSeparator(prevEvent.getDate(), nextEventDate);
return wantsDateSeparator(prevEvent.getDate() || undefined, nextEventDate);
}

// Get a list of read receipts that should be shown next to this event
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/dialogs/MessageEditHistoryDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export default class MessageEditHistoryDialog extends React.PureComponent<IProps
}
const baseEventId = this.props.mxEvent.getId();
allEvents.forEach((e, i) => {
if (!lastEvent || wantsDateSeparator(lastEvent.getDate(), e.getDate())) {
if (!lastEvent || wantsDateSeparator(lastEvent.getDate() || undefined, e.getDate() || undefined)) {
nodes.push(
<li key={e.getTs() + "~"}>
<DateSeparator roomId={e.getRoomId()} ts={e.getTs()} />
Expand Down
7 changes: 5 additions & 2 deletions src/components/views/rooms/SearchResultTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export default class SearchResultTile extends React.Component<IProps> {
// is this a continuation of the previous message?
const continuation =
prevEv &&
!wantsDateSeparator(prevEv.getDate(), mxEv.getDate()) &&
!wantsDateSeparator(prevEv.getDate() || undefined, mxEv.getDate() || undefined) &&
shouldFormContinuation(
prevEv,
mxEv,
Expand All @@ -96,7 +96,10 @@ export default class SearchResultTile extends React.Component<IProps> {
let lastInSection = true;
const nextEv = timeline[j + 1];
if (nextEv) {
const willWantDateSeparator = wantsDateSeparator(mxEv.getDate(), nextEv.getDate());
const willWantDateSeparator = wantsDateSeparator(
mxEv.getDate() || undefined,
nextEv.getDate() || undefined,
);
lastInSection =
willWantDateSeparator ||
mxEv.getSender() !== nextEv.getSender() ||
Expand Down
43 changes: 20 additions & 23 deletions src/utils/exportUtils/HtmlExport.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2021 The Matrix.org Foundation C.I.C.
Copyright 2021, 2023 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -66,7 +66,7 @@ export default class HTMLExporter extends Exporter {
}

protected async getRoomAvatar(): Promise<ReactNode> {
let blob: Blob;
let blob: Blob | undefined = undefined;
const avatarUrl = Avatar.avatarUrlForRoom(this.room, 32, 32, "crop");
const avatarPath = "room.png";
if (avatarUrl) {
Expand All @@ -85,7 +85,7 @@ export default class HTMLExporter extends Exporter {
height={32}
name={this.room.name}
title={this.room.name}
url={blob ? avatarPath : null}
url={blob ? avatarPath : ""}
resizeMethod="crop"
/>
);
Expand All @@ -96,9 +96,9 @@ export default class HTMLExporter extends Exporter {
const roomAvatar = await this.getRoomAvatar();
const exportDate = formatFullDateNoDayNoTime(new Date());
const creator = this.room.currentState.getStateEvents(EventType.RoomCreate, "")?.getSender();
const creatorName = this.room?.getMember(creator)?.rawDisplayName || creator;
const exporter = this.client.getUserId();
const exporterName = this.room?.getMember(exporter)?.rawDisplayName;
const creatorName = (creator ? this.room.getMember(creator)?.rawDisplayName : creator) || creator;
const exporter = this.client.getUserId()!;
const exporterName = this.room.getMember(exporter)?.rawDisplayName;
const topic = this.room.currentState.getStateEvents(EventType.RoomTopic, "")?.getContent()?.topic || "";
const createdText = _t("%(creatorName)s created this room.", {
creatorName,
Expand Down Expand Up @@ -217,20 +217,19 @@ export default class HTMLExporter extends Exporter {
</html>`;
}

protected getAvatarURL(event: MatrixEvent): string {
protected getAvatarURL(event: MatrixEvent): string | undefined {
const member = event.sender;
return (
member.getMxcAvatarUrl() && mediaFromMxc(member.getMxcAvatarUrl()).getThumbnailOfSourceHttp(30, 30, "crop")
);
const avatarUrl = member?.getMxcAvatarUrl();
return avatarUrl ? mediaFromMxc(avatarUrl).getThumbnailOfSourceHttp(30, 30, "crop") : undefined;
}

protected async saveAvatarIfNeeded(event: MatrixEvent): Promise<void> {
const member = event.sender;
const member = event.sender!;
if (!this.avatars.has(member.userId)) {
try {
const avatarUrl = this.getAvatarURL(event);
this.avatars.set(member.userId, true);
const image = await fetch(avatarUrl);
const image = await fetch(avatarUrl!);
const blob = await image.blob();
this.addFile(`users/${member.userId.replace(/:/g, "-")}.png`, blob);
} catch (err) {
Expand All @@ -243,15 +242,15 @@ export default class HTMLExporter extends Exporter {
const ts = event.getTs();
const dateSeparator = (
<li key={ts}>
<DateSeparator forExport={true} key={ts} roomId={event.getRoomId()} ts={ts} />
<DateSeparator forExport={true} key={ts} roomId={event.getRoomId()!} ts={ts} />
</li>
);
return renderToStaticMarkup(dateSeparator);
}

protected async needsDateSeparator(event: MatrixEvent, prevEvent: MatrixEvent): Promise<boolean> {
if (prevEvent == null) return true;
return wantsDateSeparator(prevEvent.getDate(), event.getDate());
protected async needsDateSeparator(event: MatrixEvent, prevEvent: MatrixEvent | null): Promise<boolean> {
if (!prevEvent) return true;
return wantsDateSeparator(prevEvent.getDate() || undefined, event.getDate() || undefined);
}

public getEventTile(mxEv: MatrixEvent, continuation: boolean): JSX.Element {
Expand All @@ -264,9 +263,7 @@ export default class HTMLExporter extends Exporter {
isRedacted={mxEv.isRedacted()}
replacingEventId={mxEv.replacingEventId()}
forExport={true}
readReceipts={null}
alwaysShowTimestamps={true}
readReceiptMap={null}
showUrlPreview={false}
checkUnmounting={() => false}
isTwelveHour={false}
Expand All @@ -275,7 +272,6 @@ export default class HTMLExporter extends Exporter {
permalinkCreator={this.permalinkCreator}
lastSuccessful={false}
isSelectedEvent={false}
getRelationsForEvent={null}
showReactions={false}
layout={Layout.Group}
showReadReceipts={false}
Expand All @@ -286,7 +282,8 @@ export default class HTMLExporter extends Exporter {
}

protected async getEventTileMarkup(mxEv: MatrixEvent, continuation: boolean, filePath?: string): Promise<string> {
const hasAvatar = !!this.getAvatarURL(mxEv);
const avatarUrl = this.getAvatarURL(mxEv);
const hasAvatar = !!avatarUrl;
if (hasAvatar) await this.saveAvatarIfNeeded(mxEv);
const EventTile = this.getEventTile(mxEv, continuation);
let eventTileMarkup: string;
Expand All @@ -312,8 +309,8 @@ export default class HTMLExporter extends Exporter {
eventTileMarkup = eventTileMarkup.replace(/<span class="mx_MFileBody_info_icon".*?>.*?<\/span>/, "");
if (hasAvatar) {
eventTileMarkup = eventTileMarkup.replace(
encodeURI(this.getAvatarURL(mxEv)).replace(/&/g, "&amp;"),
`users/${mxEv.sender.userId.replace(/:/g, "-")}.png`,
encodeURI(avatarUrl).replace(/&/g, "&amp;"),
`users/${mxEv.sender!.userId.replace(/:/g, "-")}.png`,
);
}
return eventTileMarkup;
Expand Down Expand Up @@ -403,7 +400,7 @@ export default class HTMLExporter extends Exporter {
if (this.cancelled) return this.cleanUp();
if (!haveRendererForEvent(event, false)) continue;

content += this.needsDateSeparator(event, prevEvent) ? this.getDateSeparator(event) : "";
content += (await this.needsDateSeparator(event, prevEvent)) ? this.getDateSeparator(event) : "";
const shouldBeJoined =
!this.needsDateSeparator(event, prevEvent) &&
shouldFormContinuation(prevEvent, event, false, this.threadsEnabled);
Expand Down

0 comments on commit b69b64a

Please sign in to comment.