Allow group admission with compatible commitments
Verify and publish checkpoint container / container (push) Canceled after 0s
Verify and publish checkpoint container / container (push) Canceled after 0s
This commit is contained in:
1 parent
0faa7923b0
commit
6524ed3bf2
14 files changed
+679
-53
No files matched your search
@@ -15,6 +15,10 @@ export type CoalitionNexusView = {
|
||||
/** Until group admission can reconcile a live bribe commitment, only
|
||||
* departure remains available in this Nexus. */
|
||||
admissionBlocked?: boolean;
|
||||
/** Invitation choices that this actor cannot make while commitments apply. */
|
||||
blockedInvitations?: readonly { groupId: string; entrant: string }[];
|
||||
/** Whether this actor is unable to accept the pending invitation. */
|
||||
acceptBlocked?: boolean;
|
||||
};
|
||||
|
||||
export type CoalitionNexusIntent =
|
||||
@@ -35,7 +39,9 @@ export function coalitionNexusOptions(view: CoalitionNexusView): {
|
||||
const invitations = !seated || view.proposal || view.admissionBlocked ? [] : view.groups.flatMap(group =>
|
||||
(group.members.length < 2 || group.members.length >= (view.variant === 'unlimited' ? 6 : 3)) ? [] : view.players
|
||||
.filter(player => !occupied.has(player.id) &&
|
||||
(player.id === view.me || group.members.includes(view.me)))
|
||||
(player.id === view.me || group.members.includes(view.me)) &&
|
||||
!view.blockedInvitations?.some(blocked =>
|
||||
blocked.groupId === group.id && blocked.entrant === player.id))
|
||||
.map(player => ({ groupId: group.id, entrant: player.id, members: group.members })));
|
||||
const participants = view.proposal
|
||||
? [...view.proposal.original.members, view.proposal.entrant] : [];
|
||||
@@ -43,7 +49,8 @@ export function coalitionNexusOptions(view: CoalitionNexusView): {
|
||||
return {
|
||||
invitations,
|
||||
mayLeave: seated && !!ownGroup && !view.proposal,
|
||||
mayAccept: mayDecline && !view.admissionBlocked && !view.proposal!.approvals.includes(view.me),
|
||||
mayAccept: mayDecline && !view.admissionBlocked && !view.acceptBlocked &&
|
||||
!view.proposal!.approvals.includes(view.me),
|
||||
mayDecline,
|
||||
};
|
||||
}
|
||||
@@ -70,6 +77,7 @@ export function CoalitionNexus({ view, disabled = false, onIntent }: {
|
||||
<li key={group.id}>{names(group.members)}</li>)}</ul> : <p>There are no alliances yet.</p>}
|
||||
{proposal ? <div aria-live="polite">
|
||||
{view.admissionBlocked && <p>Acceptance is unavailable while a bribe commitment remains unresolved. You may decline this invitation.</p>}
|
||||
{!view.admissionBlocked && view.acceptBlocked && <p>Acceptance is unavailable while it would conflict with your commitments. You may decline this invitation.</p>}
|
||||
<p>{name(proposal.proposer)} proposes adding {name(proposal.entrant)} to {names(proposal.original.members)}.</p>
|
||||
<p>Approved: {names(proposal.approvals)}. Waiting for: {names(
|
||||
[...proposal.original.members, proposal.entrant].filter(id => !proposal.approvals.includes(id)),
|
||||
@@ -87,6 +95,7 @@ export function CoalitionNexus({ view, disabled = false, onIntent }: {
|
||||
</div> : <div>
|
||||
{view.admissionBlocked && <p>Invitations are unavailable while a bribe commitment remains unresolved.
|
||||
Finish the commitment or wait until its binding period ends.</p>}
|
||||
{!view.admissionBlocked && !!view.blockedInvitations?.length && <p>Some invitations are unavailable while they would conflict with your commitments.</p>}
|
||||
{options.invitations.length > 0 && <p>{view.variant === 'unlimited'
|
||||
? 'Invite an unallied player to an existing alliance, or ask to join one.'
|
||||
: 'Invite an unallied player to an existing pair, or ask to join a pair.'}</p>}
|
||||
|
||||
Reference in new issue
Block a user