mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-03 18:50:30 +08:00
186 lines
6.9 KiB
TypeScript
186 lines
6.9 KiB
TypeScript
import type { ActionWithAuthor } from "@bindings/cob/inbox/ActionWithAuthor";
|
|
import type { Action as IssueAction } from "@bindings/cob/issue/Action";
|
|
import type { Action as PatchAction } from "@bindings/cob/patch/Action";
|
|
|
|
import { formatOid, pluralize } from "@app/lib/utils";
|
|
|
|
export type Action =
|
|
| ActionWithAuthor<IssueAction>
|
|
| ActionWithAuthor<PatchAction>;
|
|
|
|
// N.b. I have taken the `%` char as indicator for a `txt-id` class
|
|
export function createSummary(
|
|
a: Action[],
|
|
kind: "issue" | "patch",
|
|
oid: string,
|
|
count: number,
|
|
) {
|
|
const lastAction = a[a.length - 1];
|
|
let summary = `${lastAction.type} not implemented!`;
|
|
|
|
function times(count: number) {
|
|
return count > 1 ? `${count} times` : "";
|
|
}
|
|
|
|
if (lastAction.oid === oid) {
|
|
summary = `opened ${kind} %${formatOid(lastAction.oid)}%`;
|
|
} else if (lastAction.type === "comment") {
|
|
summary = `left ${count > 1 ? count : "a"} ${pluralize("comment", count)}`;
|
|
} else if (lastAction.type === "revision") {
|
|
const revisions = a.map(i => `%${formatOid(i.oid)}%`).slice(0, 10);
|
|
summary = `created ${pluralize("revision", count)} ${[
|
|
...revisions,
|
|
...(a.length >= 11 ? ["%…%"] : []),
|
|
].join(", ")}`;
|
|
} else if (lastAction.type === "merge") {
|
|
summary = `merged ${pluralize("revision", count)} %${formatOid(lastAction.revision)}%`;
|
|
} else if (lastAction.type === "edit" && kind === "issue") {
|
|
summary = `edited issue${count ? times(count) : ""}`;
|
|
} else if (lastAction.type === "edit" && kind === "patch") {
|
|
summary = `edited ${pluralize("revision", count)} %${formatOid(lastAction.oid)}%`;
|
|
} else if (lastAction.type === "revision.edit") {
|
|
summary = `edited ${pluralize("revision", count)} %${formatOid(lastAction.revision)}%`;
|
|
} else if (lastAction.type === "lifecycle" && count > 1) {
|
|
summary = `changed to ${lastAction.state.status} and ${count} more changes`;
|
|
} else if (
|
|
lastAction.type === "lifecycle" &&
|
|
lastAction.state.status === "draft"
|
|
) {
|
|
summary = `changed to ${lastAction.state.status}`;
|
|
} else if (
|
|
lastAction.type === "lifecycle" &&
|
|
lastAction.state.status === "open"
|
|
) {
|
|
summary = `reopened ${kind}`;
|
|
} else if (
|
|
lastAction.type === "lifecycle" &&
|
|
lastAction.state.status === "archived"
|
|
) {
|
|
summary = `archived ${kind}`;
|
|
} else if (
|
|
lastAction.type === "lifecycle" &&
|
|
lastAction.state.status === "closed" &&
|
|
lastAction.state.reason === "solved"
|
|
) {
|
|
summary = `closed ${kind} as solved`;
|
|
} else if (
|
|
lastAction.type === "lifecycle" &&
|
|
lastAction.state.status === "closed"
|
|
) {
|
|
summary = `closed ${kind}`;
|
|
} else if (lastAction.type === "revision.comment") {
|
|
summary = `left ${count > 1 ? count : "a"} ${pluralize("comment", count)}`;
|
|
} else if (lastAction.type === "review.comment") {
|
|
summary = `left ${count > 1 ? count : "a"} review ${pluralize("comment", count)}`;
|
|
} else if (a.every(e => e.type === "comment.react")) {
|
|
const reactions = a.map(i => i.reaction).slice(0, 10);
|
|
summary = `reacted with ${[
|
|
...reactions,
|
|
...(a.length >= 11 ? ["%…%"] : []),
|
|
].join(", ")} to ${count > 1 ? count : "a"} ${pluralize("comment", count)}`;
|
|
} else if (lastAction.type === "comment.edit") {
|
|
summary = `edited ${count > 1 ? count : "a"} ${pluralize("comment", count)}`;
|
|
} else if (lastAction.type === "review" && lastAction.verdict) {
|
|
summary = `${lastAction.verdict}ed revision %${formatOid(lastAction.revision)}% with a review`;
|
|
} else if (lastAction.type === "review") {
|
|
summary = `left a review with a comment on revision %${formatOid(lastAction.revision)}%`;
|
|
} else if (lastAction.type === "assign") {
|
|
summary = "changed assigns";
|
|
} else if (lastAction.type === "revision.comment.edit") {
|
|
summary = `edited ${count > 1 ? count : "a"} ${pluralize("comment", count)}`;
|
|
} else if (lastAction.type === "comment.redact") {
|
|
summary = `redacted ${count > 1 ? count : "a"} ${pluralize("comment", count)}`;
|
|
} else if (lastAction.type === "label") {
|
|
summary = `added ${pluralize("label", count)}`;
|
|
} else if (lastAction.type === "review.comment.edit") {
|
|
summary = `edited ${count > 1 ? count : "a"} review ${pluralize("comment", count)}`;
|
|
} else if (lastAction.type === "review.comment.react") {
|
|
summary = `reacted to ${count > 1 ? count : "a"} review ${pluralize("comment", count)}`;
|
|
} else if (lastAction.type === "review.comment.redact") {
|
|
summary = `redacted ${count > 1 ? count : "a"} review ${pluralize("comment", count)}`;
|
|
} else if (lastAction.type === "review.comment.resolve") {
|
|
summary = `resolved ${count > 1 ? count : "a"} review ${pluralize("comment", count)}`;
|
|
} else if (lastAction.type === "review.comment.unresolve") {
|
|
summary = `unresolved ${count > 1 ? count : "a"} review ${pluralize("comment", count)}`;
|
|
} else if (lastAction.type === "review.edit") {
|
|
summary = `edited review ${times(count)}`;
|
|
} else if (lastAction.type === "review.redact") {
|
|
summary = `redacted ${count > 1 ? count : "a"} ${pluralize("review", count)}`;
|
|
} else if (lastAction.type === "revision.comment.react") {
|
|
summary = `reacted to ${count > 1 ? count : "a"} revision ${pluralize("comment", count)}`;
|
|
} else if (lastAction.type === "revision.comment.redact") {
|
|
summary = `redacted ${count > 1 ? count : "a"} revision ${pluralize("comment", count)}`;
|
|
} else if (lastAction.type === "revision.react") {
|
|
summary = `reacted to ${count > 1 ? count : "a"} ${pluralize("revision", count)}`;
|
|
} else if (lastAction.type === "revision.redact") {
|
|
summary = `redacted ${count > 1 ? count : "a"} ${pluralize("revision", count)}`;
|
|
}
|
|
|
|
return summary.replaceAll(/[%](\S+)[%]/g, '<span class="txt-id">$1</span>');
|
|
}
|
|
|
|
export function compressActions(
|
|
actions: Action[],
|
|
kind: "issue" | "patch",
|
|
oid: string,
|
|
) {
|
|
const result: {
|
|
summary: string;
|
|
oid: string;
|
|
items: Action[];
|
|
}[] = [];
|
|
|
|
let currentGroup: Action[] = [];
|
|
|
|
for (const action of actions) {
|
|
if (currentGroup.length === 0) {
|
|
currentGroup.push(action);
|
|
continue;
|
|
}
|
|
|
|
const last = currentGroup[currentGroup.length - 1];
|
|
const sameAuthorDid = last.author.did === action.author.did;
|
|
const sameType =
|
|
last.type === action.type ||
|
|
(last.type === "revision.edit" && action.type === "edit") ||
|
|
(action.type === "revision.edit" && last.type === "edit") ||
|
|
action.oid === oid;
|
|
|
|
if (sameAuthorDid && sameType) {
|
|
currentGroup.push(action);
|
|
} else {
|
|
const summaryStr = createSummary(
|
|
currentGroup,
|
|
kind,
|
|
oid,
|
|
currentGroup.length,
|
|
);
|
|
|
|
result.push({
|
|
summary: summaryStr,
|
|
oid,
|
|
items: currentGroup,
|
|
});
|
|
|
|
currentGroup = [action];
|
|
}
|
|
}
|
|
|
|
// Summarize any open actions.
|
|
if (currentGroup.length > 0) {
|
|
const summaryStr = createSummary(
|
|
currentGroup,
|
|
kind,
|
|
oid,
|
|
currentGroup.length,
|
|
);
|
|
result.push({
|
|
summary: summaryStr,
|
|
oid,
|
|
items: currentGroup,
|
|
});
|
|
}
|
|
|
|
return result;
|
|
}
|