Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow kicking of players #68

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

menonsamir
Copy link
Collaborator

@menonsamir menonsamir commented Feb 20, 2024

Adds a button that allows kicking of a player.

Screenshot 2024-02-20 at 1 29 09 PM

The kick button disappears after the first clue is answered.

Players can only be kicked from the room at the
beginning of the first round, before any clues
have been answered.
Copy link

vercel bot commented Feb 20, 2024

Someone is attempting to deploy a commit to a Personal Account owned by @cmnord on Vercel.

@cmnord first needs to authorize it.

@menonsamir menonsamir changed the title app: add button to kick a player Allow kicking of players Feb 20, 2024
@@ -17,6 +17,7 @@ enableMapSet();

export enum ActionType {
Join = "join",
Kick = "kick",
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered calling this "Leave", but since a kick can be initiated by another player, I went with kick. I'm open to "Leave" if folks think that is better.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "kick" is better, since anyone can kick anyone else. You can also kick yourself

@@ -74,6 +74,7 @@ function stateToGameEngine(
*/
answeredBy,
answers: state.answers.get(clueKey) ?? new Map<string, string>(),
numAnswered: state.numAnswered,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The game engine did not give us numAnswered (the number of answered clues in the round) from the State, so I added code to thread it through.

@menonsamir menonsamir requested a review from cmnord February 20, 2024 22:39
Copy link

vercel bot commented Feb 20, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
jep ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 20, 2024 11:51pm

Copy link
Owner

@cmnord cmnord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I'll look at the preview branch for UI later, but looks good overall. Can you allow self-kicking? I can imagine if a player accidentally joins on two devices, they might equally want to kick device A from device B or self-kick from device A.

Comment on lines 74 to 75
method="DELETE"
action={`/room/${roomId}/player`}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏 nice

Comment on lines +156 to +159
key={i}
roomId={roomId}
player={p}
winning={p.score === maxScore}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alphabetize these and the fields in PlayerScore? that would make it easier to compare their props

state: initialState,
actions: [PLAYER1_JOIN_ACTION, PLAYER2_JOIN_ACTION, PLAYER1_KICK_ACTION],
expectedState: produce(initialState, (draft) => {
draft.boardControl = PLAYER2.userId;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙌

@@ -17,6 +17,7 @@ enableMapSet();

export enum ActionType {
Join = "join",
Kick = "kick",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "kick" is better, since anyone can kick anyone else. You can also kick yourself

return;
}
// Don't allow the only player to be kicked.
if (draft.players.size === 1) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch, can you prevent this on the client side as well (once players can kick themselves)?

(type === GameState.ShowBoard || type === GameState.PreviewRound) &&
numAnswered === 0 &&
round === 0;

return (
<div className="flex flex-col gap-2 sm:grid sm:grid-cols-3">
{yourPlayer ? (
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you not kick yourself?

}
// If this player has board control, give it to the next player.
if (draft.boardControl === action.payload.userId) {
const players = Array.from(draft.players.keys());
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you call this playerIds to disambiguate it from Map<string, Player>?

@@ -28,7 +32,11 @@ export async function action({ request, params }: ActionFunctionArgs) {
}

const type =
request.method === "POST" ? ActionType.Join : ActionType.ChangeName;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you change this to a switch (request.method) now instead of multiple ternary operators? the cute/annoying way to do this without reassignment is something like:

const type = () => {
    switch (request.method) {
        case "POST":
            return ActionType.Join;
        // ...
}();

{player.name}
</p>
<div className="ml-auto flex items-center gap-2">
<button
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, can you also add alt text to this that shows up on hover like Kick player ${player.name}

@cmnord
Copy link
Owner

cmnord commented Feb 21, 2024

Closes #15.

@menonsamir
Copy link
Collaborator Author

This looks great! I'll look at the preview branch for UI later, but looks good overall. Can you allow self-kicking? I can imagine if a player accidentally joins on two devices, they might equally want to kick device A from device B or self-kick from device A.

Sure, self-kick is a good idea. I think the UI may be a bit tricky, since we also have the name editing UI for yourself.

image

Where do you think the kick button (currently an 'x') should go overall? Wherever we choose, I'd like to make it consistent for your player and the other ones. Here are some options I've thought of:

  1. Between the edit icon and the crown
image
  1. Below the crown
image
  1. Don't show crowns before any answers have been given (when kicks are possible), and put the kick button below the edit button
image

The main issue with (1) is that the kick button (an 'x') may look like it might just 'clear' the name input. My current inclination is (3), perhaps with the kick button a little lower, and maybe a red accent on highlight (so that it's clear this is a significant action). If we wanted to be as clear as possible, we could also make this button actually say 'Kick', though this is uglier (the button does at least disappear after the first question).

@cmnord cmnord force-pushed the main branch 2 times, most recently from 0326ae3 to f16dc1b Compare July 13, 2024 07:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants