/* Copyright 2024 New Vector Ltd. Copyright 2020 The Matrix.org Foundation C.I.C. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE files in the repository root for full details. */ import React, { type ReactNode } from "react"; import BaseDialog from "./BaseDialog"; import { _t } from "../../../languageHandler"; import { EchoStore } from "../../../stores/local-echo/EchoStore"; import { formatTime } from "../../../DateUtils"; import SettingsStore from "../../../settings/SettingsStore"; import { RoomEchoContext } from "../../../stores/local-echo/RoomEchoContext"; import RoomAvatar from "../avatars/RoomAvatar"; import { TransactionStatus } from "../../../stores/local-echo/EchoTransaction"; import Spinner from "../elements/Spinner"; import AccessibleButton from "../elements/AccessibleButton"; import { UPDATE_EVENT } from "../../../stores/AsyncStore"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; interface IProps { onFinished(): void; } export default class ServerOfflineDialog extends React.PureComponent { public componentDidMount(): void { EchoStore.instance.on(UPDATE_EVENT, this.onEchosUpdated); } public componentWillUnmount(): void { EchoStore.instance.off(UPDATE_EVENT, this.onEchosUpdated); } private onEchosUpdated = (): void => { this.forceUpdate(); // no state to worry about }; private renderTimeline(): ReactNode[] { return EchoStore.instance.contexts.map((c, i) => { if (!c.firstFailedTime) return null; // not useful if (!(c instanceof RoomEchoContext)) throw new Error("Cannot render unknown context: " + c.constructor.name); const header = (
{c.room.name}
); const entries = c.transactions .filter((t) => t.status === TransactionStatus.Error || t.didPreviouslyFail) .map((t, j) => { let button = ; if (t.status === TransactionStatus.Error) { button = ( t.run()}> {_t("action|resend")} ); } return (
{t.auditName} {button}
); }); return (
{formatTime(c.firstFailedTime, SettingsStore.getValue("showTwelveHourTimestamps"))}
{header} {entries}
); }); } public render(): React.ReactNode { let timeline = this.renderTimeline().filter((c) => !!c); // remove nulls for next check if (timeline.length === 0) { timeline = [
{_t("server_offline|empty_timeline")}
]; } const serverName = MatrixClientPeg.safeGet().getDomain(); return (

{_t("server_offline|description")}

  • {_t("server_offline|description_1", { serverName })}
  • {_t("server_offline|description_2")}
  • {_t("server_offline|description_3")}
  • {_t("server_offline|description_4")}
  • {_t("server_offline|description_5")}
  • {_t("server_offline|description_6")}
  • {_t("server_offline|description_7")}
  • {_t("server_offline|description_8")}

{_t("server_offline|recent_changes_heading")}

{timeline}
); } }