Skip to content

Commit

Permalink
Add a changelog and improve contributors section
Browse files Browse the repository at this point in the history
This improves the contributors section in the About page. It now uses
flexbox to dynamically place the contributors. Additionally their avatar
is now being shown.

Also the ten most recent changes are now being shown in the About page.
The information is extracted from the git history. The idea is to mark
commit messages with a special changelog section at the end that's
specifically meant to be shown as a user facing change. It can be
arbitrary markdown and looks like this (which is also the first one):

Changelog: The About page now shows the most recent changes. The
contributors section has also been improved. It now shows the avatar of
each contributor.
  • Loading branch information
CryZe committed May 31, 2024
1 parent 909d615 commit 8bfdfae
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 28 deletions.
49 changes: 34 additions & 15 deletions src/css/About.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
@import 'mobile';
@import 'variables';

$text-width: 400px;
$icon-size: 40px;
$title-font-size: 40px;
$build-version-font-size: 12px;
Expand Down Expand Up @@ -37,33 +36,53 @@ $link-color: #56b0ff;
font-size: $build-version-font-size;
}

.contributors-header {
margin-bottom: 0;
h2 {
margin-bottom: $ui-large-margin;
}

.contributor {
margin-block-start: 0.5em;
margin-block-end: 0.5em;
a {
color: $link-color;
}

.changelog {
margin-left: $ui-large-margin;

&:last-child {
margin-block-end: 0;
>div {
margin: $ui-large-margin 0 $ui-large-margin $ui-large-margin;
}
}

a {
color: $link-color;
}
.contributors {
margin: 0 auto;
display: flex;
flex-wrap: wrap;
gap: 14px;
justify-content: space-evenly;
align-items: end;
font-size: 14px;

p {
max-width: $text-width;
a {
display: flex;
align-items: center;
flex-direction: column;
gap: 4px;

@include mobile {
max-width: 100%;
img {
width: 42px;
height: 42px;
border-radius: 50%;
}
}
}

@include mobile {
box-sizing: border-box;
}
}

max-width: 700px;

@include mobile {
max-width: 100%;
}
}
14 changes: 13 additions & 1 deletion src/type-definitions/webpack-globals.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
declare const BUILD_DATE: string;
declare const COMMIT_HASH: string;
declare const CONTRIBUTORS_LIST: string[];
declare const CONTRIBUTORS_LIST: Contributor[];
declare const CHANGELOG: ChangelogEntry[];

declare interface Contributor {
id: string,
name: string,
}

declare interface ChangelogEntry {
id: string,
message: string,
date: string,
}
45 changes: 37 additions & 8 deletions src/ui/About.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from "react";

import LiveSplitIcon from "../assets/icon.svg";
import { renderMarkdown } from "../util/Markdown";

import "../css/About.scss";

Expand All @@ -13,6 +14,11 @@ interface Callbacks {
openTimerView(): void,
}

const changelogRenderSettings = {
softBreak: false,
escapeHtml: false,
};

export class About extends React.Component<Props> {
public render() {
const renderedView = this.renderView();
Expand All @@ -21,6 +27,8 @@ export class About extends React.Component<Props> {
}

private renderView() {
const idealAvatarResolution = Math.round(devicePixelRatio * 42);

return (
<div className="about">
<div className="about-inner-container">
Expand All @@ -42,14 +50,35 @@ export class About extends React.Component<Props> {
View Source Code on GitHub
</a>
</p>
<h2 className="contributors-header">Contributors</h2>
{
CONTRIBUTORS_LIST.map((contributor) => (
<p className="contributor">
<a href={`https://github.com/${contributor}`} target="_blank">{contributor}</a>
</p>
))
}
<h2>Recent Changes</h2>
<div className="changelog">
{
CHANGELOG.map((change) => (
<>
<a href={`https://github.com/LiveSplit/LiveSplitOne/commit/${change.id}`} target="_blank">
{change.date}
</a>
<div>
{renderMarkdown(change.message, changelogRenderSettings)}
</div>
</>
))
}
</div>
<h2>Contributors</h2>
<div className="contributors">
{
CONTRIBUTORS_LIST.map((contributor) => (
<a href={`https://github.com/${contributor.name}`} target="_blank">
<img
src={`https://avatars.githubusercontent.com/u/${contributor.id}?s=${idealAvatarResolution}&v=4`}
onError={(e) => (e.target as any).remove()}
/>
{contributor.name}
</a>
))
}
</div>
</div>
</div>
);
Expand Down
9 changes: 6 additions & 3 deletions src/util/Markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ export function replaceFlag(countryCode: string): JSX.Element {
return <img className="flag" src={url} alt={countryCode} />;
}

export function renderMarkdown(markdown: string): JSX.Element {
export function renderMarkdown(markdown: string, options: {
softBreak?: boolean,
escapeHtml?: boolean,
} = {}): JSX.Element {
const markdownWithEmotes = replaceTwitchEmotes(markdown);
const parsed = new CommonMarkParser().parse(markdownWithEmotes);
const renderedMarkdown = new CommonMarkRenderer({
escapeHtml: true,
escapeHtml: options.escapeHtml ?? true,
linkTarget: "_blank",
softBreak: "br",
softBreak: options.softBreak === false ? undefined : "br",
}).render(parsed);

return (
Expand Down
37 changes: 36 additions & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,36 @@ import fetch from "node-fetch";
import { fileURLToPath } from 'url';
import * as sass from "sass";

function parseChangelog() {
return execSync("git log --grep \"^Changelog: \" -10")
.toString()
.split(/^commit /)
.slice(1)
.map((commit) => {
const changelogIndex = commit.indexOf(" Changelog: ");
if (changelogIndex === -1) {
return {};
}
const dateIndex = commit.indexOf("Date: ");
if (dateIndex === -1) {
return {};
}
const afterDate = commit.substring(dateIndex + 8);
const date = moment(new Date(afterDate.substring(0, afterDate.indexOf("\n")))).utc().format("YYYY-MM-DD");
const id = commit.substring(0, commit.indexOf("\n"));
const message = commit
.substring(changelogIndex + 15)
.replaceAll("\n ", "\n")
.trim();
return {
id,
message,
date,
};
})
.filter((changelog) => changelog.message);
}

export default async (env, argv) => {
const getContributorsForRepo = async (repoName) => {
const contributorsData = await fetch(`https://api.github.com/repos/LiveSplit/${repoName}/contributors`);
Expand Down Expand Up @@ -40,10 +70,14 @@ export default async (env, argv) => {

const contributorsList = Object.values(coreContributorsMap)
.sort((user1, user2) => user2.contributions - user1.contributions)
.map((user) => user.login);
.map((user) => {
return { id: user.id, name: user.login };
});
const commitHash = execSync("git rev-parse --short HEAD").toString();
const date = moment.utc().format("YYYY-MM-DD kk:mm:ss z");

const changelog = parseChangelog();

const basePath = path.dirname(fileURLToPath(import.meta.url));

const isProduction = argv.mode === "production";
Expand Down Expand Up @@ -97,6 +131,7 @@ export default async (env, argv) => {
BUILD_DATE: JSON.stringify(date),
COMMIT_HASH: JSON.stringify(commitHash),
CONTRIBUTORS_LIST: JSON.stringify(contributorsList),
CHANGELOG: JSON.stringify(changelog),
}),
...(isProduction ? [
new HtmlInlineScriptPlugin({
Expand Down

0 comments on commit 8bfdfae

Please sign in to comment.