import type { ReactIsland } from "@ethicdevs/react-monolith";
import React, { useCallback, useMemo, useState } from "react";
import type { RepositoryObject } from "../types";
import { AppRoute } from "../routes.defs";
import { Grid } from "../components/Grid";
import { buildRouteLink } from "../utils/shared";
export interface RepositoryCommitSummaryLineProps {
commit: RepositoryObject;
currentRef: string;
orgSlug: string;
repoSlug: string;
}
const MAX_COMMIT_LINE_LENGTH = 60;
const TRAILING_CHAR = " ...";
const TRAILING_CHAR_LENGTH = TRAILING_CHAR.length;
const RepositoryCommitSummaryLine: ReactIsland<RepositoryCommitSummaryLineProps> =
({ orgSlug, repoSlug, commit }) => {
const [isFullSubjectShown, setIsFullSubjectShown] =
useState<boolean>(false);
const toggleFullSubjectVisibility = useCallback(
(ev: React.MouseEvent<HTMLSpanElement>) => {
ev.preventDefault();
setIsFullSubjectShown((prevVisibility) => !prevVisibility);
},
[setIsFullSubjectShown]
);
const isSubjectTooLongForDisplay = useMemo(
() => commit.subject.length > MAX_COMMIT_LINE_LENGTH,
[commit.subject.length]
);
const subject = useMemo(
() =>
isSubjectTooLongForDisplay
? `${commit.subject.substring(
0,
MAX_COMMIT_LINE_LENGTH - TRAILING_CHAR_LENGTH
)}`
: commit.subject,
[commit.subject]
);
return (
<Grid.Col fluid nowrap>
<Grid.Row
gap={8}
alignItems={"stretch"}
style={{ flexWrap: "wrap-reverse" }}
>
<Grid.Col flex={"1 0 calc(100% - 220px)"} style={{ minWidth: 360 }}>
<strong>{commit.author.name}</strong>
<span style={{ marginTop: 8 }}>
<a
href={buildRouteLink(AppRoute.REPOSITORY_SHOW_OBJECT, {
orgSlug,
repoSlug,
objectId: commit.commit,
})}
>
{subject}
</a>
{isSubjectTooLongForDisplay ? (
<span onClick={toggleFullSubjectVisibility}>
{TRAILING_CHAR}
</span>
) : null}
</span>
</Grid.Col>
<Grid.Col
alignItems={"flex-end"}
style={{
textAlign: "right",
flex: "1 0 200px",
width: 200,
minWidth: 200,
}}
>
<span>
<a
href={buildRouteLink(AppRoute.REPOSITORY_SHOW_OBJECT, {
orgSlug,
repoSlug,
objectId: commit.commit,
})}
>
{commit.abbreviated_commit}
</a>
{commit.abbreviated_parent.trim() != "" ? (
<a
href={buildRouteLink(AppRoute.REPOSITORY_SHOW_OBJECT, {
orgSlug,
repoSlug,
objectId: commit.parent,
})}
>
{` (parent ${commit.abbreviated_parent})`}
</a>
) : null}
</span>
<span style={{ marginTop: 8 }}>
{new Date(commit.author.date).toLocaleString()}
</span>
</Grid.Col>
</Grid.Row>
{isFullSubjectShown ? (
<code style={{ marginTop: 8 }}>{commit.subject}</code>
) : null}
</Grid.Col>
);
};
RepositoryCommitSummaryLine.displayName = "RepositoryCommitSummaryLine";
export default RepositoryCommitSummaryLine;