/* Copyright 2024 New Vector Ltd. Copyright 2019 Michael Telatynski <7t3chguy@gmail.com> Copyright 2016 Aviral Dasgupta SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ import React from "react"; import { _t } from "../../../languageHandler"; import QuestionDialog from "./QuestionDialog"; import Spinner from "../elements/Spinner"; import Heading from "../typography/Heading"; interface IProps { newVersion: DevelopVersionString; version: DevelopVersionString; onFinished: (success: boolean) => void; } type State = Partial>; interface Commit { sha: string; html_url: string; commit: { message: string; }; } const REPOS = ["element-hq/element-web", "matrix-org/matrix-js-sdk"] as const; export type DevelopVersionString = string & { _developVersionString: never }; /* * Parse a version string is compatible with the Changelog dialog ([element-version]-js-[js-sdk-version]) */ export function parseVersion(version: string): Record<(typeof REPOS)[number], string> | null { const parts = version.split("-"); if (parts.length === 3 && parts[1] === "js") { const obj: Record = {}; for (let i = 0; i < REPOS.length; i++) { const commit = parts[2 * i]; obj[REPOS[i]] = commit; } return obj; } return null; } export function checkVersion(version: string): version is DevelopVersionString { return parseVersion(version) !== null; } export default class ChangelogDialog extends React.Component { public constructor(props: IProps) { super(props); this.state = {}; } private async fetchChanges(repo: (typeof REPOS)[number], oldVersion: string, newVersion: string): Promise { const url = `https://riot.im/github/repos/${repo}/compare/${oldVersion}...${newVersion}`; try { const res = await fetch(url); if (!res.ok) { this.setState({ [repo]: res.statusText }); return; } const body = await res.json(); this.setState({ [repo]: body.commits }); } catch (err) { this.setState({ [repo]: err instanceof Error ? err.message : _t("error|unknown") }); } } public componentDidMount(): void { const commits = parseVersion(this.props.version)!; const newCommits = parseVersion(this.props.newVersion)!; for (const repo of REPOS) { this.fetchChanges(repo, commits[repo], newCommits[repo]); } } private elementsForCommit(commit: Commit): JSX.Element { return (
  • {commit.commit.message.split("\n")[0]}
  • ); } public render(): React.ReactNode { const logs = REPOS.map((repo) => { let content; if (this.state[repo] == null) { content = ; } else if (typeof this.state[repo] === "string") { content = _t("update|error_unable_load_commit", { msg: this.state[repo], }); } else { content = (this.state[repo] as Commit[]).map(this.elementsForCommit); } return (
    {repo}
      {content}
    ); }); const content = (
    {this.props.version == null || this.props.newVersion == null ? (

    {_t("update|unavailable")}

    ) : ( logs )}
    ); return ( ); } }