Handle rejoin = failed

This commit is contained in:
Kalle 2026-05-01 17:21:38 +03:00
parent 072fdca641
commit e5229aa301
3 changed files with 33 additions and 10 deletions

View File

@ -38,7 +38,9 @@ export function RematchVotePanel({
members.map((m) => m.id),
).length;
const voteResolved = RejoinVote.result(votes).type === "RESOLVED";
const voteResult = RejoinVote.result(votes);
const voteResolved = voteResult.type === "RESOLVED";
const voteFailed = voteResult.type === "FAILED";
const viewerVotedYes =
RejoinVote.userContinueStatus(votes, viewerUserId) === true;
const viewerVotedNo =
@ -47,9 +49,11 @@ export function RematchVotePanel({
return (
<div className={styles.root}>
<div className={styles.prompt}>
{voteResolved
? t("q:match.rematch.resolved", { count: currentRoundSize })
: t("q:match.rematch.prompt", { count: currentRoundSize })}
{voteFailed
? t("q:match.rematch.fizzled")
: voteResolved
? t("q:match.rematch.resolved", { count: currentRoundSize })
: t("q:match.rematch.prompt", { count: currentRoundSize })}
</div>
<ul className={styles.list}>
{members.map((member) => {
@ -71,7 +75,7 @@ export function RematchVotePanel({
</SendouButton>
</Link>
</div>
) : viewerVotedNo ? null : (
) : voteFailed || viewerVotedNo ? null : (
<div className={styles.buttons}>
<FormWithConfirm
fields={[

View File

@ -34,6 +34,17 @@ describe("RejoinVote.result()", () => {
continuingUserIds: [1, 3],
});
});
test("fails when fewer than two members want to continue", () => {
expect(
RejoinVote.result([
{ userId: 1, isContinuing: true },
{ userId: 2, isContinuing: false },
{ userId: 3, isContinuing: false },
{ userId: 4, isContinuing: false },
]),
).toEqual({ type: "FAILED" });
});
});
describe("RejoinVote.userContinueStatus()", () => {

View File

@ -7,21 +7,29 @@ export interface RejoinVote {
isContinuing: boolean;
}
const MIN_CONTINUING_GROUP_SIZE = 2;
/**
* Resolves the overall vote state. ONGOING until every member of a full
* group has cast a vote, then returns the ids of those who chose to continue.
* Resolves the overall vote state. ONGOING until every member of a full group
* has cast a vote, then RESOLVED with the ids of those who chose to continue,
* or FAILED if too few want to continue to form a viable group.
*/
// xxx: what about FAILED?
export function result(votes: RejoinVote[]) {
if (votes.length !== FULL_GROUP_SIZE) {
return { type: "ONGOING" as const };
}
const willContinue = votes.filter((vote) => vote.isContinuing);
const continuingUserIds = votes
.filter((vote) => vote.isContinuing)
.map((vote) => vote.userId);
if (continuingUserIds.length < MIN_CONTINUING_GROUP_SIZE) {
return { type: "FAILED" as const };
}
return {
type: "RESOLVED" as const,
continuingUserIds: willContinue.map((vote) => vote.userId),
continuingUserIds,
};
}